Skip to content

Instantly share code, notes, and snippets.

@allco
Created December 4, 2018 16:41
Show Gist options
  • Save allco/d50fc10f523293d22fc3d85efe4aaff2 to your computer and use it in GitHub Desktop.
Save allco/d50fc10f523293d22fc3d85efe4aaff2 to your computer and use it in GitHub Desktop.
Rx'ie interface for the device `connected` state
package com.drivekitt.common
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkInfo
import android.os.Build
import androidx.annotation.RequiresApi
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ConnectivityReporter @Inject constructor(context: Context) {
@RequiresApi(Build.VERSION_CODES.N)
class ConnectivityReporterApi24(context: Context) {
val connectivityStatesStream: Observable<Boolean> = Observable.create<Boolean> { emitter ->
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) = emitter.onNext(true)
override fun onLost(network: Network?) = emitter.onNext(false)
}
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
cm.registerDefaultNetworkCallback(callback)
emitter.setCancellable { cm.unregisterNetworkCallback(callback) }
}
}
class ConnectivityReporterApi23(context: Context) {
companion object {
@Suppress("DEPRECATION")
private val INTENT_FILTER = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
}
val connectivityStatesStream: Observable<Boolean> = Observable.create<Boolean> { emitter ->
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when {
intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) -> emitter.onNext(false)
else -> {
@Suppress("DEPRECATION")
(intent.extras?.get(ConnectivityManager.EXTRA_NETWORK_INFO) as? NetworkInfo)
?.also { emitter.onNext(it.isConnected) }
}
}
}
}
context.registerReceiver(receiver, INTENT_FILTER)
emitter.setCancellable { context.unregisterReceiver(receiver) }
}
}
private val connectivityStatesStream by lazy {
when {
Build.VERSION.SDK_INT >= 24 -> ConnectivityReporterApi24(context).connectivityStatesStream
else -> ConnectivityReporterApi23(context).connectivityStatesStream
}
.distinctUntilChanged()
.debounce(200, TimeUnit.MILLISECONDS, Schedulers.io())
.replay(1)
.refCount()
}
/**
* @returns true if it's online, false otherwise
*/
fun statesStream(): Observable<Boolean> = connectivityStatesStream
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment