android api-26 +快捷方式广播接收器未调用

时间:2018-10-16 04:25:47

标签: android android-broadcastreceiver desktop-shortcut

我正在尝试在桌面上为应用创建固定的快捷方式。从按钮调用CreateShortcut方法,并显示android创建快捷方式对话框。当呼叫者选择“确定”时,广播接收者应被呼叫并执行完成,以便活动退出。

这是我第一次使用广播接收器,但看起来很简单。只需创建一个接收器,并在一个意图过滤器中注册它即可,该过滤器与一个意图具有相同的作用,并且当该意图被发送时,应该导致接收者被调用,对吗?

创建快捷方式就很好,但是广播接收器永远不会被调用。我在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()
        );
    }
}

这几天我一直在努力,我很沮丧。
谢谢

1 个答案:

答案 0 :(得分:0)

我终于收到了我的BroadcastReceiver的回调。我的主要问题是我用错了意图。我认为只要操作正确,广播接收方的意图和快捷方式的意图就可以相同。错误!快捷方式意图必须具有一个动作集,但是在我所做的测试中,它似乎并不在乎该动作是什么。并且广播接收器被创建为“ Intent = new Intent(context,class); setAction(...);”,该快捷方式将被创建并且功能正常,但是广播接收器从未被调用。我可以使广播接收器正常工作的唯一方法是仅使用Intent,而除了操作集(或可能的其他内容)之外,别无其他。我无法使用创建快捷方式和调用广播接收器的相同意图来使程序正常工作。

遇到的另一个问题是,该界面允许您创建多个固定的快捷方式-然后为每个创建的快捷方式调用一次广播接收器。我发现您可以在界面中查询所有固定的快捷方式,并按ID进行筛选以找出您的快捷方式是否已存在,并使用该信息来避免在首页上创建多个相同的固定快捷方式。

下面的代码似乎可以很好地使用API​​26 +创建快捷方式,并且只要用户接受快捷方式,就会调用接收方。文档指出,只有在用户接受后,他们才会呼叫您的接收者。当然,这使得检测用户交互的结束相当困难。由于请求被埋在我的实际应用程序中,因此计划将其作为单独活动的一部分打开,但是如果他不希望使用快捷方式,我无法检测到用户已完成操作。如果有人有建议,我将不胜感激。

// 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 = "
                                        + "\"$1%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());
                }
            }
        }
    }