Reputation: 13060
I'm trying to expose a .png file located in my application's /data directory through a ContentProvider but instead of reaching the openFile
method query
is being called. Now I only ever have a single image which I need to expose for sharing to other applications, how can I setup my Intent to goto openFile
instead of query
?
Intent shareImageIntent = new Intent(Intent.ACTION_SEND);
shareImageIntent.setType("image/*");
shareImageIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(shareImageIntent, "Share image"));
Where the Uri looks like
content://my.package.contentprovider/fileName
Or alternatively do I need to create a database for this and return a cursor?
UPDATE
So this appears to be working on everything except the SMS app (which is what I decided to test first) I would like to support sharing to it however.
Here's the relevant stack trace:
Caused by: java.lang.IllegalArgumentException: Query on content://mypackage.myprovider/someImage.png returns null result. at com.android.mms.ui.UriImage.initFromContentUri(UriImage.java:104) at com.android.mms.ui.UriImage.(UriImage.java:63) at com.android.mms.model.ImageModel.initModelFromUri(ImageModel.java:83) at com.android.mms.model.ImageModel.(ImageModel.java:65) at com.android.mms.data.WorkingMessage.changeMedia(WorkingMessage.java:481) at com.android.mms.data.WorkingMessage.setAttachment(WorkingMessage.java:375) ...
So the SMS app is performing a query instead of reading directly from openFile
, which every other app on my phone seems to do (including other Google apps)
Does anyone know what I need to return here to fullfil the query appropriately? I'm going to go AOSP digging now.
Upvotes: 5
Views: 4866
Reputation: 13060
After digging through the source code of the SMS (MMS really) app this is what I came up with.
Inside UriImage.initFromContentUri
the application makes the query code and assumes there are 2 returned columns in the Cursor
} else {
filePath = c.getString(c.getColumnIndexOrThrow(Images.Media.DATA));
mContentType = c.getString(c.getColumnIndexOrThrow(Images.Media.MIME_TYPE));
}
So inorder for your ContentProvider
to work with the MMS app, you need to return a Cursor
in query
that only has one row and the two columns (Images.Media.DATA & Images.Media.MIME_TYPE) with the appropriate data. The MMS will then make the call to openFile
to actually retrieve the image.
Upvotes: 4
Reputation: 80340
An easier way to share a image resource is to save it to external storage (SD-card) and then do:
Uri imageUri = Uri.fromFile(pathToFile);
Update:
Try using
Uri imageUri = Uri.parse("android.resource://com.package.yourapp/" +imageResID);
Update2
Try saving file to Media Store and then sending it:
String url = Media.insertImage(context.getContentResolver(), imageFile.getAbsolutePath(), imageFile.getName(), imageFile.getName());
Uri imageUri = Uri.parse(url);
Final Update using ContentProvider
and Cursor
:
Your ContentProvider
must implement query(..)
method and it must return a Cursor
. See the source code of UrlImage.initFromContentUri(..)
(which is internally used by MMS app) to see how cursor is called. Take a look at the MatrixCursor
if it fits the bill.
Upvotes: 2
Reputation: 885
If your content provider is already working you can access to a ParcelFileDescriptor via the method openFileDescriptor in the content provider.
A quick, and dirty, example for this:
ParcelFileDescriptor descriptor = mContext.getContentResolver().openFileDescriptor(IMGURI, "r");
Bitmap bmp = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor());
Cheers!
Upvotes: 0