Custom intent-chooser - why on Android 6 does it s

2019-04-16 05:57发布

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 ?

1条回答
不美不萌又怎样
2楼-- · 2019-04-16 06:45

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);
        }
    }
查看更多
登录 后发表回答