Reputation: 3020
Following up on this question, is there a way to start an intent in android without prompting the user for anything?
Right now, I am retrieving the image like this:
public void changeImage(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, getResources().getString(R.string.select_picture)),
PICK_IMAGE);
}
Then I store the Uri, and when necessary display the image (I actually resize it first, but that doesn't matter):
Uri _uri = Uri.parse(_path);
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(_uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap b = BitmapFactory.decodeStream(imageStream);
iv.setImageBitmap(b);
I would like to retrieve the image data given its Uri by "silently" invoking the intent so as to get the relevant permission. So I would need something like:
Edit:
I tried the setPackage()
method. This code has the following behavior:
If the ACTION_VIEW intent is used, the gallery opens and shows the specific image.
If the ACTION_GET_CONTENT intent is used, I get prompted to pick an image from the gallery, even though I supply the specific Uri.
>
Uri _uri = Uri.parse(_path);
InputStream imageStream = null;
Bitmap b = null;
try {
imageStream = getContentResolver().openInputStream(_uri);
b = BitmapFactory.decodeStream(imageStream);
ImageView iv = (ImageView) findViewById(R.id.playerImage);
iv.setImageBitmap(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
Intent dummyIntent = new Intent(Intent.ACTION_GET_CONTENT);
//Intent dummyIntent = new Intent(Intent.ACTION_VIEW);
dummyIntent.setDataAndType(_uri,"image/*");
dummyIntent.setPackage("com.google.android.gallery3d");
startActivityForResult(dummyIntent, PICK_IMAGE);
}
Any ideas?
Upvotes: 17
Views: 1586
Reputation: 12899
You have different types of Intents, the silent ones are the broadcast and service intents. And by silent I mean that there's nothing visible going on for the user by default (no activity is launched).
An intent will just ask the system: is there something capable of handling it? If there is, it will pass it to that something (or in case of multiple options will ask the user). And you have no control after that unless what's handling it is your code.
Your problem is actually with Picasa.
When the user pick an image from Picasa you get an Uri. You can use that Uri with the ContentResolver to get the image. What's actually happening when you do is that a ContentProvider from Picasa will process the Uri and return you the InputStream for the image.
From the other question I understood that you do not immediately get the image, instead you save the Uri in the database and later process it.
Since Picasa use a permission mechanism to provide you the image and since that permission is expired when you try to use the Uri you want to obtain the Uri (along with the permission) again from Picasa without asking the user again.
The problem is that Picasa is in control on that permission and so if Picasa do not provide you with an intent to obtain the permission by knowing the Uri there's nothing you can do.
This is not even a bug in my opinion: you have the permission to access the image when the user decide so, you do not automatically get the permission to access every image from Picasa. A service that "silently" provide you with the permission to access every Picasa image by knowing its Uri would just let you get any image from the user without him knowing. This is probably not what the Picasa developers wants.
The best suggestion I can give you is the same one that you got in the other question: when the user chose the image immediately obtain it and save locally, then use the local Uri to access the image.
Upvotes: 1
Reputation: 1957
You should be able to get the "real" uri (one that won't change) in the following way:
This is done for audio file, so use "MediaStore.Images.Media.EXTERNAL_CONTENT_URI" and change other details to match your case.
Pre kit-kat:
String songName = "";
Cursor cursor = getContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Audio.Media.TITLE}, MediaStore.MediaColumns.DATA + " =?", new String[]{uri.toString()}, null);
if (cursor != null && cursor.moveToNext()) {
songName = cursor.getString(0);
}
if (cursor != null) {
cursor.close();
}
return songName;
After Kitkat, there is the change due to the document provider, this code should do the trick:
Cursor cursor = null;
String songName = "";
try {
String[] column = new String[]{MediaStore.Audio.Media.TITLE};
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
// where id is equal to
String sel = MediaStore.Images.Media._ID + " =?";
cursor = getContext().getContentResolver().
query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null);
if (cursor != null && cursor.moveToNext()) {
songName = cursor.getString(0);
}
}
catch (Exception e){
Logger.log(e);
}
finally {
if (cursor != null) {
cursor.close();
}
}
return songName;
Again, change the details to match your case and save the real uri taken from the cursor you get (probably get this field in your projections : MediaStore.Images.Media.DATA).
Upvotes: 0
Reputation: 829
Instead of trying to send a "silent" intent, a possible solution could be to save the URI of the file using "Shared Preferences" -- you could save the user and URI as a key/value pair (for example).
When you want to open the file later, it could then be opened without sending an intent.
Upvotes: 0