2015-04-29 2 views
3

У меня есть фоновый сервис, выполняющий некоторую работу - поиск местоположения пользователя по интервалу (запущен с startService). Как только произойдет специальное условие, я хотел бы сделать следующее:Либо показать уведомление, либо отреагировать в приложении

  1. Если приложение находится на переднем плане, начните конкретную операцию.
  2. Если приложение не находится на переднем плане или закрыто, покажите уведомление, которое начнет выполнять требуемую активность при нажатии.

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

ответ

1

Я determint, если мое приложение находится на переднем плане

Там в несколько способов узнать, что находится впереди, но я предпочитаю, чтобы отслеживать это сам (так как это помогает мне применять дополнительную логику, если это необходимо). Плюс это довольно простая задача. Чтобы это произошло, вам понадобится статический счетчик int (вы можете использовать свой объект Application, если он у вас есть, или он есть в другом месте, на самом деле не имеет значения). В каждом ActivityonResume() вы увеличиваете счетчик на единицу, а в onPause() вы уменьшаете его на единицу. Если счетчик равен 0, то ни один из ваших действий не находится на переднем плане, поэтому с вашей точки зрения вы находитесь в фоновом режиме и вы отправляете уведомление. Для простоты я всегда делаю это в своем классе ActivityBase, все мои действия расширяются.

Если вы не хотите, чтобы отслеживать его самостоятельно, вы можете использовать ActivityManager, чтобы увидеть, что в настоящее время на переднем плане:

public boolean isAppInForeground() { 
    ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> services = am.getRunningTasks(Integer.MAX_VALUE); 

    return (services.get(0).topActivity.getPackageName().toString() 
         .equalsIgnoreCase(getPackageName().toString())); 
} 

, но это требует <uses-permission android:name="android.permission.GET_TASKS" /> запись в манифесте, так что не всегда приветствуется.

+0

Несколько дополнительных вопросов. Могу ли я быть уверенным, что статическое поле распределяется между областями приложения и срока службы? Что делать, если приложение полностью закрыто, но работает? И что, если приложение разбилось? Хорошая идея делает действия, связанные с открытым приложением в широковещательном приемнике? –

+0

Я также добавил подход на основе ActivityManager. Что касается ваших вопросов: вы можете использовать подкласс объекта 'Application', если ваше приложение использует любое, поскольку у вас всегда есть один объект приложения для каждого приложения. В качестве альтернативы вы можете оставить свой счетчик в Singleton, но, пожалуйста, [см. Этот вопрос] (http://stackoverflow.com/questions/2423622/volatile-vs-static-in-java), если вы используете Threads в своем приложении. –

+0

Один объект приложения для каждого приложения не применяется, если вы используете несколько процессов. Те же самые статические объекты будут доступны между классом приложения и службами, если они находятся в одном процессе. Если служба в том же процессе, что и приложение запущена, приложение также будет запущено.Ответ на широковещательные сообщения является хорошим, но должен знать о проблемах с безопасностью, а также обратный вызов должен отвечать в течение 5 секунд, поэтому нужно передать любую тяжелую работу на службу – FunkTheMonk

0

Альтернатива ответам Марцина заключается в том, чтобы связать и отвязать свои действия с Сервисом. Это позволит поддерживать связь между Сервисом и активностью, пока эта привязка существует, и Служба будет знать, доступна ли в данный момент активность, способная обрабатывать сценарий. вы можете не захотеть запускать действие непосредственно, если пользователь находится в середине какого-то важного процесса (например, принимает T & Cs/EULA или что-то еще), поэтому служба может сообщить Деянию, что произошло событие, но действие может правильно реагировать на событие.

+0

Вы имеете в виду начальный сервис с 'startService' и' binsService', и если связующее является живым, тогда отправьте информацию к нему и показывать уведомление иначе? –

+0

Да, это то, что я имею в виду. Связанная служба только останется в живых, пока что-то связано с ней, поэтому, если вы хотите, чтобы служба была активной, а ui не была на экране, да запустите ее, а затем привяжите ее. Обратите внимание, что запущенная служба должна быть явно остановлена, поэтому, если она что-то разряжает батарею, у вас должен быть тайм-аут или что-то, чтобы гарантировать, что она не работает все время. – FunkTheMonk

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