Уведомление открывает активность, кнопка «Назад» нажата, основная активность открыта? - PullRequest
7 голосов
/ 30 сентября 2011

Лучший способ описать мою проблему таков:

  1. При загрузке создается уведомление (с BroadcastReceiver).
  2. Открывается основное действие моего приложенияи кнопка домой нажата (приложение все еще работает в фоновом режиме, пока система не закроет его).
  3. Я опускаю строку состояния и нажимаю на уведомление, ранее созданное при загрузке.
  4. Начинается какое-то действие, отличное от основного.
  5. Я нажимаю кнопку «Назад» и отображается основное действие.

Как я могу предотвратить этот последний шаг?Что я хочу с помощью кнопки «Назад», так это вернуться туда, где я находился, это домашний экран (рабочий стол со всеми виджетами и значками приложений).Предполагалось, что основное действие моего приложения должно выполняться в фоновом режиме. Почему оно вызывалось с помощью кнопки «Назад»?

В случае необходимости мой код для создания уведомления выглядит следующим образом:

public void createNotification(int notifyId, int iconId, String contentTitle, String contentText) {
    Intent intent = new Intent(mContext, NewNoteActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(AgendaNotesAdapter.KEY_ROW_ID, (long)notifyId);

    PendingIntent contentIntent = PendingIntent.getActivity(mContext, notifyId, intent, 0);

    Notification notification = new Notification(iconId, contentTitle, 0);
    notification.setLatestEventInfo(mContext, contentTitle, contentText, contentIntent);

    mNotificationManager.notify(notifyId, notification);

Я пытался добавить еще пару комбинаций флагов к intent, но ни одна из них не решила мою проблему ... Предложения?

Ответы [ 5 ]

19 голосов
/ 31 января 2013

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

Когда вы запускаете Activity из уведомления, вы должны сохранить ожидаемый пользовательский опыт навигации.Нажатие Back должно вернуть пользователя через обычный рабочий процесс приложения на главный экран, а нажатие Recents должно отобразить действие как отдельную задачу.

http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse

Ваша ситуация - Настройка регулярного действия PendingIntent

См. Полные шаги в ссылке.В основном вам необходимо:
1. Определить Activity иерархию в AndroidManifest.xml

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>


2. Создать задний стек * на основе 1029 *на Intent, который запускает Activity:

...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
5 голосов
/ 10 сентября 2012

Была такая же проблема. Для меня сработало задание в манифесте следующего атрибута для активности, запускаемой уведомлением:

android:taskAffinity=""

Это, по сути, отделяет сродство активности уведомлений от основной активности, и поэтому ОС не чувствует необходимости «возвращаться» к основной деятельности, а просто возвращается к тому, что было до, например «рабочий стол».

3 голосов
/ 30 сентября 2011

Ваша проблема в следующих шагах, так как я знаю из вашего вопроса:

1.Создать уведомление после завершения загрузки

2. Основные действия будут вызываться при запуске

3. Вы нажали кнопку «Домой», чтобы основная активность была остановлена, но не уничтожила

4. Вы нажимаете на уведомление в строке состояния, чтобы ваш application will be resume, чтобы у вас уже была основная активность в вашем заднем стеке, и уведомление будетсоздайте новое действие, как вы упомянули в своем вопросе. Деятельность NewNoteActivity будет возвращена в стек назад. ТАК на этом шаге you have two activities in back stack

5. Вы нажали кнопку назад, чтобы last activity will be destroy и ваш main activity will be resume Но вы хотитечтобы перейти на домашнюю страницу.

Итак, ваша проблема в следующих шагах, как я знаю из вашего вопроса:

1.Создать уведомление после завершения загрузки

2. Основные действиявызовет при запуске

3. Вы нажали кнопку «Домой», чтобы основное действие было остановлено, но не уничтожено

4.Вы нажимаете на уведомление в строке состояния so ваше application will be resume, чтобы у вас уже была основная активность в вашем заднем стеке, и уведомление создаст новую активность, как вы упоминали в своем вопросе. Действия NewNoteActivity будут перенесены в задний стек. SO на этом шаге you have two activities in back stack

5. Вы нажали кнопку «Назад», чтобы last activity will be destroy и ваше main activity will be resume Но вы хотели открыть активность на домашней странице, когда нажимали кнопку «Назад» из действия NewNoteActivity.

Таким образом, решение заключается в том, что при нажатии кнопки «Назад» изВ своей активности NewNoteActivity вы снова запускаете основное действие с флагом Intent.FLAG_ACTIVITY_CLEAR_TOP, чтобы ваше основное действие было воссоздано и получало метод onNewIntent(), чтобы вы могли получить флаг и завершить основное действие, например,

1038 *

@Override
    public void onBackPressed() {
        Intent i = new Intent(this, Main.class);
    i.putExtra("exit", true);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
    super.onBackPressed();
    }

Теперь вам нужно внедрить метод onNewIntent() в основное занятие

При нажатии кнопки «Назад» из действия NewNoteActivity ваше основное действие вызовет метод onNewIntent(), поэтому в этом методеВы должны получить флаговую переменную, которая передается из действия NewNoteActivity. Если выВы получите флаг, и если это правда, тогда просто завершите Основное действие, чтобы вы получили Главный экран.

РЕДАКТИРОВАТЬ

Вы говорите, что у вас есть какое-либо действие из A, B или C, и вы нажали кнопку назад, чтобы это действие было закрыто.Если у вас есть только одно действие в стеке, в это время ваше приложение будет закрыто, это означает, что вы получите домашний экран. Но если у вас более одного действия и вы нажали кнопку «Назад», у вас есть хотя бы одно действие в стеке, и теперь вы нажимаете науведомление, так что это откроет новую активность, связанную с вашим уведомлением, так что эта активность будет перенесена на нее в обратном стеке. Теперь, если вы нажали кнопку назад, ваша последняя активность, связанная с вашим уведомлением, будет закрыта, если вы не изменили onBackPressed() в этом действии, а затем он будет проверять задний стек, если какое-либо действие в заднем стеке будет возобновлено, или если в заднем стеке не будет никаких действий, тогда ваше приложение будет закрыто, и вы получите домашний экран

2 голосов
/ 22 июня 2017

Я использую это решение в своих приложениях. Переопределите onBackPressed (в вашей активности, перенаправленной из уведомления) и проверьте, находится ли ваше приложение в стеке или нет. если нет, то начните свою корневую активность. Пользователь всегда может перейти от вашей корневой активности. Это то, что я делаю в своих приложениях

@Override
public void onBackPressed() {
    if (isTaskRoot()) {
        Intent intent = new Intent(this,YourMainActivity.class);
        startActivity(intent);
        super.onBackPressed();
    }else {
        super.onBackPressed();
    }
}
0 голосов
/ 11 марта 2016

Это работает для меня. попробуйте это:

notifyIntent.setAction(Intent.ACTION_MAIN);
notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);
...