Awareness API и Android O с помощью BroadcastReceiver
У меня есть приложение для Android, которое использует API Awareness для настройки забора при подключении гарнитуры.
Я внедрил AwarenessFence, используя код, как в примерах: https://developers.google.com/awareness/android-api/fence-register.
У меня есть PendingIntent, определяемый как:
PendingIntent.getBroadcast(context, 0, new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0)
Затем в моем файле AndroidManifest.xml у меня есть
<receiver android:name=".fence.FenceDetector$MyFenceReceiver">
<intent-filter>
<action android:name="my.application.packageFENCE_RECEIVER_ACTION" />
</intent-filter>
Это объявлено в манифесте из-за того, что я хочу получать трансляции, даже когда мое приложение находится в фоновом режиме.
Все это отлично работало на Android 7.0 и ниже, но когда я запускаю его на Android 8.0, я получаю сообщение об ошибке:
BroadcastQueue: Background execution not allowed: receiving Intent { act=my.application.packageFENCE_RECEIVER_ACTION
Я предполагаю, что это связано с новыми ограничениями для выполнения фона на Android O.
Может кто-нибудь сказать мне, как зарегистрировать широковещательный приемник, который может прослушивать триггеры оповещения для оповещений, когда он находится в фоновом режиме на устройстве Android с API 26.
Сообщите мне Если есть что-то непонятное или мне нужно что-то уточнить.
Заранее спасибо
Ответы
Ответ 1
Теперь я не могу протестировать его на устройстве, но из всего, что я прочитал, ограничение распространяется только на неявные трансляции. Это означает, что если вы создаете явную трансляцию вместо этого, все, что вам нужно, чтобы заставить ее работать.
Это означает вместо этого:
// implicit intent matching action
PendingIntent.getBroadcast(context, 0,
new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0)
вы делаете это:
// explicit intent directly targeting your class
PendingIntent.getBroadcast(context, 0,
new Intent(context, FenceDetector.MyFenceReceiver.class), 0)
Ответ 2
Я немного погулял и наткнулся на этот пост в блоге CommonsWare. В нем оговаривается сама проблема, с которой вы столкнулись.
Из вышеприведенного сообщения: -
Одна из наиболее противоречивых изменений в Android O - для приложений с достаточно высокий targetSdkVersion - это эффективный запрет на неявный трансляций.
Итак, в соответствии с этим, я не думаю, что ваша проблема имеет какое-либо отношение к API-интерфейсу Awareness. Вместо этого, это из-за нового поведения, введенного в Android 8.
К сожалению, на данный момент, похоже, не существует жизнеспособного решения. Опять же, фразы из того же поста: -
Если вы принимаете неявные трансляции, отправленные системой (например, ACTION_PACKAGE_ADDED), сохраните цель targetSdkVersion на уровне 25 или ниже, пока мы не выясним лучшие обходные пути, которые (надеюсь) не привлекают опрос.
Итак, мы надеемся, что в ближайшем будущем будет лучшее решение для 8. Между тем, вы могли бы рассмотреть другие варианты или могли бы рассмотреть вопрос о снижении целевого уровня.
Ответ 3
Ваше понимание очень правильно.
Приложения, ориентированные на Android 8.0 или более поздние версии, больше не могут регистрировать широковещательные приемники для неявных передач в своем манифесте. Неявная трансляция - это широковещательная передача, которая специально не предназначена для этого приложения.
Приложения могут продолжать регистрироваться для явных передач в своих манифестах.
Источник
Если вас интересует настроить забор, когда гарнитура подключена к. Вы можете использовать
Примечание. В настоящее время ряд неявных трансляций освобождается от этого ограничения. Приложения могут продолжать регистрировать приемники для этих трансляций в своих манифестах, независимо от уровня API, на который нацелены приложения. Список исключенных трансляций см. В Неявные исключения трансляции.
Вы можете запросить ACTION_HEADSET_PLUG
в Android Manifest
. В onReceive
вы можете:
- запустите
NotificationManager.startServiceInForeground()
, чтобы вы могли выполнять работу в фоновом режиме.
- Найдите способ дублирования функциональных возможностей службы с запланированным заданием. Если служба не делает что-то сразу же заметное для пользователя, вы обычно должны иметь возможность использовать запланированное задание. См. Планировщик заданий
- Отложите фоном работу до тех пор, пока приложение не будет естественно на переднем плане.
Я бы предложил использовать комбинацию Планировщик заданий с ACTION_HEADSET_PLUG
, если необходимо выполнить длительную работу.
Другой разумный, если необходимо выполнить кратковременную работу, которая в onReceive
вы можете получить помощь от следующего:
A BroadcastReceiver, который использует goAsync(), чтобы отметить, что ему нужно больше времени для завершения после завершения onReceive(). Это особенно полезно, если работа, которую вы хотите заполнить в onReceive(), достаточно длинна, чтобы заставить поток пользовательского интерфейса пропускать кадр ( > 16 мс), что делает его более подходящим для фонового потока.
вы не должны запускать длинные потоки фона из широковещательного приемника. После onReceive() система может убить процесс в любое время, чтобы восстановить память, и при этом он завершает порожденный поток, выполняемый в этом процессе. Чтобы этого избежать, вы должны либо вызвать goAsync() (если вам нужно немного больше времени для обработки широковещательной передачи в фоновом потоке), либо назначить JobService из приемника с помощью JobScheduler, поэтому система знает, что процесс продолжает выполнять активные Работа.
Источник