Get IntentSender object for createChooser method in Android

前端 未结 2 1171
青春惊慌失措
青春惊慌失措 2020-12-03 02:36

I would like to use new version of Intent.createChooser method which uses IntentSender.

Documentation states only that I can grab it from Pending

相关标签:
2条回答
  • 2020-12-03 03:21

    The chooser target intent is not a PendingIntent. For instance, in the following snippet, I am declaring intent for ACTION_SEND, with type text/plain, and this is the my target intent for the Intent.createChooser. Then I am creating another Intent, receiver, and a handler, the PendingIntet, which will invoke onReceive of my BroadcastReceiver after the user picks something from the chooser.

    // Set up the broadcast receiver (preferably as a class member)
    BroadcastReceiver receiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             // Unregister self right away
             context.unregisterReceiver(this);
    
             // Component will hold the package info of the app the user chose
             ComponentName component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_CHOSEN_COMPONENT);
             // Do something with component
         }
    }
    
    
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
    intent.setType("text/plain");
    
    // Use custom action only for your app to receive the broadcast
    final String shareAction = "com.yourdomain.share.SHARE_ACTION";
    Intent receiver = new Intent(shareAction);
    receiver.putExtra("test", "test");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, receiver, PendingIntent.FLAG_UPDATE_CURRENT);
    Intent chooser = Intent.createChooser(intent, "test", pendingIntent.getIntentSender());
    
    // Before firing chooser activity, register the receiver with our custom action from above so that we receive the chosen app
    context.registerReceiver(receiver, new IntentFilter(SHARE_ACTION));
    
    startActivity(chooser);
    

    Edit:

    The information, in the case of the BroadcastReceiver is embedded in the intent you get as parameter. After you selected one of the option, retrieve the Bundle's extras and using the key Intent.EXTRA_CHOSEN_COMPONENT, you should be able to find what the user picked.

    Try adding as simple Log.d to onReceive

    for (String key : intent.getExtras().keySet()) {
        Log.d(getClass().getSimpleName(), " " + intent.getExtras().get(key));
    }
    

    In my example I got

    ComponentInfo{org.telegram.messenger/org.telegram.ui.LaunchActivity}

    for Telegram and

    ComponentInfo{com.google.android.apps.inbox/com.google.android.apps.bigtop.activities.ComposeMessageActivity}
    

    for InBox

    0 讨论(0)
  • 2020-12-03 03:22

    Another way to do it.

        /**
         * Receiver to record the chosen component when sharing an Intent.
         */
        static class TargetChosenReceiver extends BroadcastReceiver {
            private static final String EXTRA_RECEIVER_TOKEN = "receiver_token";
            private static final Object LOCK = new Object();
    
            private static String sTargetChosenReceiveAction;
            private static TargetChosenReceiver sLastRegisteredReceiver;
    
            static boolean isSupported() {
                return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1;
            }
    
            @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
            static void sendChooserIntent(Activity activity, Intent sharingIntent) {
                synchronized (LOCK) {
                    if (sTargetChosenReceiveAction == null) {
                        sTargetChosenReceiveAction = activity.getPackageName() + "/"
                                + TargetChosenReceiver.class.getName() + "_ACTION";
                    }
                    Context context = activity.getApplicationContext();
                    if (sLastRegisteredReceiver != null) {
                        context.unregisterReceiver(sLastRegisteredReceiver);
                    }
                    sLastRegisteredReceiver = new TargetChosenReceiver();
                    context.registerReceiver(
                            sLastRegisteredReceiver, new IntentFilter(sTargetChosenReceiveAction));
                }
    
                Intent intent = new Intent(sTargetChosenReceiveAction);
                intent.setPackage(activity.getPackageName());
                intent.putExtra(EXTRA_RECEIVER_TOKEN, sLastRegisteredReceiver.hashCode());
                final PendingIntent callback = PendingIntent.getBroadcast(activity, 0, intent,
                        PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
                Intent chooserIntent = Intent.createChooser(sharingIntent,
                        activity.getString(R.string.share_link_chooser_title),
                        callback.getIntentSender());
                activity.startActivity(chooserIntent);
            }
    
            @Override
            public void onReceive(Context context, Intent intent) {
                synchronized (LOCK) {
                    if (sLastRegisteredReceiver != this) return;
                    context.getApplicationContext().unregisterReceiver(sLastRegisteredReceiver);
                    sLastRegisteredReceiver = null;
                }
                if (!intent.hasExtra(EXTRA_RECEIVER_TOKEN)
                        || intent.getIntExtra(EXTRA_RECEIVER_TOKEN, 0) != this.hashCode()) {
                    return;
                }
    
                ComponentName target = intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT);
                if (target != null) {
                    setLastShareComponentName(context, target);
                }
            }
        }
    
    0 讨论(0)
提交回复
热议问题