registerNetworkCallback메서드를 사용하여 네트워크 콜백을 등록 할 때 때때로 트리거되지 않고 때로는 거짓 긍정을 트리거합니다.
- 인터넷 연결로 앱을 시작하면
onAvailable메서드가 트리거됩니다.
- 그러나 우리가 앱을 시작할 때 장치에 인터넷 연결이 없으면 아무것도
NetworkCallback호출 되지 않습니다 (p. 1 때문에 매우 이상합니다)
- Wi-Fi 연결이 있지만 인터넷 연결
onAvailable방법이 없으면 트리거됩니다. 인터넷 연결 관찰을 기대하기 때문에 위양성 행동이라고 생각합니다.
아래 코드에서 볼 수 있듯이 기본적으로 인터넷 연결이 가능하며 변경되는 경우에만 트리거됩니다. 위양성 트리거가 없습니다.
그냥 요약 이 와 이 (하지만 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)
}
}
종속성을 제공하는 방법
@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)
그리고 사용 방법 :
@Inject
lateinit var connectionManager: ConnectionManager
viewLifecycleOwner.observe(connectionManager) { isInternetAvailable ->
}
targetSdkVersionN 이상으로 업이 필요한 동작을 원한다면 어떻게 될까요?