Использование Alarm Manager для запуска службы, но только если основное приложение не запущено

Итак, проблема в том, что у меня есть видеокамера, которая подключена к телефону через Bluetooth. Вся связь с устройством осуществляется через службу Android. Сервис периодически обновляет камеру GPS-координатами. Сервис, к сожалению, написан не моей компанией, и мы имеем контроль только над его запуском и отправкой ему команд (однако GPS он выполняет самостоятельно, если он подключен к устройству). Как только служба запускается нашим приложением, мы пытаемся подключиться к любым сопряженным устройствам, которые содержат OUI моей компании. После того, как устройство отключится (возможно, оно выключится или разрядится батарея), оно не будет автоматически повторно подключено, пока пользователь не перезапустит наше приложение. Таким образом, координаты GPS не будут отправлены на камеру в этом сценарии.

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

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

Однако проблема в том, что если мое приложение уже запущено? Если это так, то пользователь управляет подключением к устройству (у него запрашивается это). Нужно ли мне использовать общие настройки или что-то в этом роде, чтобы узнать, запущено ли мое приложение? Есть ли способ узнать из службы, запущено ли приложение? Я вижу, что это становится сложным. Если у кого-то есть идеи, как с этим справиться, дайте мне знать.


person Matt Wolfe    schedule 24.04.2012    source источник


Ответы (2)


Я бы предложил следующий метод:

  1. Установите будильник, чтобы запустить службу через X минут
  2. Немедленно установить таймер для приложения на X-1 минут
  3. Когда таймер приложения истекает: отмените текущий и установите новый будильник для службы и новый таймер для приложения.

Таким образом, служба не запустится, если приложение все еще работает, и после закрытия приложения тревога не будет остановлена.

person MByD    schedule 24.04.2012
comment
Я немного запутался, где происходят такие вещи, можете ли вы уточнить? Когда вы говорите установить будильник для запуска службы через X минут, это из моего приложения или что-то, что запускается, скажем, при загрузке? Является ли X просто интервалом, который я планирую использовать (поэтому, если это было всего 2 минуты, я установил его для запуска через 1 минуту). Я предполагаю, что делаю это из своего приложения, могу ли я поместить его в действие или, скажем, в свой класс приложения? - person Matt Wolfe; 24.04.2012
comment
Я имел в виду ваше приложение. Лучше установить его из самого приложения, а не из действия, так как вы можете переходить от одного действия к другому во время использования приложения. Когда я говорю X, я имею в виду интервал, но не устанавливайте его на повтор, а когда он вызывается, сбрасывайте его. - person MByD; 24.04.2012
comment
Хорошо, кажется, это имеет смысл. Спасибо. - person Matt Wolfe; 24.04.2012
comment
@MattWolfe - буду рад узнать, сработает ли это (после того, как вы закончите) - person MByD; 25.04.2012
comment
На самом деле с этим были некоторые проблемы (но это была хорошая идея). Основная проблема заключается в том, что в большинстве случаев приложение зависает довольно долго после того, как пользовательский интерфейс исчез. Вместо этого я сделал следующее: когда пользовательский интерфейс находится под контролем, я установил для общего параметра значение true и просто проверяю его в своем сервисе. Я также использовал службу намерения бодрствования Commonsware для обработки деталей обеспечения запуска моей службы (с помощью wakelocks). Я запускаю автоматическое подключение при загрузке, и это также произойдет при запуске приложения. Я едва протестировал его, но, похоже, он работает до сих пор. - person Matt Wolfe; 26.04.2012
comment
@MattWolfe - я был бы рад узнать, что с этим пошло не так. - person MByD; 01.05.2012

Ответ Биньямина Шарета был хорошим, но, к сожалению, он не решил мою проблему, потому что, когда приложение больше не видно или не используется, оно может все еще работать, и для фактического закрытия приложения требуется довольно много времени. Еще одна вещь, которую следует отметить, это когда ваш сервис/прослушиватель или любой другой компонент запускается, который создает экземпляр вашего класса приложения, что может усложнить ситуацию.

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

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

Я использовал намерение бодрствования Commonsware, чтобы просыпаться каждую минуту и ​​делать следующее:

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

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

Единственные реальные улучшения, о которых я могу думать, это:

  1. Если я уже подключен, прекратите пробуждать службу каждую минуту, пока она не будет отключена.
  2. когда bluetooth отключен, перестаньте пробуждать службу. Как только он будет снова включен, начните пытаться снова подключиться каждую минуту. Я считаю, что есть способ получать уведомления о включении Bluetooth с помощью фильтров намерений.

Для простоты я еще не реализовал их.

person Matt Wolfe    schedule 30.04.2012