【问题标题】:Get IntentSender object for createChooser method in Android获取 Android 中 createChooser 方法的 IntentSender 对象
【发布时间】:2015-08-18 08:38:28
【问题描述】:

我想使用新版本的Intent.createChooser 方法,它使用IntentSender

文档仅说明我可以从 PendingIntent 实例中获取它。就我而言,PendingIntent 似乎没有任何其他用途。

还有其他方法可以获取IntentSender 还是我需要创建PendingIntent

【问题讨论】:

  • 您必须通过PendingIntent 创建它。构造函数是公共的,但使用 @hide 进行注释
  • @Blackbelt 但我应该将PendingIntent 作为目标Intent 传递吗?

标签: android android-intent android-pendingintent


【解决方案1】:

选择器目标意图不是PendingIntent。例如,在下面的 sn-p 中,我声明了 ACTION_SEND 的意图,类型为 text/plain,这是我对 Intent.createChooser 的目标意图。然后我创建另一个Intent、接收器和一个处理程序PendingIntent,在用户从选择器中选择某些内容后,它将调用我的BroadcastReceiver 的onReceive

// Set up the broadcast receiver (preferably as a class member)
BroadcastReceiver broadcastReceiver = 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(broadcastReceiver, new IntentFilter(SHARE_ACTION));

startActivity(chooser);

编辑

BroadcastReceiver 的情况下,信息嵌入在您作为参数获得的意图中。选择其中一个选项后,检索捆绑包的附加内容并使用密钥 Intent.EXTRA_CHOSEN_COMPONENT,您应该能够找到用户选择的内容。

尝试将简单的 Log.d 添加到onReceive

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

在我的例子中,我得到了

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

对于Telegram

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

InBox

【讨论】:

  • 不要忘记将广播寄存器类添加到清单中
  • 是否有任何代码示例可以让我看看如何执行此操作?我的广播接收器没有收到任何东西。
  • 我的广播接收器也无法正常工作。您能否展示一下您是如何连接广播接收器的?我正在我的活动中注册它,但不确定要使用什么来用于意图过滤器。
  • 我们做什么,当api级别低于22时
  • 1.此 createChooser 在 API >= 22 上可用 2. 该方法对我不起作用。 onReceive 在选择器打开时立即调用,而不是从选择器中选择某些应用程序时调用。
【解决方案2】:

另一种方法。

    /**
     * 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);
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    相关资源
    最近更新 更多