Custom intent-chooser - why on Android 6 does it show empty cells?
T

1

2

Background

I wish to show the native intent-chooser, while having the ability to customize it a bit.

For this, I've found the next StackOverflow thread:

How to customize share intent in Android?

The problem

Thing is, when I use the suggested code on Android 5.x and below, everything seems to be fine, but when I use it on Android 6.0.1 (tested on Nexus 5 and emulator, when having multiple apps to share content with) , I get empty cells and sometimes even empty app names, as such:

enter image description here

This doesn't appear when using the non-customized intent-chooser:

startActivity(Intent.createChooser(intent, "default chooser"));

enter image description here

The code

Seeing the solutions, I've created the next code:

private void test(Intent shareIntent) {
    List<Intent> targetedShareIntents = new ArrayList<>();
    final List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
    if (!resInfo.isEmpty()) {
        for (ResolveInfo resolveInfo : resInfo) {
            Intent targetedShareIntent = new Intent(shareIntent);
            targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
            targetedShareIntents.add(targetedShareIntent);
        }
        Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), "Select app to share");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
        startActivity(chooserIntent);
    }
}

private void prepareIntentToShare(Intent intent) {
    intent.setAction(android.content.Intent.ACTION_SEND);
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_STREAM, mUri);
    intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
    intent.putExtra(android.content.Intent.EXTRA_TEXT, "body");
}

And the way to test it:

Intent intent = new Intent();
prepareIntentToShare(intent);
test(intent);

What I've tried

I've tried to change various things in the intents, but without any luck. I've also tried to find out what is the order that the intents are supposed to be in (because maybe it's important), but I didn't find it.

Lastly, I've decided to post about it to Google, assuming this is a bug:

https://code.google.com/p/android/issues/detail?id=202693

The questions

  1. Why does it occur? Can I fix it somehow, while still using the native intent-chooser? How come it occurs only on Android 6 and above?

  2. How can I put the correct name for each item there, as I see "twitter" twice, for example, yet other apps do show the correct name (like the one of the qr-code-scanner)?

  3. Is it possible to keep the native behavior of how to order of apps, as shown using the simple way of showing the intent-chooser? Maybe get the list of apps the way they are supposed to be ordered ?

Toggle answered 7/3, 2016 at 11:32 Comment(2)
Did you solve it? I also have same questions.Arborization
@空気嫁 Sadly it seems it's intentional and Google doesn't consider this a bug (written here: code.google.com/p/android/issues/detail?id=202693 ) , so the only way to do it is to mimic the entire sharing dialog yourself.Toggle
A
3

I spend some time to read ChooserActivity and ResolverActivity and kind of solving thoese problems.

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);

    if (resolveInfos != null && !resolveInfos.isEmpty()) {
        List<Intent> targetIntents = new ArrayList<>();
        for (ResolveInfo resolveInfo : resolveInfos) {
            ActivityInfo activityInfo = resolveInfo.activityInfo;
            // remove activities which packageName contains 'ttt' for example
            if (activityInfo.packageName.contains("ttt")) {
                continue;
            }
            Intent targetIntent = new Intent(Intent.ACTION_SEND);
            targetIntent.setType("text/plain");
            targetIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.setting_share_app_subject));
            targetIntent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.setting_share_app_body));
            targetIntent.setPackage(activityInfo.packageName);
            targetIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));

            // wrap with LabeledIntent to show correct name and icon

            LabeledIntent labeledIntent = new LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon);

            // add filtered intent to a list
            targetIntents.add(labeledIntent);
        }
        Intent chooserIntent;
        // deal with M list seperate problem
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // create chooser with empty intent in M could fix the empty cells problem
            chooserIntent = Intent.createChooser(new Intent(), context.getString(R.string.setting_share_app_title));
        } else {
            // create chooser with one target intent below M
            chooserIntent = Intent.createChooser(targetIntents.remove(0), context.getString(R.string.setting_share_app_title));
        }
        if (chooserIntent == null) {
            return;
        }
        // add initial intents
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[targetIntents.size()]));
        try {
            context.startActivity(chooserIntent);
        } catch (ActivityNotFoundException e) {
            Logger.e(TAG, e, e);
        }
    }

EDIT: seems on Android Q (10 - API 29) this is broken, and will show just up to 2 items instead of all of them. Asked about this again here.

EDIT: made a sample of choosing which items to exclude from sharing, here, which should work for all Android versions.

Arluene answered 14/12, 2016 at 10:39 Comment(6)
Seems to work perfectly . Thank you! Just note that the type you've chosen is different from mine, so the number of items shown can be different.Toggle
Do you know perhaps how to get the direct share items to appear though?Toggle
I am not sure that I understand direct share items correctly...What are they. Are they the apps the filtered by the system through the Intent?Arborization
The OS offers them. You can see an example here: androidcentral.com/using-direct-share-android . They are shown at the top of what appears. If you want to try it, here's a sample project: issuetracker.google.com/issues/110325510Toggle
How to solve the Bug in Android 10. Showing only 3 Apps instead of 8.Intercessor
Have this issue also on Android 10. Showing only a few apps while debugging It should show 10Malleolus

© 2022 - 2024 — McMap. All rights reserved.