ネットワークの状態変更をAndroid Nでも常時受け取りたいと思ったのですが、ちょっと調べた範囲では「Activityでやりましょう」という記事が多かったため、メモがてら実行結果を残しておきます。
Android Nからの変更点
ご存知のように、Android Nからバックグラウンド処理の最適化が行われるようになりました。
そのため、Android Nからは以下のように AndroidManifest.xml に記載しても開発中は警告が出ますし、実際に起動させても通知してくれません。
AndroidManifest.xml
<manifest ...>
<application ...>
<receiver android:name=".ConnectivityBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
</manifest>
代替案
そのため、CONNECTIVITY_ACTION を registerReceiver で登録してあげることでAndroid N以降も動作するようになります。
試してみたところ、私の手元の端末2台では、Activity でも Service でも動作を確認できました。
以下は Service での例になります。
ConnectivityChangeService.kt
class ConnectivityChangeService : Service() {
override fun onBind(intent: Intent?): IBinder = Binder()
// 変更時処理
private val receiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null || context == null) {
return
}
val action = intent.action
if (action != ConnectivityManager.CONNECTIVITY_ACTION) {
return
}
// TODO
}
}
override fun onCreate() {
registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = START_REDELIVER_INTENT
override fun onDestroy() = try {
unregisterReceiver(receiver)
} catch (e : IllegalArgumentException) {
// エラー処理
}
}
※ Build.VERSION.SDK_INTでの分岐は適宜行ってください<(_ _)>
雑感
Android NでもCONNECTIVITY_CHANGEは受信可能になりました!
バージョンごとに次々と変更点が増えていくので、しっかりドキュメントを読んで代替案を使えるようにしていきたいと思います。