Возобновить приложение и стек из уведомления
Я хочу возобновить свое приложение из уведомления строки состояния точно так же, как когда пользователь нажимает его значок в пусковой установке.
то есть: я хочу, чтобы стек был в том же состоянии, что и до того, как пользователь покинул его.
проблема при установке ожидающего намерения в уведомлении заключается в том, что оно всегда нацелено на определенную деятельность. Я не хочу этого. Мне нужно возобновить приложение так же, как это делает пусковая установка.
Итак, если пользователь находится в действии A, I хотите возобновить действие A. Если он запустил действие B Из действия A, то я хочу, чтобы B отображался, когда пользователь нажимает уведомление, и стек должен быть восстановлен, чтобы a возобновлялся, когда пользователь нажимает кнопку "Назад" в B.
есть несколько других вопросов вопросов с похожими названиями, но ни один не решает мою проблему.
7 ответов:
просто используйте те же фильтры намерений, что и Android, когда он запускает приложение:
final Intent notificationIntent = new Intent(context, YourActivity.class); notificationIntent.setAction(Intent.ACTION_MAIN); notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);как
Intentвы создали, чтобы открыть вашActivityиз панели уведомлений так же, как Android используется для запуска вашего приложения, ранее открытыйActivityбудет показано вместо создания нового.
для ситуаций, когда вы не хотите / не можете жестко закодировать активность запуска это решение работает
Intent i = getPackageManager() .getLaunchIntentForPackage(getPackageName()) .setPackage(null) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, i, 0); return new NotificationCompat.Builder(context) ... .setContentIntent(pendingIntent) .build();на setPackage (null) часть была ключевой в моем случае, так как без него приложение не возвращаюсь к предыдущей задаче. Я сравнил свое намерение с намерением из Android launcher и заметил, что pkg не был установлен там, поэтому я придумал удаление имени пакета из намерения.
моя конкретная ситуация заключалась в том, что уведомление было созданный в библиотеке, поэтому я не мог знать, что такое активность запуска.
создание действия, а затем установить категории и соответствующие флаги... Это было так, как это работало для меня, я должен был сделать это таким образом, потому что я сделал это, чтобы поддержать Api lvl 8
intent.addCategory(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setClass(this, YourActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT| Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);и в AndroidManifest
android:launchMode="singleTask"Так что же сделал трюк был
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONTнаряду с указанными в манифесте.надеюсь, что это помогает другим людям.
У меня также была та же проблема и попытаться решить эту проблему, как @Grand's ответ:
final Intent notificationIntent = new Intent(context,YourActivity.class); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER);это работает, нет сомнений в этом, но проблема заключается в том, когда вы устанавливаете свое намерение как ACTION_MAIN. Тогда вы не сможете установить какой-либо пакет для намерения. Я имею в виду, что ваши примитивные данные не будут получены из целевой активности, потому что ACTION_MAIN не может содержать никаких дополнительных данных.
вместо этого, вы можете просто установить ваши действия как singleTask и вызвать ваше намерение обычно без установки ACTION_MAIN и получения намерения от метода onNewIntent () вашей целевой активности.
но помнить, если вы позвоните, супер.onNewIntent (intent); затем будет создан второй экземпляр действия.
Это очень просто откройте файл манифеста и установите режим запуска атрибута singleTop в вашем атрибуте активности
<uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.REORDER_TASKS" /> private void bringApplicationToForeground(){ ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { List<ActivityManager.AppTask> tasksList = am.getAppTasks(); for (ActivityManager.AppTask task : tasksList){ task.moveToFront(); } }else{ List<ActivityManager.RunningTaskInfo> tasksList = am.getRunningTasks(Integer.MAX_VALUE); if(!tasksList.isEmpty()){ int nSize = tasksList.size(); for(int i = 0; i < nSize; i++){ if(tasksList.get(i).topActivity.getPackageName().equals(getPackageName())){ am.moveTaskToFront(tasksList.get(i).id, 0); } } } } }