Is there a way to use Intent.ACTION_SEND
to share a screenshot without requiring android.permission.WRITE_EXTERNAL_STORAGE
?
Here's the share part:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
Intent chooserIntent = Intent.createChooser(shareIntent, shareTitle);
startActivity(chooserIntent);
The share works fine when the uri points to a file in getExternalFilesDir()
, but I'd prefer a solution that does not require the WRITE_EXTERNAL_STORAGE
permission for privacy-concerned users.
I've tried 3 different approaches:
File Provider:
uri = FileProvider.getUriForFile(context, authority, imageFile);
This works for some share styles (Gmail) but not others (Google+).
Upload to a web server:
uri = Uri.parse("http://my-image-host.com/screenshot.jpg");
This fails everywhere, crashing some (Google+).
(I suspect this could work if I implemented sharing logic myself using per-social-network APIs instead of the chooserIntent
)
Inject into Media Store:
uri = MediaStore.Images.Media.insertImage(contentResolver, bitmap, name, description);
This throws a SecurityException explaining it requires WRITE_EXTERNAL_STORAGE.
Are there other approaches I'm missing?
Based on work by Stefan Rusek, I created
LegacyCompatCursorWrapper
, designed to help improve compatibility ofFileProvider
(and otherContentProvider
implementations) with client apps that are looking for_DATA
columns and not finding them. The_DATA
pattern was used originally byMediaStore
, but it was never a good idea for apps to try referring to that column.To use it in conjunction with
FileProvider
, add my CWAC-Provider library as a dependency, and then create your own subclass ofFileProvider
, such as this one:All this does is wrap the
FileProvider
query()
results in aLegacyCompatCursorWrapper
. The rest of your app configuration would be identical to usingFileProvider
directly (e.g.,<meta-data>
element), except that your<activity>
element'sandroid:name
attribute would point to your own class. You can see this in action in this sample app.