Находясь в сервисе, проверьте, есть ли определенное действие в стеке действий.

Мне нужен совет по структуре моего приложения. Речь идет об обмене сообщениями с использованием GCM. Итак, я получаю вызов onMessageReceived в GcmListenerService (с данными сообщения). Теперь есть два случая:

а) В стеке активности уже есть активность чата, и я должен отправить туда Intent с информацией о новом сообщении, чтобы активность обновила свои представления

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

Как определить, есть ли активность чата в стеке активности?


person T.Vert    schedule 16.08.2016    source источник
comment
просто используйте привязанный шаблон локальной службы, и ваша служба будет знать, есть ли к ней привязанный клиент.   -  person pskink    schedule 16.08.2016
comment
@pskink, значит, мне нужно создать экземпляр службы (обычный) и привязать к нему активность чата? Я имею в виду, что мы не можем привязываться к GcmListenerService, верно?   -  person T.Vert    schedule 16.08.2016
comment
GcmListenerService расширяет Service, поэтому вы можете вызывать bindService на нем   -  person pskink    schedule 16.08.2016
comment
@pskink, а разве GcmListenerService не создается только для обработки сообщения, а затем автоматически уничтожается?   -  person T.Vert    schedule 16.08.2016
comment
прочитайте это, чтобы узнать жизненный цикл связанной/запущенной службы   -  person pskink    schedule 16.08.2016
comment
@pskink, ну, мы не можем переопределить метод onBind в GcmListenerService, он окончательный и возвращает null   -  person T.Vert    schedule 16.08.2016
comment
упс, очень плохо... так что вам, вероятно, нужна какая-то другая служба для привязки... или, может быть, можно использовать какой-то одиночный флаг (установленный и снятый вашей активностью)   -  person pskink    schedule 16.08.2016
comment
@pskink, одноэлементный флаг звучит интересно, я никогда не думал об этом ... Будет ли это хорошей практикой? Я, вероятно, воспользуюсь им, потому что это намного проще, чем создание другого сервиса и привязка к нему. Спасибо :)   -  person T.Vert    schedule 17.08.2016
comment
если вам не нравятся обычные синглтоны, вы можете использовать пользовательский android.app.Application, но его документы Java говорят: "There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton."   -  person pskink    schedule 17.08.2016


Ответы (1)


Есть возможность проверить текущие задачи и их стек с помощью ActivityManager.

Итак, чтобы определить, является ли действие последним:

запрашивать разрешения android.permission.GET_TASKS в манифесте.

Используйте следующий код:

ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );

List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);

if(taskList.get(0).numActivities == 1 &&
   taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
    Log.i(TAG, "This is last activity in the stack");
}

этот приведенный выше код будет действителен только в том случае, если у вас есть одна задача. Если есть вероятность, что для вашего приложения будет существовать определенное количество задач - вам нужно будет проверить другие элементы списка задач. Подробнее о задачах Tasks и Back Stack

И второе решение

public boolean isRunning(Context ctx) {
        ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

        for (RunningTaskInfo task : tasks) {
            if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) 
                return true;                                  
        }

        return false;
    }
person Riyaz Parasara    schedule 16.08.2016