Возобновить приложение и стек из уведомления
Я хочу возобновить свое приложение из уведомления в строке состояния точно так же, как когда пользователь нажимает значок в панели запуска.
То есть: я хочу, чтобы стек находился в том же состоянии, что и до того, как пользователь оставил его.
Проблема при настройке ожидающего намерения уведомления заключается в том, что он всегда нацелен на конкретное действие. Я не хочу этого. Мне нужно возобновить приложение так же, как это делает программа запуска.
Итак, если пользователь находится в действии A, я хочу возобновить действие A. Если он запустил действие B из действия A, тогда я хочу, чтобы B отображался, когда пользователь удаляет уведомление, и стек, который нужно восстановить, что A возобновляется, когда пользователь удаляет кнопку "Назад" в B.
Есть несколько других вопросов с похожими названиями, но ни одна проблема не затрагивает мою проблему.
Ответы
Ответ 1
Просто используйте те же фильтры намерений, что и 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
будет отображаться вместо создания нового.
Ответ 2
В ситуациях, когда вы не хотите/не можете жестко закодировать активность запуска, это решение работает
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 и заметил, что pkg не был установлен там, так что я придумал удаление имени пакета из намерения.
Моя особая ситуация заключалась в том, что уведомление было создано в библиотеке, так что я не мог знать, что будет за активность запуска.
Ответ 3
У меня также была та же проблема, и я попытался решить проблему, как @GrAnd ответ:
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() целевой активности.
Но заблудитесь, если вы позвоните, super.onNewIntent(намерение); то будет создан второй экземпляр действия.
Ответ 4
Создание активности, а затем установите категории и соответствующие флаги...
Именно так это работало для меня, я должен был сделать это так, потому что я сделал это для поддержки 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
вместе с линией, установленной в манифесте.
Надеюсь, что это поможет другим людям.
Ответ 5
Это очень просто
откройте файл манифеста и установите атрибут Режим запуска singleTop в свой атрибут активности
Ответ 6
<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);
}
}
}
}
}
Ответ 7
Может быть более простой способ, но вы можете хранить данные в базе данных sqlite и всякий раз, когда вы перезапускаете приложение, все состояния, которые вы сохранили, в базу данных, которую вы можете получить, и установите свои значения в том, что им нужно.