i am calling an intent to share an image. this works with most providers, BUT with Google+. Google+ opens the post activity without the image and displays the toast "You can only post photos stored on your device." at the same time.
File f = storeImage(image); // f = /data/data/com.myapp/files/1333070776978.jpg
Uri uri = Uri.fromFile(f);
Intent share = new Intent(Intent.ACTION_SEND);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, uri);
share.putExtra(Intent.EXTRA_TITLE,"Share that title");
share.putExtra(Intent.EXTRA_SUBJECT,"Share that subject");
share.putExtra(Intent.EXTRA_TEXT,"Check that out...");
share.putExtra("sms_body", "sms body");
startActivity(Intent.createChooser(share, "Share Image"));
i save the image with
Context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
my understanding was that by setting FLAG_GRANT_READ_URI_PERMISSION, i give Google+ specific access to this file.
it works when i store the image into the MediaStore, but i actually don't wanna clutter the users image gallery.
ContentValues values = new ContentValues(2);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATA, f.getAbsolutePath());
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
any advice is appreciated
Simon
Google+ cannot access file://
Uris from the private folder of another application. And the FLAG_GRANT_READ_URI_PERMISSION
doesn't work in this case because it's only for Uris in the "data" part of an Intent, but not for extras.
One common workaround is to add it to the gallery (via the MediaStore
) but it's not necessary to do so. The correct solution in this case is to use a FileProvider
:
FileProvider is a special subclass of ContentProvider that facilitates secure sharing of files associated with an app by creating a
content://
Uri for a file instead of afile:///
Uri.
First place the following in your AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp.testshare.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
Then this file in res\xml\filepaths.xml
:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="shared_images" path="shared_images/" />
</paths>
Then, to share an image file, make sure it's in the path specified above (i.e. shared_images
under getFilesDir()
) and build the intent as follows:
File file = getImageFileToShare();
Uri fileUri = FileProvider.getUriForFile(this, "com.myapp.testshare.fileprovider", file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
intent.setType("image/png");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
(Make sure the authority specified in the getUriForFile()
method matches the one in the manifest).
This will produce a content://
Uri (like content://com.myapp.testshare.fileprovider/shared_images/img1.png
that the Google+ app will be able to access, and thus include in the post).
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