AlarmManager dentro de BroadcastReceiver cuando BOOT_COMPLETED
Tengo un servicio "GroupsTaskAlarmChecker" que se llama cada 20 segundos por AlarmManager en la actividad onCreate de Groups.class de esta manera:
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);
Esto funciona perfectamente. Pero tengo que hacer eso cuando arranque del dispositivo. Entonces sé que tengo que hacer AndroidManifest como este:
- ¿Qué significa la pérdida de una conexión de servicio?
- Cómo evitar el servicio de asesinato del sistema cuando se cancela la aplicación / actividad
- Android Context.bindService devuelve siempre falso y el objeto ServiceConnection nunca se activa
- Android.os.deadobjectexception en el servicio android
- ¿Necesito agregar un filtro de intenciones al iniciar un servicio?
<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>
Y luego mi broadcastReceiver como este:
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); } }
Pero dentro de este onReceive no sé cómo puedo hacer lo mismo que hice antes (con la intención y alarmManager para iniciar el servicio cada 20 segundos). Error en esta línea:
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
¿Es posible que no pueda crear un AlarmManager dentro de BroadcastReceiver?
Les agradezco a todos, soy un principiante de Android y necesito su ayuda. Lo siento por mi inglés
- Usar SharedPreferences en modo multiproceso
- Cómo evitar que el servicio se ejecute de nuevo si ya está ejecutando android
- Detener o matar un servicio
- Inicie Android Service cada 5 minutos
- No se pudo encontrar la clase SoapObject
- ¿Cómo mantengo un Servicio vivo indefinidamente?
- Evitar copias múltiples de un servicio de Android
- ¿Puede existir un servicio de fondo sin su aplicación principal?
ALARM_SERVICE no está definido en la clase ReceiverBoot ni en BroadcastReceiver.
Debe hacer referencia a Context.ALARM_SERVICE como argumento para getSystemService (String).
Para resumir las respuestas y comentarios anteriores: el controlador onReceive recibe un contexto que se puede utilizar para acceder a getSystemService y ALARM_SERVICE. Código de muestra:
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); } } }
Cree una nueva clase con este código y, por supuesto, cambie MyReceiver y MyService a los nombres de su implementación.
He aquí una pequeña contribución, que creo que puede agregar una visión más completa sobre el logro de la meta de esta pregunta.
Primero : configura un "receptor" dentro de AndroidManifest desde tu aplicación.
<receiver android:name=".AlarmBroadcastReceiver" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
Segundo : con una clase que EXTENDE la clase abstracta BroadcastReceiver, debe determinar si la acción de intención fue "BOOT_COMPLETED". Si la condición se cumple, puede llamar a un método de su clase que tiene toda la construcción de su Alarma.
Consulte el siguiente fragmento siguiente.
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()"); } }
En su onReceive:
if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){ //start it again here }