8

I have a simple code to share photos through external apps that have been working as expected in previous Android versions. But we are getting some reports saying that users can not share photos with their apps because only some of them appears in the share sheet.

We did some tests in different phones (with Android 10), and the results is that there are only like 3 or 4 app available to share, and it depends on the phone. For instance, in some phones Gmail is shown, but no in other. In those where Gmail appears, it works correctly.

Any idea why?

This is how Uri looks: content://com.MyPackageName.fileprovider/external_cache/test2014_000000059279.jpg

This is how mime looks: image/jpeg

Here is the code, I've simplified it a bit.

public void shareViaIntent(Context context, Uri uri, String mimeType, CharSequence shareTitle) {
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType(mimeType);
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read file from temp cache path of our app
    shareIntent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.shared_text));
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);

    final ArrayList<Intent> shareIntents = getExternalShareIntents(context, shareIntent);

    Intent chooserIntent = Intent.createChooser(target, shareTitle);
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, shareIntents.toArray(new Parcelable[]{}));
    context.startActivity(chooserIntent);
}

private ArrayList<Intent> getExternalShareIntents(Context context, Intent shareIntent) throws Throwable {
    final List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(shareIntent, 0);

    final ArrayList<Intent> shareIntents = new ArrayList<>();
    for (ResolveInfo resolveInfo : resolveInfos) {
        final String packageName = resolveInfo.activityInfo.packageName;

        if (packageName.equals(buildInfo.getApplicationId())) {
            continue;
        }

        Intent intent = new Intent(shareIntent);
        intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
        shareIntents.add(intent);
    }

    return shareIntents;
}

And here you can see the behavior changes depending on the phone..

share examples

Thanks in advance

adalpari
  • 3,052
  • 20
  • 39
  • Hey, I just bumped into the same issue. Did you find a meaningful solution by any chance? – ArieDov Oct 14 '20 at 13:30
  • Same problem here. I only see `Bluetooth` and `Nearby Share`. Running `Android 11` on a `Pixel 3` with `targetSdkVersion 30` if that matters. – l33t Nov 10 '20 at 21:55
  • Looks like a duplicate of [this question](https://stackoverflow.com/q/57846229), see also [these](https://issuetracker.google.com/issues/136027280) [issues](https://issuetracker.google.com/issues/134367295). – gmk57 Dec 18 '20 at 13:40

1 Answers1

5

When your app's targetSdkVersion is 30 or later, you will receive a filtered list of activities/packages. Hence, the weird results on different phones/setups. It's also worth noticing that this also affects ShareActionProvider which is commonly used for share actions.

Package Visibility in Android 11

Read about the details in Android Documentation. There you find the solution to this problem. The manifest must include a <queries> tag.

The solution

Run the latest version of Android Studio and Gradle. Then modify your AndroidManifest.xml as shown below. My sample only handles text/plain, but you can of course add other MIME types if your app needs it.

<manifest>
  <application>
    <!-- -->
  </application>
  <queries>
    <intent>
      <action android:name="android.intent.action.SEND" />
      <data android:mimeType="text/plain" />
    </intent>
  </queries>
</manifest>

With this in place, the Intent Chooser no longer shows a filtered list.

l33t
  • 18,692
  • 16
  • 103
  • 180