Android API-26 + ярлык вещания приемник не называется - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь создать закрепленный ярлык на рабочем столе для приложения.Метод 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 голосов
/ 19 октября 2018

Я наконец-то получил ответный звонок на мой BroadcastReceiver.Моя главная проблема заключалась в том, что я неправильно использовал намерения.Я подумал, что намерение приемника широковещательной передачи и назначение ярлыка могут быть одинаковыми, если действие было правильным.Неправильно!У быстрого ярлыка должен быть набор действий, но в тестах, которые я проводил, мне было все равно, что это за действие.И получатель широковещания был создан как «Intent = new Intent (context, class); setAction (...);», ярлык был бы создан и функционировал нормально, но приемник широковещания никогда не вызывался.Единственный способ заставить вещательный приемник работать - это использовать Intent только для него, кроме набора действий (или, возможно, дополнений).Я не мог заставить программу работать, используя то же самое намерение создать ярлык и вызвать широковещательный приемник.

Другая проблема, с которой столкнулись, состояла в том, что интерфейс позволяет создавать несколько закрепленных ярлыков - и затем вызыватьВаш широковещательный приемник один раз для каждого созданного ярлыка.Я обнаружил, что вы можете запросить интерфейс для всех закрепленных ярлыков и отфильтровать по идентификатору, чтобы выяснить, существует ли уже существующий ярлык, и использовать эту информацию, чтобы избежать создания нескольких идентичных закрепленных ярлыков на домашней странице.

Кажется, код нижеработает API26 + для создания ярлыка, и получатель вызывается, пока пользователь принимает ярлык.Документы заявляют, что они будут вызывать ваш получатель только после подтверждения пользователя.Это, конечно, делает обнаружение конца взаимодействия пользователя довольно трудным.Поскольку запрос скрывается в моем реальном приложении, планировалось открыть его как часть отдельного действия, но у меня нет никакого способа обнаружить, что пользователь завершил работу, если он не хочет ярлык.Если у кого-то есть предложения, буду признателен, если вы их услышите.

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