Переплетная служба BroadcastReceiver

В моем приложении используется служба, запущенная с помощью BOOT_COMPLETE BroadcastReceiver, во время запуска я получаю сообщение об ошибке

мой код:

public class projet extends BroadcastReceiver { 
 public void onReceive(Context context, Intent intent) { 

  intent = new Intent(context, ScreenshotService.class);
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  context.bindService(intent, aslServiceConn, Context.BIND_AUTO_CREATE);
}
}

Ошибка:

java.lang.RuntimeException: Unable to start receiver com.example.projet: android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to bind to services

Ответ 1

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

Правила для широковещательных приемников:

  • Приемники широковещательной передачи не будут иметь никакого пользовательского интерфейса (в основном), и у него будет только фоновая логика.
  • Приемники широковещательной передачи будут иметь максимальный временной интервал в 10 секунд, чтобы завершить свою функциональность, иначе он сработает.
  • Вам не следует выполнять длительные операции или асинхронные операции в приемнике.   Пример: a. Подготовка SD-карты.    б. Загрузка/загрузка файлов из Интернета.            с. Создание файлов Db.            д. Связывание с услугами
  • Не показывать диалог пользователю в широковещательном приемнике. (это асинхронная операция)
  • Вы можете использовать "тосты" или "Уведомления".
  • Не записывайте никаких тяжелых функций.

Ссылка взята из разработчика android

Ответ 2

Если вы знаете, что работает Service, вы можете использовать его Binder с помощью метода BroadcastReceiver.peekService(Context, Intent) (см. peekService docs).

Но, как уже сказано в других ответах, не допускается привязывать Service к .

Ответ 3

Лучший способ - сначала запустить IntentService из BroadcastReceiver.onReceive(), используя:

context.StartService(new Intent(context, YourIntentService.class));

Затем в IntentService.onHandleIntent():

@Override
protected void onHandleIntent(Intent intent) {
    mContext = getApplicationContext();
    mContext.bindService(new Intent("com.ServiceToBind.BIND"), yourConnection, Context.BIND_AUTO_CREATE);
}

Ответ 4

Проблема

BroadcastReceiver не могут быть привязаны к Service, как указывали другие ответы.

Решение

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

Ответ 6

В соответствии с документацией bindService:

Примечание: этот метод нельзя вызывать из BroadcastReceiver компонент. Образец, который вы можете использовать для связи с BroadcastReceiver для службы - вызов startService (Intent) с аргументы, содержащие команду для отправки, со службой вызывая метод stopSelf (int) при выполнении этой команды.

Что я сделал: (Не уверен, что он работает во всех случаях) Вы можете создать Сервис и запустить эту услугу в своем BroadcastReceiver. Внутри вашего метода onCreate() вы можете вызвать метод из другого класса, который отвечает за привязку. Вы можете передать контекст из службы в этот класс и использовать его следующим образом: ctx.bindService(...)

Ответ 8

Просто. Опция 1: Я создал пустую операцию (не пользовательский интерфейс, просто onCreate() для службы Bind) и finish(). В трансляции > Начать операцию с помощью Bundle (при необходимости). Проблема решена.

Выбор 2: То же самое, что и выше, но с использованием службы вместо Activity. Получить трансляцию событий > Начать новую службу > Привязать существующую службу, которую вы хотите привязать.