Почему мой BroadcastReceiver не вызывает другие методы? - PullRequest
1 голос
/ 08 ноября 2011

У меня есть BroadcastReceiver, который может успешно перехватить трансляцию, но если я попытаюсь вызвать из него другой метод, он не всегда будет работать.Вот мои настройки:

private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (working == true) {
            //toast to make sure we got here
            doWork();
        }
    }
}

Тост в if вызывается, но doWork не выполняется.Кто-нибудь имел дело с подобной проблемой?

Ответы [ 2 ]

2 голосов
/ 08 ноября 2011

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

From: http://developer.android.com/reference/android/content/BroadcastReceiver.html

Объект BroadcastReceiver действителен только на время вызова onReceive (Context, Intent).Как только ваш код возвращается из этой функции, система считает, что объект завершен и больше не активен.

Это имеет важные последствия для того, что вы можете сделать в реализации onReceive (Context, Intent): все, что требует асинхронногооперация недоступна, потому что вам нужно будет вернуться из функции для обработки асинхронной операции, но в этот момент BroadcastReceiver больше не активен, и, таким образом, система может завершить свой процесс до завершения асинхронной операции.

В частности, вы не можете показывать диалог или привязку к услуге из BroadcastReceiver.Для первого вы должны вместо этого использовать API NotificationManager.Для последнего вы можете использовать Context.startService (), чтобы отправить команду службе.

1 голос
/ 08 ноября 2011

Скорее всего, он не бодрствует достаточно долго. Используете ли вы WakeLock для предотвращения возврата Android в спящий режим?

Итак, во-первых, вам нужно добавить это в свой манифест:

<uses-permission android:name="android.permission.WAKE_LOCK" />

и затем в вашем приемнике // псевдокод, за исключением частей, которые имеют значение ...

 public WakeLock wl;
    @Override
    public void onReceive(c,i){
       wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);//this matters
       wl.getWakeLock().acquire(); //as does this


       //do whatever but DON'T do it here... call a Service like this...
       Intent i = new Intent(context, MyExcellentService.class);

        try {
    PendingIntent.getService(context, 0,i, 0).send();
         }catch(Exception e){}

       //hold on to wl in some way and release it in the service, not here,
       wl.getWakeLock().release();


    }

Если вы собираетесь использовать службу, вам необходимо зарегистрировать ее в своем манифесте, например, так ...

<service android:name="MyExcellentService" />

И я бы расширил Приложение и держал там WakeLock, чтобы вам не приходилось передавать его более замысловатыми способами. Вы можете просто войти в Приложение и поговорить прямо с ним!

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

Дайте мне знать, если это работает, я режу и вставляю из разных мест, поэтому я могу что-то упустить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...