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

Возобновить приложение и стек из уведомления

Я хочу возобновить свое приложение из уведомления в строке состояния точно так же, как когда пользователь нажимает значок в панели запуска.

То есть: я хочу, чтобы стек находился в том же состоянии, что и до того, как пользователь оставил его.

Проблема при настройке ожидающего намерения уведомления заключается в том, что он всегда нацелен на конкретное действие. Я не хочу этого. Мне нужно возобновить приложение так же, как это делает программа запуска.

Итак, если пользователь находится в действии A, я хочу возобновить действие A. Если он запустил действие B из действия A, тогда я хочу, чтобы B отображался, когда пользователь удаляет уведомление, и стек, который нужно восстановить, что A возобновляется, когда пользователь удаляет кнопку "Назад" в B.

Есть несколько других вопросов с похожими названиями, но ни одна проблема не затрагивает мою проблему.

4b9b3361

Ответ 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 и всякий раз, когда вы перезапускаете приложение, все состояния, которые вы сохранили, в базу данных, которую вы можете получить, и установите свои значения в том, что им нужно.