2010-08-25 6 views
9

Я разрабатываю приложение с многочисленными действиями. Я хотел бы создать постоянное уведомление, которое (более или менее) говорит: «AppName - Return to AppName», которое будет присутствовать при запуске моих фоновых служб. Создание и удаление уведомления не было проблемой.Используйте постоянное уведомление, позволяющее пользователю вернуться к запущенному приложению Android

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

Моя первая попытка уродливого обходного пути состояла в том, чтобы сделать операцию (назовем ее «returnFromNotify»), единственной задачей которой было «закончить» себя в «onCreate». Уведомление откроет «returnFromNotify» в области истории приложений, которое затем немедленно удалит себя, отправив пользователя обратно в предыдущее состояние истории в стеке приложений. Кажется, это работает ... если пользователь не использовал «назад», чтобы полностью отказаться от приложения. Затем, когда они попадают в уведомление, загружаются «returnFromNotify», затем заканчивается, отправка их обратно на главный экран (так как в стеке для приложения нет приложения).

Я считал, что пытаюсь определить, было ли что-либо в стеке истории до «returnFromNotify», а если нет, запустите мою основную деятельность. Я тоже не могу найти способ сделать это.

Любой вход или предложения для новичков Java/Android? FYI. Моя основная история связана с языками на основе скриптов.

ответ

6

Мне нравится ваша первоначальная идея создания деятельности «returnFromNotify» лучше, чем предлагаемый ваш обходной путь, как это является можно обнаружить, если ResumeActivity находится в нижней части стека (и, следовательно, единственным видом деятельности в стеке) ,

Вот как вы можете это сделать:

Добавить ResumeActivity в манифест и указать noHistory атрибут:

<activity android:name=".ResumeActivity" android:noHistory="true" /> 

Указание noHistory удостоверится это активность не будет находиться в стеке, как только как он заканчивается. Таким образом, вы знаете, что в стеке будет отображаться только текущий экземпляр ResumeActivity.

Чтобы проверить стек приложений, вы также должны просить разрешения GET_TASKS:

<uses-permission android:name="android.permission.GET_TASKS" /> 

Теперь вы можете использовать ActivityManager::getRunningTasks(), чтобы определить, если ResumeActivity является единственным видом деятельности, в стеке:

public class ResumeActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if(isOnlyActivityInStack()) { //check the application stack 
      //This activity is the only activity in the application stack, so we need to launch the main activity 
      Intent main = new Intent(this, MainActivity.class); 
      main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      startActivity(main); 
     } else { 
      //Return the user to the last activity they had open 
      this.finish(); 
     } 
    } 

    /** 
    * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack 
    * 
    * @return boolean This activity is the only activity in the stack? 
    **/ 
    private boolean isOnlyActivityInStack() { 
     ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
     boolean onlyActivityInStack = false; 

     for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) { 
      if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack 
       if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) { 
        //If the ResumeActivity is the base activity, we know that it is the only activity in the stack 
        onlyActivityInStack = true; 
        break; 
       } 
      } 
     } 

     return onlyActivityInStack; 
    } 

} 

Я знаю, что вы задавали этот вопрос более 2 лет назад, но я предоставляю этот ответ на случай, если кто-то еще столкнется с этой конкретной ситуацией (как и я). Я думаю, вы были на правильном пути с решением, из которого вы изначально работали.

+0

Да! Этот проект был для работы, с которой я больше не работаю, поэтому мне это совершенно не нужно ... но это звучит как ТОЧНО, что я искал, так что спасибо! Надеюсь, кто-то еще найдет это полезным. – Slobaum

3

Хорошо, я считаю, что нашел подходящий обход для моего конкретного случая. Я добавил статическое целое к моей «mainActivity», и каждый раз, когда он запускается «onCreate», он увеличивает целое число. Каждый раз, когда он «onDestroy» уволен, он уменьшается.

В моем «returnFromNotify» я смотрю на статическое целое, чтобы увидеть, если оно больше 0. Если это так, я предполагаю, что есть активная «mainActivity», и что выполнение «finish» внутри «returnFromNotify» вернется там. В противном случае он предполагает, что пользователи «поддерживают», заканчивают сами, затем используют «startActivity» для запуска нового экземпляра «mainActivity».

Это не универсальное решение, но для моих целей, я думаю, этого будет достаточно. Я по-прежнему открыт для других ответов, и если кто-то может пробить дыру в моей логике, сделайте это - конструктивный критика приветствуется. Благодарю.

1

Я думаю, что нет простого способа сделать это, но вместо добавления счетчика в mainActivity я бы продлить Application:

Базового класс для тех, кому необходимо поддерживать глобальное состояние приложения. Вы может обеспечить собственную реализацию по , указав его имя в теге AndroidManifest.xml, которая приведет к тому, что класс будет экземпляр для вас, когда процесс для вашего приложения/пакета создан.

Я бы mantein логику там и есть метод, как:

public Intent getIntentForLastActivityShown(); 

называться, когда элемент уведомления щелкнул.

+1

Как вы могли бы использовать getIntentForLastActivityShown()? Не проще было бы сохранить дескриптор уведомления в классе Application, а затем каждый раз, когда вы начинаете новый вызов вызова setLatestEventInfo из notificaiton и обновляете pendingIntent до текущей видимой активности. – schwiz

1

Моим первым подходом было бы использовать SharedPreferences и хранить пару значений ключа, называемую примерно lastDisplayedActivity. Тогда в каждой данный вид деятельности onResume (и, возможно, `OnCreate ') вы бы такую ​​строку:

sharedPreferences.edit().putInteger("lastDisplayedActivity", ReturnFromNotify.THIS_ACTIVITY_NAME); 

Другими словами, хранить переменную приложения шириной, указывающего, деятельность последнего отображения. Затем вы просто берете эту переменную из SharedPreferences и запускаете соответствующую операцию.

+0

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

+0

В некоторых случаях он может автоматически восстановить состояние, но если ваша активность не отображается в данный момент, Android * может убить ее в любое время * для восстановления дополнительной памяти. Другими словами, если вы хотите быть уверенным, что вы сохраните состояние Activity, вы должны сохранить его в другом месте. Существует множество способов сделать это, но если у вас есть достаточное количество данных, я бы рекомендовал использовать базу данных SQLite: http://developer.android.com/guide/topics/data/data-storage.html#db – Computerish

0

Обычно я использую операцию с именем «Launcher», которая проверяет состояние моего приложения модели и запускает действия (или выполняет другие действия) в зависимости от правил модели. Я положил Модель объект в моем классе приложения. Модель может использовать Предпочтения для сохранения состояния. Я делаю это, чтобы избежать статических полей в действиях.

 Смежные вопросы

  • Нет связанных вопросов^_^