Skip to content

Instantly share code, notes, and snippets.

@kennjr
Created July 2, 2024 08:52
Show Gist options
  • Save kennjr/323fbaae907d26d57f8aaa80e065f57c to your computer and use it in GitHub Desktop.
Save kennjr/323fbaae907d26d57f8aaa80e065f57c to your computer and use it in GitHub Desktop.
A simple and concise way to observe available networks on android and whether they have an internet connection.
/*
* Copyright 2024 Ken Juniour
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* We're using this to check whether a network has internet,
* we do this because sometimes a network is available but lacks an internet connection
*/
object DoesNetworkHaveInternet {
fun execute(): Boolean{
return try {
// ping google server
val socket = Socket()
socket.connect(InetSocketAddress("8.8.8.8", 53), 1500)
socket.close()
true
}catch (e: IOException){
false
}
}
}
/*
* Copyright 2024 Ken Juniour
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkRequest
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import com.ramanie.android.common.SystemMessaging
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
class NetworkLiveData(context: Context): LiveData<Boolean>() {
private val TAG = "NetworkLiveDataTAG"
private lateinit var networkCallback: ConnectivityManager.NetworkCallback
private val connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private val validNetworks: MutableSet<Network> = HashSet()
private fun checkValidNetworks (){
postValue(validNetworks.size > 0)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
// when there's an observer registered to this liveData
override fun onActive() {
networkCallback = createNetworkCallback()
val networkRequest = NetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET).build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
checkValidNetworks()
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
// when there isn't an observer registered to this liveData
override fun onInactive() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun createNetworkCallback() = object :ConnectivityManager.NetworkCallback() {
/**
* Called when a network is detected.
* If that network has internet, save it to the validNetworks set
*/
override fun onAvailable(network: Network) {
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
val hasInternetAccess = networkCapabilities?.hasCapability(NET_CAPABILITY_INTERNET)
if (hasInternetAccess == true){
// check whether this network actually has internet connection
CoroutineScope(IO).launch {
val hasInternet = DoesNetworkHaveInternet.execute()
if (hasInternet){
validNetworks.add(network)
checkValidNetworks()
}
}
}
}
/**
* If the callback was registered with registerNetworkCallback(),
* the method below will be call for each network that doesn't satisfy the criteria of the callback
*/
override fun onLost(network: Network) {
validNetworks.remove(network)
checkValidNetworks()
}
}
}
@kennjr
Copy link
Author

kennjr commented Jul 2, 2024

Use this when you want to ensure that the user's device is connected to the internet for a certain task to be performed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment