web-dev-qa-db-ja.com

Android Nで15分未満の間隔のジョブスケジューラ

「Nougat」で15分未満の間隔でジョブを設定する方法についての私の質問の一部は、ここの彼の答えで「Blizzard」によって答えられました。
Android Nでジョブスケジューラが実行されていません
彼は問題を説明し、次の回避策の使用を提案しました。

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();
}    

ただし、提案された

  .setMinimumLatency(REFRESH_INTERVAL)    

一度だけジョブを開始します。
しかし、[ハンドラーまたはアラームマネージャーを使用しない] Android nougatデバイスで約30秒の周期で定期的に取得するにはどうすればよいですか。

18
tomseitz

誰かがまだ状況を克服しようとしている場合、

> = Android N(定期的なジョブを15分未満に設定する場合)の回避策を次に示します。

SetMinimumLatencyのみが使用されていることを確認してください。また、時間がかかるタスクを実行している場合、次のジョブは、現在のジョブの終了時間+ PROVIDED_TIME_INTERVALにスケジュールされます

.SetPeriodic(long millis)は、以下のAPIレベルでうまく機能しますAndroid N

@Override
public boolean onStartJob(final JobParameters jobParameters) {
    Log.d(TAG,"Running service now..");
    //Small or Long Running task with callback

    //Reschedule the Service before calling job finished
    if(Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
              scheduleRefresh();

    //Call Job Finished
    jobFinished(jobParameters, false );

    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);
  }

UPDATE:居眠りモードで繰り返しジョブを実行することを検討している場合とJobSchedulerについて考える、FYI:JobSchedulerはDozeモードでの実行を許可されません。

JobSchedulerについて話していたため、Dozingについては説明していません。 @ Elletlar、アプリが居眠りモードにある場合でも実行されると考える人もいることを指摘してくれてありがとう。

居眠りモードの場合、AlarmManagerは最適なソリューションを提供します。setExactAndAllowWhileIdle()定期的なジョブを正確な期間で実行する場合、または柔軟な場合はsetAndAllowWhileIdle()を使用します。

デバイスは常に目覚まし時計の居眠りモードから出て、再び居眠りモードに戻るので、setAlarmClock()を使用することもできます。別の方法は、FCMを使用することです。

参照:居眠りの制限

https://developer.Android.com/training/monitoring-device-state/doze-standby

10
MRah

データの小さな部分を更新するためにジョブをセットアップしたいとき、私は同じことで苦労しました。この問題の解決策は、i calledjobFinished(JobParameters, boolean)の後、同じIDでJobをもう一度セットアップすることであることがわかりました。メインスレッドで毎回動作するはずです。

ジョブをセットアップする私の機能は次のようになります。

JobInfo generateRefreshTokenJobInfo(long periodTime){
    JobInfo.Builder jobBuilder = new JobInfo.Builder(1L, new ComponentName(mContext, JobService.class));
    jobBuilder.setMinimumLatency(periodTime);
    jobBuilder.setOverrideDeadline((long)(periodTime * 1.05));
    jobBuilder.setRequiresDeviceIdle(false);
    return jobBuilder.build();
}

Jobの最初の呼び出し後に作業を終了すると、メインスレッドで呼び出します

jobFinished(mJobParameters, true);
registerRefreshJob(5*60*1000L);

これにより、同じIDで同じ時間だけ、ジョブが再スケジュールされます。デバイスがアイドル状態にある場合でも、居眠り中のウェイクロックの不足を考慮に入れなければならないため、希望どおりにジョブを開始できない場合があります。 https://developer.Android.com/about/versions/nougat/Android-7.0-changes.html に記載されています

Dozeに入ってから一定時間デバイスが静止している場合、システムは残りのDoze制限をPowerManager.WakeLock、AlarmManagerアラーム、GPS、Wi-Fiスキャンに適用します。 Dozeの一部またはすべての制限が適用されているかどうかに関係なく、システムはデバイスを起動して簡単なメンテナンスウィンドウを開きます。その間、アプリケーションはネットワークアクセスを許可され、遅延ジョブ/同期を実行できます。

0
Changeling