Уведомление о восстановлении задачи, а не конкретной деятельности? - PullRequest
28 голосов
/ 05 июля 2011

У меня есть служба переднего плана, которая поддерживает соединение с сервером до тех пор, пока пользователь входит в приложение.Это сделано для того, чтобы соединение поддерживалось и могло получать сообщения непосредственно с сервера, даже если пользователь отправил приложение в фоновый режим, нажав Home.

В приложении имеется несколько операций, любая из которыхможет быть активным при отправке в фоновом режиме.

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

Спасибо за любой совет, который вы можете предложить.

Ответы [ 5 ]

63 голосов
/ 02 сентября 2011

Что вам нужно, так это простая деятельность, которая ничего не делает.Вот пример:

public class NotificationActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Now finish, which will drop the user in to the activity that was at the top
        //  of the task stack
        finish();
    }
}

Настройте свое уведомление, чтобы начать эту деятельность.Убедитесь, что в манифесте сходство задач этого действия совпадает со сходством задач других действий в вашем приложении (по умолчанию это так, если вы явно не установили android: taskAffinity ).

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

Это не будет работать, если ваше приложение не 'т уже работает.Однако у вас есть 2 варианта для решения этой проблемы:

  1. Убедитесь, что уведомление не присутствует в панели уведомлений, когда ваше приложение не запущено.

  2. В методе onCreate () объекта NotificationActivity проверьте, запущено ли ваше приложение, и не запускается ли оно, вызовите startActivity () и запустите ваше приложение.Если вы сделаете это, обязательно установите флаг Intent.FLAG_ACTIVITY_NEW_TASK при запуске приложения, чтобы корневым действием задачи не было NotificationActivity.

29 голосов
/ 02 марта 2012

Работает очень хорошо, спасибо Дэвид!Следующий класс проверяет, запущено ли уже приложение и, если нет, запускает его перед завершением (как это было предложено Дэвидом в варианте 2).

public class NotificationActivity extends Activity 
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);

        // If this activity is the root activity of the task, the app is not running
        if (isTaskRoot())
        {
            // Start the app before finishing
            Intent startAppIntent = new Intent(getApplicationContext(), MainActivity.class);
            startAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startAppIntent);
        }

        finish();
    }
}
13 голосов
/ 28 апреля 2012

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

4 голосов
/ 24 апреля 2015
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);

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

Вместо этого вы можете просто установить свои действия как singleTask и нормально вызывать свое намерение, не устанавливая ACTION_MAIN, и получать намерение от метода onNewIntent () своей целевой деятельности.

Но будьте внимательны, если вы позвоните, super.onNewIntent (намерение); тогда будет создан второй экземпляр действия. Только не вызывайте супер метод.

4 голосов
/ 08 октября 2013

Мое решение, которое имитирует поведение программы запуска (выводит задачу на передний план):

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClassName(MyApplication.class.getPackage().getName(), MainActivity.class.getName());
...