I'm building a Chooser app that replaces the native Android Share dialog. It works fine except when I try to share an image from Chrome via longpress image > share image.
I found that Google+ doesn't catch the exception (it crashes) so I can have a look at it via Logcat:
- Do an image search on Google.
- Select an image (this should show the preview)
- Longpress the image
- Choose "Share image"
- My chooser activity pops up
- Select Google+
- Google+ crashes with this error:
java.lang.SecurityException: UID 10130 does not have permission to content://com.android.chrome.FileProvider/images/screenshot/15307295588677864462883877407218.jpg [user 0]
My code (simplified):
@Override
public void onCreate() {
handleIntent();
}
private void handleIntent() {
// Get intent and payload
mIntent = getIntent();
mPayloadIntent = (Intent) mIntent.getParcelableExtra(Intent.EXTRA_INTENT);
// Nullify some things for queryIntentActivities (or no results will be found)
mPayloadIntent.setComponent(null);
mPayloadIntent.setPackage(null);
// Retrieve a list of targets we can send mPayloadIntent to..
List<ResolveInfo> targets = context.getPackageManager().queryIntentActivities(mPayloadIntent, 0);
// etc...
}
private void onClickTarget(ResolveInfo target) {
// Prepare..
ComponentName compName = new ComponentName(
target.activityInfo.applicationInfo.packageName,
target.activityInfo.name);
// Build a 'new' shareIntent
Intent shareIntent = new Intent(mPayloadIntent);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
shareIntent.setComponent(compName);
// Start the targeted activity with the shareIntent
startActivity(shareIntent);
finish();
}
AndroidManifest.xml:
<activity
android:name=".ActShareReplace"
android:label="Sharedr"
android:theme="@style/AppTheme.TransparentActivity"
>
<intent-filter>
<action android:name="android.intent.action.CHOOSER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
If I look at the documentation for Intent.ACTION_CHOOSER it says:
If you need to grant URI permissions through a chooser, you must specify the permissions to be granted on the ACTION_CHOOSER Intent in addition to the EXTRA_INTENT inside. This means using setClipData(ClipData) to specify the URIs to be granted as well as FLAG_GRANT_READ_URI_PERMISSION and/or FLAG_GRANT_WRITE_URI_PERMISSION as appropriate.
I'm not completely sure if this is something my app has to do or if it's the responsibility of the app that invoked the chooser activity - but I would assume it's the latter. My app can't set URI permissions for intents it's receiving, can it?
Anyway, if I inspect the extra's and flags on mIntent
and mPayloadIntent
I get:
mIntent only has extras, no flags (as far as I can tell):
android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER IntentSender{4fa3901: android.os.BinderProxy@3aec3a6} (android.content.IntentSender)
android.intent.extra.INTENT Intent { act=android.intent.action.SEND typ=image/jpeg flg=0x80001 clip={image/jpeg U:content://com.android.chrome.FileProvider/images/screenshot/15307316967108618905323381238187.jpg} (has extras) } (android.content.Intent)
android.intent.extra.TITLE Share via (java.lang.String)
mPayloadIntent:
android.intent.extra.STREAM content://com.android.chrome.FileProvider/images/screenshot/1530731945132897653908815339041.jpg (android.net.Uri$HierarchicalUri)
- FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
- FLAG_ACTIVITY_NEW_DOCUMENT
- FLAG_GRANT_READ_URI_PERMISSION
So mPayloadIntent
does have the FLAG_GRANT_READ_URI_PERMISSION
but mIntent does not. According to the docs it should.
I've read that it's possible that my app consumed the URI permission so I tried caching the file myself but as soon as I try to access the URI through a ContentResolver, I get a - you guessed it - permission error.
I then realized that I probably shouldn't have to cache the file as Android's native Chooser Activity doesn't seem to do that either. So that's where I'm at now. Back to square one.
Is this a Chrome bug? An Android bug? Or am I doing something wrong?
I'd happily blame Chrome and file a bug report but someone who's working on a similar project (and ran into the same issue) told me Whatsapp has a similar problem. It, too, shares images via a content:// uri.
For completeness, I'm testing this on a Pixel 2016 with Android 8.1. I have no idea what the other guy (who ran into the same issue with WA) is using.