Как программно возобновить активность из уведомления? - PullRequest
0 голосов
/ 04 июля 2018

Я прочитал много ответов по этой теме, но ни один из них не решил эту проблему.

В приложении запущена «служба переднего плана», поэтому требуется уведомление.

Так создается Intent.

Intent intent = new Intent(context, notificationClass);
return PendingIntent.getActivity(context, 0, intent, 0);

Обратите внимание, что класс Activity для запуска из уведомления известен во время выполнения (notificationClass). Для дополнительного контекста есть библиотека, которая предоставляет View, который при накачке создает Service, который создает Notification, и поскольку любой Activity может включать View, Class запрашивается, чтобы при пользователь нажимает на уведомление, возобновляет правильное Activity.

Затем intent добавляется к notificationBuilder (NotificationCompat.Builder).

notificationBuilder.setContentIntent(intent);

Реализуя это, когда приложение переходит в фоновый режим, а затем нажимается уведомление, оно создает новую копию Activity вместо ее возобновления.

В целях тестирования я получил ожидаемое поведение (Activity возобновляется после нажатия на уведомление), добавив launchMode из Activity (знать заранее) к singleTop в файле AndroidManifest.xml. Но я не смог заставить его работать по-другому.

С этими ограничениями мне интересно, возможно ли получить такое же поведение программно при создании Notification. Я попробовал несколько комбинаций Intent флагов (также addFlags против setFlags) без удачи.

Есть ли возможность создать Intent, который будет вести себя как объяснено?

Большое спасибо!

cc'ing https://stackoverflow.com/users/769265/david-wasser, который ответил на множество похожих Intent связанных вопросов

Ответы [ 2 ]

0 голосов
/ 20 августа 2018

После некоторого тестирования методом проб и ошибок я заработал, используя следующую комбинацию методов

PackageManager pm = context.getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(context.getPackageName());
intent.setPackage(null);
return PendingIntent.getActivity(context, 0, intent, 0);enter code here

Ключевая часть здесь была intent.setPackage(null);

/**
 * (Usually optional) Set an explicit application package name that limits
 * the components this Intent will resolve to.  If left to the default
 * value of null, all components in all applications will considered.
 * If non-null, the Intent can only match the components in the given
 * application package.
 *
 * @param packageName The name of the application package to handle the
 * intent, or null to allow any application package.
 *
 * @return Returns the same Intent object, for chaining multiple calls
 * into a single statement.
 *
 * @see #getPackage
 * @see #resolveActivity
 */

Очевидно, что pm.getLaunchIntentForPackage(context.getPackageName()); возвращает Intent, ограниченный компонентами в context.getPackageName(), и впоследствии необходимо явно указать для пакета null, чтобы все компоненты были учтены.

Хотя я не совсем уверен насчет ^ FWIW добавив его, решил проблему ¯ \ _ (ツ) _ / ¯

0 голосов
/ 04 июля 2018

Не уверен, что я полностью понимаю, но если вы просто хотите вывести существующую задачу на передний план (что аналогично выбору задачи из списка недавних задач), попробуйте следующее:

PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(packageName);
return PendingIntent.getActivity(context, 0, intent, 0);

packageName - это имя пакета в AndroidManifest.xml.

Это «запускает» корень Activity для задачи, которая фактически ничего не запускает, а просто выводит существующую задачу на передний план.

...