2013-09-21 3 views
11

Моё приложение использует сервис, который запускается с помощью BOOT_COMPLETE BroadcastReceiver, в перспективе я получаю ошибкуBinding службы по 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 
+0

http://skillgun.com/question/538/android/receivers/what-will-happen-if-broad-cast-receiver-binds-to-binder-service-is-there-any-problem –

+0

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

ответ

17

Нельзя связывать Rvice от широковещательного приемника. Причина в том, что широковещательные приемники представляют собой легкие весовые компоненты, где это должно быть finish its functionality with in not more than 10 seconds maximum. Другой андроид может принудительно убить ваш ресивер. Связывание (установление соединения) службы может занять более 10 секунд в некоторых худших случаях, поэтому андроид не позволит этого.

Правила для радиоприемников:

  1. радиоприемники не будет иметь никакого UI (в основном), и он будет иметь только фон логику.
  2. Приемники широковещательной передачи будут иметь максимальный временной интервал в 10 секунд, чтобы завершить свою функциональность, иначе он сработает.
  3. Вам не следует выполнять длительные операции или асинхронные операции в приемнике. Пример: a. Подготовка SD-карты. b. Загрузка/загрузка файлов из Интернета. c. Создание файлов Db. d. Связывание с услугами
  4. Не показывать диалог пользователю в широковещательном приемнике. (это асинхронная операция)
  5. Вы можете использовать «тосты» или «Уведомления».
  6. Не пишите никаких тяжелых функций.

Ref взяты из developer android

+3

Хороший ответ! Тем не менее, вы можете запустить службу из широковещательного приемника. –

+0

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

7

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

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

+2

Обратите внимание, что 'peekService', кажется, возвращает' null', когда служба не запущена, или служба еще не связана каким-то другим. – Sam

+0

@Sam Это именно то, что я написал. Обратите внимание на слова «Если вы знаете, что служба запущена». –

+1

Нет, это не так; вы не упомянули, что он возвращает «null» при сбое, и вы не упомянули, что он терпит неудачу, если служба работает, но не привязана к чему-то еще. – Sam

0

Согласно bindService документации:

Note: this method can not be called from a BroadcastReceiver component. A pattern you can use to communicate from a BroadcastReceiver to a Service is to call startService(Intent) with the arguments containing the command to be sent, with the service calling its stopSelf(int) method when done executing that command.

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

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); 
} 
+0

Сделайте вашу жизнь легкой. :-) – gaurav414u

+0

Эй, парень, который отклонил мой ответ. Не могли бы вы объяснить, что вам не понравилось? Это был наилучший возможный способ, о котором я мог думать, и на самом деле я использую этот код в своем приложении. Таким образом, код даже проверен и доказал свою работоспособность. – gaurav414u

+0

Мой плохой. Я., его намерение. Благодаря @Eric – gaurav414u

1

Проблема

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

Решение

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

0

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

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

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