truco samsung programacion oreo juego empty dish descargar collector cats all android android-jobscheduler android-7.0-nougat

android - samsung - neko collector



Job Scheduler no se ejecuta en Android N (4)

En Android Nougat, la llamada al método setPeriodic(long intervalMillis) utiliza setPeriodic (long intervalMillis, long flexMillis) para programar trabajos periódicos.

Según la documentación:

JobInfo.Builder setPeriodic (intervalo largoMillis, flexMillis largo)

Especifique que este trabajo debe repetirse con el intervalo y la flexibilidad proporcionados. El trabajo puede ejecutarse en cualquier momento en una ventana de longitud flexible al final del período.

Intervalo Milisegundo : Intervalo de milisegundos para el que se repetirá este trabajo. Se aplica un valor mínimo de getMinPeriodMillis ().

flexMillis long: Flex de milisegundos para este trabajo. Flex está sujeto a al menos getMinFlexMillis () o al 5 por ciento del período, lo que sea mayor.

Trabajo periódico de muestra programado para 5 segundos:

private static final int JOB_ID = 1001; private static final long REFRESH_INTERVAL = 5 * 1000; // 5 seconds JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName) .setPeriodic(REFRESH_INTERVAL) .setExtras(bundle).build();

El código anterior funciona bien en Lollipop y Marshmallow, pero cuando ejecute en Nougat, verá el siguiente registro:

W/JobInfo: Specified interval for 1001 is +5s0ms. Clamped to +15m0s0ms W/JobInfo: Specified flex for 1001 is +5s0ms. Clamped to +5m0s0ms

Como hemos establecido el intervalo de actualización periódica en 5 segundos, que es menor que el umbral getMinPeriodMillis() . Android Nougat aplica getMinPeriodMillis() .

Como solución alternativa, estoy usando el siguiente código para programar trabajos a intervalos periódicos si el intervalo de trabajo es inferior a 15 minutos.

JobInfo jobInfo; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { jobInfo = new JobInfo.Builder(JOB_ID, serviceName) .setMinimumLatency(REFRESH_INTERVAL) .setExtras(bundle).build(); } else { jobInfo = new JobInfo.Builder(JOB_ID, serviceName) .setPeriodic(REFRESH_INTERVAL) .setExtras(bundle).build(); }

Ejemplo de ejemplo de JobService:

public class SampleService extends JobService { @Override public boolean onStartJob(JobParameters params) { doSampleJob(params); return true; } @Override public boolean onStopJob(JobParameters params) { return false; } public void doSampleJob(JobParameters params) { // Do some heavy operation ...... // At the end inform job manager the status of the job. jobFinished(params, false); } }

Job Scheduler funciona como se esperaba en dispositivos Android Marshmallow y Lollipop, pero no se está ejecutando y Nexus 5x (Android N Preview).

Código para programar el trabajo

ComponentName componentName = new ComponentName(MainActivity.this, TestJobService.class.getName()); JobInfo.Builder builder; builder = new JobInfo.Builder(JOB_ID, componentName); builder.setPeriodic(5000); JobInfo jobInfo; jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobInfo = builder.build(); int jobId = jobScheduler.schedule(jobInfo);

El servicio se define en manifiesto como:

<service android:name=".TestJobService" android:permission="android.permission.BIND_JOB_SERVICE" />

¿Alguien tiene este problema en Android N (Vista previa)?


He encontrado la respuesta al problema al que nos enfrentamos con los dispositivos Nougat. Los dispositivos de turrón no pueden programar el trabajo si el trabajo necesita reprogramarse en menos de 15 minutos.

Probé dando el tiempo de intervalo como 15 minutos y el trabajo comenzó a programarse cada 15 minutos.

Código de programador de trabajo:

public static void scheduleJob(Context context) { ComponentName serviceComponent = new ComponentName(context, PAJobService.class); JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceComponent); builder.setPeriodic(15 * 60 * 1000, 5 * 60 *1000); JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); int ret = jobScheduler.schedule(builder.build()); if (ret == JobScheduler.RESULT_SUCCESS) { Log.d(TAG, "Job scheduled successfully"); } else { Log.d(TAG, "Job scheduling failed"); } }

Servicio de trabajo:

public class PAJobService extends JobService { private static final String TAG = PRE_TAG + PAJobService.class.getSimpleName(); private LocationManager mLocationManager; public boolean onStartJob(JobParameters params) { Log.d(TAG, "onStartJob"); Toast.makeText(getApplicationContext(), "Job Started", Toast.LENGTH_SHORT).show(); return false; } public boolean onStopJob(JobParameters params) { Log.d(TAG, "onStopJob"); return false; } }

En resumen, si hubiera aumentado el tiempo de intervalo a 15 minutos, el código habría comenzado a funcionar.

private static final long REFRESH_INTERVAL = 15 * 60 * 1000;


Si alguien todavía está tratando de superar la situación,

Aquí hay una solución alternativa para> = Android N (si desea establecer el trabajo periódico en menos de 15 minutos)

Compruebe que solo se utiliza setMinimumLatency. Además, si está ejecutando una tarea que lleva mucho tiempo, el siguiente trabajo se programará a las, Hora de finalización del TRABAJO actual + PROVIDED_TIME_INTERVAL

.SetPeriodic (long millis) funciona bien para el nivel API por debajo de Android N

@Override public boolean onStartJob(final JobParameters jobParameters) { Log.d(TAG,"Running service now.."); //Small or Long Running task with callback //Call Job Finished when your job is finished, in callback jobFinished(jobParameters, false ); //Reschedule the Service before calling job finished if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) scheduleRefresh(); return true; } @Override public boolean onStopJob(JobParameters jobParameters) { return false; } private void scheduleRefresh() { JobScheduler mJobScheduler = (JobScheduler)getApplicationContext() .getSystemService(JOB_SCHEDULER_SERVICE); JobInfo.Builder mJobBuilder = new JobInfo.Builder(YOUR_JOB_ID, new ComponentName(getPackageName(), GetSessionService.class.getName())); /* For Android N and Upper Versions */ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mJobBuilder .setMinimumLatency(60*1000) //YOUR_TIME_INTERVAL .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); }

ACTUALIZACIÓN: Si está considerando ejecutar su trabajo repetido mientras está en modo Doze y está pensando en JobScheduler, FYI: JobSchedulers no puede ejecutar en modo Doze.

No he discutido sobre Dozing porque estábamos hablando de JobScheduler. Gracias, @Elletlar , por señalar que algunos pueden pensar que se ejecutará incluso cuando la aplicación esté en modo de reposo, lo que no es el caso.

Para el modo de reposo, AlarmManager todavía ofrece la mejor solución. Puede usar setExactAndAllowWhileIdle () si desea ejecutar su trabajo periódico en un período de tiempo exacto o usar setAndAllowWhileIdle () si es flexible.

También puede configurar el usuarioAlarmClock () ya que el dispositivo siempre sale del modo de reposo para la alarma y vuelve al modo de reposo nuevamente. Otra forma es usar FCM.


Si desea ejecutar el código periódicamente menos de 15 minutos, puede utilizar una forma complicada. Configura tu jobFinished() como este

jobFinished(parameters, true);

reprogramará el código con una estrategia de reintento. Definir un criterio de retroceso personalizado utilizando

.setBackoffCriteria();

en el constructor Luego se ejecutará periódicamente