AlarmManager внутри BroadcastReceiver при BOOT_COMPLETED

У меня есть служба "GroupsTaskAlarmChecker", которая вызывается каждые 20 секунд AlarmManager в onCreate активности Groups.class следующим образом:

int seconds = 20;

           Intent myIntent = new Intent(Groups.this, GroupsTaskAlarmChecker.class);
           pendingIntent = PendingIntent.getService(Groups.this, 0, myIntent, 0);

           AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

           Calendar calendar = Calendar.getInstance();
           calendar.setTimeInMillis(System.currentTimeMillis());
           calendar.add(Calendar.SECOND, 10);
           alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

Это прекрасно работает. Но мне нужно сделать это при загрузке устройства. Тогда я знаю, что мне нужно сделать AndroidManifest следующим образом:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <receiver android:name=".ReceiverBoot">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED">
            <category android:name="android.intent.category.HOME">
        </category></action></intent-filter>
    </receiver>

а затем mi broadcastReceiver вот так:

 public class ReceiverBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    int seconds = 20;

        Intent myIntent = new Intent(context, GroupsTaskAlarmChecker.class);
        pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);

        AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 10);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);

    }
}

но внутри этого onReceive я не знаю, как я могу сделать то же самое, что и раньше (с намерением и alarmManager запускать службу каждые 20 секунд). Ошибка в этой строке:

 AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Возможно ли, что я не могу создать AlarmManager внутри BroadcastReceiver?

Благодарю вас всех, я новичок в Android, и мне нужна ваша помощь. Извините за мой английский ;)


person carlosdiazp    schedule 05.03.2013    source источник
comment
Я забыл написать эту строчку в этом вопросе, но не в коде @Jacob. и init, которые получают широковещательную рассылку (прежде, чем я протестирую активность init и все в порядке), я просто хочу знать, как написать первый код, который я написал в методе onReceive. Это возможно?   -  person carlosdiazp    schedule 05.03.2013


Ответы (4)


ALARM_SERVICE не определен ни в классе ReceiverBoot, ни в BroadcastReceiver.

Вы должны ссылаться на Context.ALARM_SERVICE в качестве аргумента для getSystemService (String).

person pakopa    schedule 05.03.2013

Подводя итог приведенным выше ответам и комментариям: обработчик onReceive получает контекст, который можно использовать для доступа к getSystemService и ALARM_SERVICE. Образец кода:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // Start periodic service.
        Calendar cal = Calendar.getInstance();
        Intent srvIntent = new Intent(context, MyService.class);
        PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
        // Use context argument to access service
        AlarmManager alarm = 
                        (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        // Repeat every 5 seconds
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                                5000, pIntent);
        }
    }
}

Создайте новый класс с этим кодом и, конечно, измените MyReceiver и MyService на имена в вашей реализации.

person pmont    schedule 06.08.2013

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

Во-первых: настройте «получатель» внутри AndroidManifest из вашего приложения.

<receiver
    android:name=".AlarmBroadcastReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Второй: с классом, расширяющим абстрактный класс BroadcastReceiver, вы должны определить, было ли действие намерения «BOOT_COMPLETED». Если условие выполнено, вы можете вызвать метод из своего класса, который имеет всю конструкцию для вашего Alarm.

См. Следующий фрагмент ниже.

public class AlarmBroadcastReceiver extends BroadcastReceiver {

    String TAG   = "ALARMS";
    String CLASS = this.getClass().getSimpleName() + ": ";

    Context alarmContext;

    @Override
    public void onReceive(final Context context, Intent intent) {

        Log.d(TAG, CLASS + "[START] onReceive()... ");

        alarmContext = context;

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.d(TAG, CLASS + "BOOT_COMPLETED action has been received.");
            setAlarmOnBoot();
        }

            Log.d(TAG, CLASS + "[END] onReceive()... ");

    }

    public void setAlarmOnBoot() {

        Log.d(TAG, CLASS + "[START] - setAlarmOnBoot()");

        final long beginAt  = SystemClock.elapsedRealtime() + 60 * 1000;
        final long interval = 300000; // 5 minutes

        try {
            AlarmManager alarm    = (AlarmManager)  alarmContext.getSystemService(Context.ALARM_SERVICE);
            Intent intent         = new Intent(alarmContext, AlarmBroadcastReceiver.class);
            PendingIntent pIntent = PendingIntent.getService(alarmContext, 0, intent, 0);
            alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, beginAt, interval, pIntent);
            Log.d(TAG, CLASS + "the Alarm has been configured successfully (5 minutes) of interval.");
        } catch (Exception e) {
            Log.d(TAG, CLASS + "an exception has ocurred while setting the Alarm...");
            e.printStackTrace();
        }  

        Log.d(TAG, CLASS + "[END] - setAlarmOnBoot()");

    }

}
person ivanleoncz    schedule 06.12.2016
comment
отличное решение, и спасибо за полный код, который легко понять новичкам вроде меня - person Sasa; 31.05.2017
comment
Добро пожаловать, приятель! Я считаю, что этот код не так уж и сложен и может улучшить решения, которые у нас есть для этого ответа. С Уважением :). - person ivanleoncz; 31.05.2017

в вашем onReceive:

if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){

   //start it again here

}
person MariusBudin    schedule 05.03.2013
comment
но моя проблема заключается в создании кода: я должен создать экземпляр и AlarmManager внутри broadcastReceive. И я не знаю, как это сделать: / - person carlosdiazp; 05.03.2013
comment
(если я изменяю контексты) предупреждений и ошибок нет, но да в этой строке: AlarmManager alarmManager = (AlarmManager) getSystemService (ALARM_SERVICE); Проблема с этим методом и переменной внутри широковещательного приемника ... Может быть я не могу сделать AlarmManager внутри широковещательного приемника ?? - person carlosdiazp; 05.03.2013
comment
Я думаю, вам нужен объект Context для вызова getSystemService. - person pakopa; 05.03.2013
comment
попробуйте получить SystemService из контекста, переданного параметром в методе onReceive - person MariusBudin; 05.03.2013
comment
Я не знаю, что делать, в этой строке ошибка продолжения ALARM_SERVICE не может быть разрешена в переменную: AlarmManager alarmManager = (AlarmManager) context.getSystemService (ALARM_SERVICE); - person carlosdiazp; 05.03.2013
comment
получить это тоже из контекста Context.ALARM_SERVICE - person MariusBudin; 05.03.2013
comment
Вот и все. (Context.ALARM_SERVICE) - это ответ. Большое спасибо @Ics;) - person carlosdiazp; 05.03.2013