Saat kami mendaftarkan callback jaringan menggunakan registerNetworkCallbackmetode ini, terkadang tidak terpicu dan terkadang memicu positif palsu:
- Jika kita memulai aplikasi dengan koneksi internet,
onAvailablemetode tersebut akan dipicu.
- Tetapi jika tidak ada koneksi internet pada perangkat saat kita memulai aplikasi tidak ada yang
NetworkCallbackdisebut (sangat aneh karena hal. 1)
- Jika kita memiliki koneksi wifi tetapi tanpa
onAvailablepemicu metode koneksi internet . Dan saya pikir itu adalah perilaku positif palsu karena kami mengharapkan pengamatan koneksi internet.
Seperti yang Anda lihat pada kode di bawah ini secara default koneksi internet tersedia dan hanya terpicu jika berubah. Tidak ada pemicu positif palsu.
Rangkum saja ini dan jawaban ini (tetapi hanya untuk API> = 21):
class ConnectionManager @Inject constructor(
private val connectivityManager: ConnectivityManager,
private val disposable: CompositeDisposable,
private val singleTransformer: SingleTransformer<*, *>
) : LiveData<Boolean>() {
private var isNetworkAvailable = true
private val builder = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
private val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
ping()
}
override fun onLost(network: Network) {
ping()
}
}
private fun ping() {
disposable.add(
Single.fromCallable {
try {
val timeoutMs = 1500
val socket = Socket()
val socketAddress = InetSocketAddress("8.8.8.8", 53)
socket.connect(socketAddress, timeoutMs)
socket.close()
true
} catch (e: IOException) {
false
}
}
.compose(singleTransformer as SingleTransformer<Boolean, Boolean>)
.subscribeBy {
if (isNetworkAvailable != it){
value = it
isNetworkAvailable = it
}
}
)
}
override fun onActive() {
ping()
connectivityManager.registerNetworkCallback(builder.build(), callback)
}
override fun onInactive() {
disposable.clear()
connectivityManager.unregisterNetworkCallback(callback)
}
}
Bagaimana menyediakan dependensi
@Provides
fun provideTransformer(): SingleTransformer<Boolean, Boolean> {
return SingleTransformer<Boolean, Boolean> { upstream: Single<Boolean> ->
upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
@Singleton
@Provides
fun provideConnectivityManager(context: Context): ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@Singleton
@Provides
fun provideConnectionManager(connectivityManager: ConnectivityManager, singleTransformer: SingleTransformer<Boolean, Boolean>): ConnectionManager =
ConnectionManager(connectivityManager, singleTransformer)
Dan cara menggunakan:
@Inject
lateinit var connectionManager: ConnectionManager
viewLifecycleOwner.observe(connectionManager) { isInternetAvailable ->
}
targetSdkVersionke N atau nanti?