android api-26+ shortcut broadcast receiver 未被调用

android api-26+ shortcut broadcast receiver not called

我正在尝试在桌面上为某个应用程序创建一个固定的快捷方式。从按钮调用 CreateShortcut 方法并显示 android 创建快捷方式对话框。当调用者选择 ok 时,应该调用广播接收器并执行完成,以便 activity 退出。

这是我第一次使用广播接收器,但它看起来非常简单。只需创建一个接收器,将其注册到一个与 Intent 具有相同操作的 Intent 过滤器,当 Intent 被发送时,它应该会导致接收器被调用,对吗?

快捷方式创建得很好,但从未调用广播接收器。我在 logcat.

上没有看到任何消息
private void CreateShortcut(final Context c) {
    if (ShortcutManagerCompat
             .isRequestPinShortcutSupported(c)) {

        Intent shortcutIntent = new Intent(
            c, CreateAppHomeShortcut.class);
        shortcutIntent.setAction(
            Intent.ACTION_CREATE_SHORTCUT);

        ShortcutInfoCompat shortcutInfo 
           = new ShortcutInfoCompat
            .Builder(c, "shortcut")
            .setShortLabel(c.getString(R.string.app_name))
            .setIcon(IconCompat.createWithResource(
                 c, R.drawable.qmark)
            )
            .setIntent(shortcutIntent)
            .build();

        registerReceiver(new BroadcastReceiver() {
                 @Override
                 public void onReceive(
                        Context context, Intent intent) {
                     Log.d(TAG, "msg received");
                     unregisterReceiver(this);
                     finish();
                 }
             }
            , new IntentFilter(
                 Intent.ACTION_CREATE_SHORTCUT
            )
        );
        PendingIntent successCallback = 
            PendingIntent.getBroadcast(
                c, 99
                , shortcutIntent, 0
           );
        ShortcutManagerCompat.requestPinShortcut(c,
             shortcutInfo,
             successCallback.getIntentSender()
        );
    }
}

这几天我一直在努力,但我很困惑。
谢谢

我终于收到了 BroadcastReceiver 的回调。我的主要问题是我使用了错误的意图。我认为只要操作正确,广播接收者意图和快捷方式意图就可以相同。错误的!快捷方式意图必须有一个动作集,但在我所做的测试中,它似乎并不关心该动作是什么。并且广播接收器创建为 "Intent = new Intent(context, class); setAction(...); ",将创建快捷方式并正常运行,但从未调用广播接收器。我可以让广播接收器工作的唯一方法是只为它设置一个 Intent,除了操作集(或可能的附加项)集。我无法让程序使用相同的意图来创建快捷方式和调用广播接收器。

遇到的另一个问题是该界面允许您创建多个固定的快捷方式——然后将为每个创建的快捷方式调用您的广播接收器一次。我发现您可以查询所有固定快捷方式的界面并按 ID 过滤以查明您的快捷方式是否已存在,并使用该信息避免在您的主页上创建多个相同的固定快捷方式。

下面的代码似乎可以在 API26+ 上正常创建快捷方式,只要用户接受快捷方式,就会调用接收器。文档声明他们只会在用户接受时调用您的接收器。这当然使得检测用户交互的结束变得相当困难。由于请求被隐藏在我的实际应用程序中,计划是将其作为单独的 activity 的一部分打开,但如果用户不想要快捷方式,我没有任何方法可以检测到他是否已完成.如果有人有任何建议,我将不胜感激。

// Create a shortcut and exit the activity.  If the shortcut
   // already exists,just exit.
    private void CreateShortcut(final Context c) {
        if (Build.VERSION.SDK_INT >= 26) {
            ShortcutManager sm = 
                getSystemService(ShortcutManager.class);
            if (sm != null && sm.isRequestPinShortcutSupported()) {
                final String shortcutId = "StartApp";
                boolean shortcutExists = false;
                // We create the shortcut multiple times if given the
                // opportunity.  If the shortcut exists, put up
                // a toast message and exit.
                List<ShortcutInfo> shortcuts 
                     = sm.getPinnedShortcuts();
                for (int i = 0;
                      i < shortcuts.size() && !shortcutExists; i++) {
                    shortcutExists 
                       = shortcuts.get(i).getId().equals(shortcutId);
                if (shortcutExists) {
                    Toast.makeText(c , String.format(
                            "Shortcut %s already exists."
                            , shortcutId
                        )
                        , Toast.LENGTH_LONG
                    ).show();
                    finishActivity();
                }
                else {
                    // this is the intent that actually creates the
                    // shortcut.
                    Intent shortcutIntent
                        = new Intent(c, CreateAppHomeShortcut.class);
                    shortcutIntent.setAction(
                            Intent.ACTION_CREATE_SHORTCUT);
                    ShortcutInfo shortcutInfo = new ShortcutInfo
                        .Builder(c, shortcutId)
                        .setShortLabel(
                             c.getString(R.string.app_name))
                        .setIcon(createWithResource(c
                             , R.drawable.qmark))
                        .setIntent(shortcutIntent)
                        .build();
                    // this intent is used to wake up the broadcast
                    // receiver.
                    // I couldn't get createShortcutResultIntent to
                    // work but just a simple intent as used for a
                    // normal broadcast intent works fine.
                    Intent broadcastIntent
                        = new Intent(Intent.ACTION_CREATE_SHORTCUT);
                    // create an anonymous broadcaster.  Unregister
                    // to prevent leaks when done.
                    registerReceiver(new BroadcastReceiver() {
                             @Override
                             public void onReceive(
                                      Context c, Intent intent) {
                                 unregisterReceiver(this);
                                 Log.d(TAG, String.format(
                                     "ShortcutReceiver activity = "
                                        + "\"%s\""
                                         , intent.getAction()));
                                 finishActivity();
                             }
                         }
                        , new IntentFilter(
                              Intent.ACTION_CREATE_SHORTCUT)
                    );
                    PendingIntent successCallback 
                        = PendingIntent.getBroadcast(
                            c, 99
                            , broadcastIntent, 0);
                    // Shortcut gets created here.
                    sm.requestPinShortcut(shortcutInfo
                            , successCallback.getIntentSender());
                }
            }
        }
    }