Подтвердить что ты не робот

Как использовать функцию прямого ответа Android Nougat с помощью NotificationListener?

Мое приложение использует NotificationListener для чтения сообщений от различных сторонних приложений, например WhatsApp.

До сих пор мне удалось отправить ответ, если только один чат не прочитан, код ниже.

Однако, в случае с WhatsApp, getNotification().actions возвращает нулевой объект, когда более двух чатов не прочитаны, поскольку сообщения объединены вместе. Как вы можете видеть на рисунках ниже, если уведомления расширены, есть возможность отправить прямой ответ, поэтому я уверен, что это можно использовать, также я думаю, что такие приложения, как PushBullet, используют этот метод.

Как я могу получить доступ к RemoteInput этого уведомления?

public static ReplyIntentSender sendReply(StatusBarNotification statusBarNotification, String name) {

            Notification.Action actions[] = statusBarNotification.getNotification().actions;

            for (Notification.Action act : actions) {
                if (act != null && act.getRemoteInputs() != null) {
                    if (act.title.toString().contains(name)) {
                        if (act.getRemoteInputs() != null)
                            return new ReplyIntentSender(act);
                    }
                }
            }
            return null;
        }



public static class ReplyIntentSender {
      [...]

    public final Notification.Action action;

    public ReplyIntentSender(Notification.Action extractedAction) {
            action = extractedAction;
     [...]
    }

private boolean sendNativeIntent(Context context, String message) {
            for (android.app.RemoteInput rem : action.getRemoteInputs()) {
                Intent intent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putCharSequence(rem.getResultKey(), message);
                android.app.RemoteInput.addResultsToIntent(action.getRemoteInputs(), intent, bundle);
                try {
                    action.actionIntent.send(context, 0, intent);
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
                return true;
            }
            return false;
        }
    }

Некоторое объяснение того, как работает вышеуказанный код: после получения уведомления приложение пытается получить действия и проверяет, находится ли имя в заголовке remoteInput (обычно оно находится в формате "Reply to $NAME" ), если это обнаружено, действие сохраняется в класс ReplyIntentSender, который при запуске sendNativeIntent циклически проходит через все удаленные соединения этого действия и добавляет сообщение в намерение. Если несколько чатов не прочитаны, getNotification().actions возвращает null.

Ниже приведены два скриншота, первый из которых работает без проблем, а второй - там, где он отсутствует.

Я могу ответить на это сообщение

Я не могу ответить на это сообщение

4b9b3361

Ответ 1

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

Многочисленные приложения отправляют специальные уведомления Wear, и многие из них содержат действия, доступные с устройства Android Wear. Мы можем захватить эти уведомления Wear на устройстве, извлечь действия, найти ответное действие (если оно существует), заполнить его собственным ответом и затем выполнить PendingIntent, который отправляет наш ответ обратно оригинальному приложению для его отправки получателю.

Для этого вы можете сослаться на эту ссылку (Хорошее обходное решение Rob J). Вы также можете сослаться на эту ссылку в этом контексте (Большая исследовательская работа, выполненная Михалом Тайхертом) (Возможно, вам придется работать с NotificationCompat.isGroupSummary)

Это то, что я чувствую (может быть, я абсолютно неправ)

.actions возвращает массив из Notification.Actionструктуры, привязанные к текущему уведомлению addAction (int, CharSequence, PendingIntent), Здесь метод addAction устарел один, чтобы он не работал должным образом.

Я не могу проверить это на своем конце, иначе я буду рад предоставить рабочее решение с кодом.

Надеюсь, это поможет вам. Счастливое кодирование!!!