wake studio lock keep jobintentservice example android service background-process wakelock

android - studio - ¿Mantiene un servicio en funcionamiento incluso cuando el teléfono está dormido?



service android (2)

Hubiera recomendado, si crear esta aplicación desde el principio para usar un componente del lado del servidor (sí, también necesitaría supervisión) y enviar notificaciones push, el sondeo nunca es una solución confiable.

Tengo un servicio en mi aplicación que está diseñado para ejecutarse cada 10 minutos. Básicamente, comprueba nuestros servidores para ver si todo funciona correctamente y notifica al usuario de cualquier problema. Creé esta aplicación para uso interno en nuestra empresa.

Mi compañero de trabajo usó la aplicación durante el fin de semana largo y notó que no se realizaron comprobaciones cuando el dispositivo se fue a dormir. Tenía la impresión de que se suponía que el Servicio se mantendría ejecutándose en segundo plano hasta que llame explícitamente a stopService() en mi código.

Entonces, en última instancia, mi objetivo es tener el servicio en ejecución hasta que el usuario presione el botón de apagado en la aplicación o mate el proceso.

Escuché sobre algo llamado WakeLock que está destinado a evitar que la pantalla se apague, que no es lo que quiero. Luego escuché de otra cosa llamada WakeLock parcial , que mantiene la CPU en funcionamiento incluso cuando el dispositivo está dormido. Este último suena más cercano a lo que necesito.

¿Cómo adquiero este WakeLock y cuándo debería lanzarlo y hay otras formas de evitarlo?


Nota: esta publicación se ha actualizado para incluir la API JobScheduler la JobScheduler de Android Lollipop. La siguiente es una forma viable, pero se puede considerar obsoleta si se dirige a Android Lollipop y más. Vea la segunda mitad para la alternativa JobScheduler .

Una forma de hacer tareas recurrentes es esta:

  • Crear una clase AlarmReceiver

    public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent myService = new Intent(context, YourService.class); context.startService(myService); } }

    con YourService como su servicio ;-)

Si necesita un bloqueo de WakefulBroadcastReceiver para su tarea, es aconsejable extenderlo desde WakefulBroadcastReceiver . ¡No olvide agregar el permiso WAKE_LOCK en su Manifiesto en este caso!

  • Crear una intención pendiente

Para comenzar su sondeo recurrente, ejecute este código en su actividad:

Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class); //myAlarm.putExtra("project_id", project_id); //Put Extra if needed PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager alarms = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); Calendar updateTime = Calendar.getInstance(); //updateTime.setWhatever(0); //set time to start first occurence of alarm alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringAlarm); //you can modify the interval of course

Este código configura una alarm y un pendiente de pendingIntent . El alarmManager obtiene el trabajo para repetir la alarmManager recurringAlarm todos los días (tercer argumento), pero inexacta, por lo que la CPU se activa aproximadamente después del intervalo pero no exactamente (permite al sistema operativo elegir el tiempo óptimo, lo que reduce el consumo de batería). La primera vez que se inicia la alarma (y, por lo tanto, el servicio) será el momento en que elija ser updateTime .

  • por último pero no menos importante: así es como matar la alarma recurrente

    Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class); //myAlarm.putExtra("project_id",project_id); //put the SAME extras PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager alarms = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); alarms.cancel(recurringAlarm);

Este código crea una copia de su alarma (probablemente) existente y le dice al alarmManager que cancele todas las alarmas de ese tipo.

  • por supuesto, también hay algo que hacer en el Manifest :

incluye estas dos líneas

< receiver android:name=".AlarmReceiver"></receiver> < service android:name=".YourService"></service>

dentro de la < application> -tag. Sin él, el sistema no acepta el inicio de la alarma recurrente de un servicio.

Comenzando con el lanzamiento de Android Lollipop , hay una nueva forma de resolver esta tarea elegantemente. Esto también hace que sea más fácil realizar solo una acción si se cumplen ciertos criterios, como el estado de la red.

// wrap your stuff in a componentName ComponentName mServiceComponent = new ComponentName(context, MyJobService.class); // set up conditions for the job JobInfo task = JobInfo.Builder(mJobId, mServiceComponent) .setPeriodic(mIntervalMillis) .setRequiresCharging(true) // default is "false" .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) // Parameter may be "ANY", "NONE" (=default) or "UNMETERED" .build(); // inform the system of the job JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(task);

También puede proporcionar una fecha límite con setOverrideDeadline(maxExecutionDelayMillis) .

Para deshacerse de esa tarea, solo llame a jobScheduler.cancel(mJobId); o jobScheduler.cancelAll(); .