Khi chúng tôi đăng ký một cuộc gọi lại mạng bằng registerNetworkCallbackphương pháp này, đôi khi nó không kích hoạt và đôi khi nó kích hoạt dương tính giả:
- Nếu chúng tôi khởi động ứng dụng bằng kết nối internet,
onAvailablephương thức sẽ kích hoạt.
- Nhưng nếu không có kết nối internet trên thiết bị khi chúng tôi khởi động một ứng dụng thì sẽ không có gì
NetworkCallbackđược gọi là (rất lạ vì trang 1)
- Nếu chúng ta có kết nối wifi nhưng không có
onAvailablekích hoạt phương thức kết nối internet . Và tôi nghĩ đó là hành vi tích cực giả bởi vì chúng tôi mong đợi sự quan sát của kết nối internet.
Như bạn thấy trong đoạn mã dưới đây theo mặc định kết nối internet khả dụng và nó chỉ kích hoạt nếu nó thay đổi. Không có kích hoạt dương tính giả.
Chỉ tóm tắt điều này và này câu trả lời (nhưng chỉ cho 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)
}
}
Cách cung cấp các phụ thuộc
@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)
Và cách sử dụng:
@Inject
lateinit var connectionManager: ConnectionManager
//....
viewLifecycleOwner.observe(connectionManager) { isInternetAvailable ->
// TODO
}
targetSdkVersionlên N hoặc mới hơn?