Возобновление деятельности извещения

У меня есть уведомление в строке состояния для моего приложения:

    Notification notification = new Notification(R.drawable.icon, null, System.currentTimeMillis());

    Intent notificationIntent = new Intent(this.parent, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this.parent, 0, notificationIntent, 0);

    ...

    notification.flags = Notification.FLAG_ONGOING_EVENT;        
    mNotificationManager.notify(NOTIFICATION_ID, notification);

Проблема заключается в том, что когда вы нажимаете кнопку "домой" из приложения (нажимая его на задний план), нажмите на уведомление в списке, доступном из строки состояния, и запустит новую копию действия. Все, что я хочу сделать, это возобновить приложение (например, когда вы отпускаете домашнюю кнопку и нажимаете на значок приложения). Есть ли способ создать намерение сделать это?

Ответ 1

Я решил эту проблему, изменив launchMode моей активности на singleTask в файле androidManifest.xml.

Значение по умолчанию для этого свойства равно standard, что позволяет запускать любое количество экземпляров.

"singleTask" и "singleInstance" могут только начинать задание. Они всегда находятся в корне стека активности. Кроме того, устройство может удерживать только один экземпляр активности за один раз - только одна такая задача. [...]

Режимы "singleTask" и "singleInstance" также отличаются друг от друга только в одном отношении: активность "singleTask" позволяет другим действиям быть частью своей задачи. Он всегда лежит в основе его задачи, но в эту задачу могут быть включены другие действия (обязательно "стандартные" и "одиночные" ). С другой стороны, деятельность "singleInstance" не позволяет другим действиям не участвовать в ее задаче. Это единственное занятие в задаче. Если он запускает другое действие, эта деятельность назначается другой задаче - как если бы FLAG_ACTIVITY_NEW_TASK был в намерении.

вы можете найти подробное объяснение в руководстве разработчиков Android.

Я надеюсь, что это поможет

Ответ 2

У меня была аналогичная проблема, и правильный способ справиться с этим - использовать флаги: Intent.FLAG_ACTIVITY_CLEAR_TOP и Intent.FLAG_ACTIVITY_SINGLE_TOP как это

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

Из документации это будет:

FLAG_ACTIVITY_CLEAR_TOP

Если установлено, и запущенная деятельность уже запущена в текущей задаче, вместо того, чтобы запускать новый экземпляр этого действия, все остальные действия поверх него будут закрыты, и это намерение будет доставлено в (сейчас сверху) старой деятельности как нового намерения.

FLAG_ACTIVITY_SINGLE_TOP

Если установлено, действие не будет запущено, если оно уже запущено в верхней части стека истории.

Ответ 3

У меня было непоследовательное поведение между устройствами с некоторыми намерениями, теряющими отдельно оплачиваемые предметы, и вызывались оба метода MainActivity OnNewIntent и onCreate.

Что не сработало:

Manifest:

    <activity android:name=".MainActivity"
        android:launchMode="singleTask">

Обслуживание:

    Intent notificationIntent = new Intent(this.getBaseContext(), MainActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    notificationIntent.putExtra("TEST", 1);

Что сработало:

Manifest:

    <activity android:name=".MainActivity"
        android:launchMode="singleTask">

Обслуживание:

    PackageManager pm = getPackageManager();
    Intent launchIntent = m.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
    launchIntent.putExtra("TEST", 2);

Ответ 4

Я только что нашел решение этой проблемы: я создал метод getPreviousIntent и передал его PendingIntent всем:

private Intent getPreviousIntent(Intent newIntent) {
    final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    final List<ActivityManager.RecentTaskInfo> recentTaskInfos = am.getRecentTasks(1024,0);
    String myPkgNm = getPackageName();

    if (!recentTaskInfos.isEmpty()) {
        ActivityManager.RecentTaskInfo recentTaskInfo;
        for (int i = 0; i < recentTaskInfos.size(); i++) {
            recentTaskInfo = recentTaskInfos.get(i);
            if (recentTaskInfo.baseIntent.getComponent().getPackageName().equals(myPkgNm)) {
                newIntent = recentTaskInfo.baseIntent;
                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
        }
    }
    return newIntent;
}

Ответ 5

Добавьте эту строку в соответствующую активность в файле манифеста вашего приложения.

android:launchMode="singleTask"

например:

<activity
    android:name=".Main_Activity"
    android:label="@string/title_main_activity"
    android:theme="@style/AppTheme.NoActionBar"
    android:launchMode="singleTask" />

Ответ 6

Вы можете имитировать намерение запуска (как если бы пользователь щелкнул значок вашего приложения, чтобы запустить его):

val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)

val contentIntent = PendingIntent.getActivity(context, 0, launchIntent, 0)

Таким образом, вам не нужно помечать ваше приложение как "singleTask" или "singleInstance" в манифесте (что может создать другие проблемы). Таким образом, это должно быть правильным решением.

Обратите внимание, однако,, что вышеупомянутое решение может не работать непосредственно для вас, из-за предполагаемой ошибки Android. Обсуждения об ошибке андроида и обходном пути можно найти в этом вопросе.

Ответ 7

Я использую:

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.setAction(Intent.ACTION_MAIN);

Не уверен, что это значения, которые нужно установить, но ответ находится в этих методах/флагах.