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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With