Android Nougat で変更された接続状態を検出したい。を受け取ることができない Android ドキュメントを読みましたCONNECTIVITY_ACTION
。JobScheduler
そのため、接続状態を変更するために使用しようとしました。私はこのようにしました。
私はそのように作成しますJobService
:
public class NetworkStateScheduler extends JobService {
private Messenger jobServiceMessenger;
public static final String TAG = "NetworkStateScheduler";
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d(TAG, "onStartJob");
sendMessage(jobParameters.getJobId(), NetworkInfo.State.CONNECTED);
return true;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.d(TAG, "onStopJob");
sendMessage(jobParameters.getJobId(), NetworkInfo.State.DISCONNECTED);
return true;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
jobServiceMessenger = intent.getParcelableExtra(MESSENGER_INTENT_KEY);
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(MainActivity.START_SERVICE_FILTER));
return START_NOT_STICKY;
}
private void sendMessage(int messageID, Object params) {
if (jobServiceMessenger == null) {
Log.d(TAG, "Service is bound, not started. There's no callback to send a message to.");
return;
}
Message m = Message.obtain();
m.what = messageID;
m.obj = params;
try {
jobServiceMessenger.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Error passing service object back to activity.");
}
}
}
シンプルに見えると思いますが、JobService
が起動するjobServiceMessenger
と との通信に提供されJobService
ますMainActivity
。
主な活動:
public class MainActivity extends AppCompatActivity {
public static final String MESSENGER_INTENT_KEY = "IncomingMessage";
public static final String START_SERVICE_FILTER = "start.service";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(NetworkStateScheduler.TAG, "Service started");
scheduleJob();
}
}, new IntentFilter(START_SERVICE_FILTER));
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, NetworkStateScheduler.class);
intent.putExtra(MESSENGER_INTENT_KEY, new Messenger(new IncomingMessageHandler()));
startService(intent);
}
@Override
protected void onStop() {
stopService(new Intent(this, NetworkStateScheduler.class));
super.onStop();
}
public void scheduleJob() {
Log.i(NetworkStateScheduler.TAG, "Scheduling job");
JobScheduler jobScheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.cancelAll();
JobInfo jobInfo = new JobInfo.Builder(1,
new ComponentName(this, NetworkStateScheduler.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setBackoffCriteria(0, JobInfo.BACKOFF_POLICY_LINEAR)
.build();
jobScheduler.schedule(jobInfo);
}
private static class IncomingMessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
NetworkInfo.State state = (NetworkInfo.State) msg.obj;
Log.d(NetworkStateScheduler.TAG, "state " + state);
}
}
}
コードのこの部分では、ジョブを実行して接続状態を検出する必要があるため、JobService がいつ開始されたかを知るために単純なブロードキャスト レシーバーを追加しました。
現在、このように動作しています: アプリが開始されました。サービスが開始され、ジョブの実行がトリガーされました。接続が確立されると、onStartJob
メソッド fromJobService
が呼び出されます。接続が切断されると、メソッドonStopJob
が呼び出されます。デバイスでwifiを接続または切断するたびに、onStartJob
またはonStopJob
. しかし、カップルがアプリを実行した後JobService
、サービスからのメソッドが呼び出されないことがあります。どうしてか分かりません。なぜそれが適切に機能するのか理解できず、時には機能しないこともあります。決定論的ではありません。
どうすればこれを修正できますか? (Androidマニフェストにサービスを追加しました)