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

孤街醉人 提交于 2019-12-03 22:38:55

问题


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:

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

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

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 ?


回答1:


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.



来源:https://stackoverflow.com/questions/35842612/custom-intent-chooser-why-on-android-6-does-it-show-empty-cells

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!