检查Kotlin中的Internet连接android

Kak*_*shi 9 android kotlin

我试图回答这个(接受的答案)。我可以使用“ PING”方法,但是UI变黑了,因为它说它将阻塞UI线程。它看起来并不好并且令人不安,所以我尝试使用第二种方法“连接到Internet上的套接字”,但是我不知道如何在Kotlin中使用该类。

这是android studio将Java转换为kotlin的结果

package com.mockie.daikokuten.helpers

import android.os.AsyncTask.execute
import android.os.AsyncTask
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Socket


internal class InternetCheck(private val mConsumer: Consumer) : AsyncTask<Void, Void, Boolean>() {
interface Consumer {
    fun accept(internet: Boolean?)
}

init {
    execute()
}

override fun doInBackground(vararg voids: Void): Boolean? {
    try {
        val sock = Socket()
        sock.connect(InetSocketAddress("8.8.8.8", 53), 1500)
        sock.close()
        return true
    } catch (e: IOException) {
        return false
    }

}

override fun onPostExecute(internet: Boolean?) {
    mConsumer.accept(internet)
}
}
Run Code Online (Sandbox Code Playgroud)

但是我不知道如何使用它。我这样尝试:

InternetCheck{ internet-> Log.d("test", "asdasdas") }
Run Code Online (Sandbox Code Playgroud)

它没有工作,并导致错误。它说我必须通过“消费者”。

我的问题是如何使用该课程

Jor*_*sys 39

更新: 自 Android 10 起,NetWorkInfo类及其方法的使用已过时,现在您必须使用NetworkCapabilities Class 中的 ConectivityManager 类和getNetworkCapabilities ()方法

如何在Android中检查连接?

科特林

fun isOnline(context: Context): Boolean {
    val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (connectivityManager != null) {
        val capabilities =
            connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                return true
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                return true
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                return true
            }
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

爪哇:

public static boolean isOnline(Context context) {
       ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

if (connectivityManager != null) {
       NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR");
                return true;
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI");
                return true;
            }  else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)){
                Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET");
                return true;
            }
        }
    }

return false;
}
Run Code Online (Sandbox Code Playgroud)

这两种方法都需要权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
Run Code Online (Sandbox Code Playgroud)

  • `connectivityManager.activeNetworkInfo` 已弃用 (12认同)
  • 这只检查网络是否可用,但不检查连接是否正常工作。例如,如果您已连接到 WiFi 路由器,但路由器与调制解调器断开连接,则此代码将返回“true” (3认同)
  • 答案已更新,谢谢! (2认同)

小智 17

在 android kotlin 中检查互联网连接

fun isNetworkAvailable(context: Context?): Boolean {
    if (context == null) return false
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            when {
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                    return true
                }
            }
        }
    } else {
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
            return true
        }
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)

  • &gt;= Build.VERSION_CODES.Q 不是 Build.VERSION_CODES.M 吗?这是linter在AndroidStudio中说的 (3认同)

小智 16

使用 LiveData 实时监控互联网连接 - Kotlin

我在 YouTube 上看到了这个很棒的教程。我们只需要添加一个扩展LiveData 的实用程序文件,并可以在我们的 Activity 或 Fragment 中观察它。

用法

    private lateinit var connectionLiveData: ConnectionLiveData

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityInternetConnectionTestBinding.inflate(layoutInflater)
        setContentView(binding.root)

        connectionLiveData = ConnectionLiveData(this)
        connectionLiveData.observe(this) { isNetworkAvailable ->
            isNetworkAvailable?.let {
                updateUI(it)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

实用程序文件

const val TAG = "MyTagConnectionManager"

class ConnectionLiveData(context: Context) : LiveData<Boolean>() {

    private lateinit var networkCallback: ConnectivityManager.NetworkCallback
    private val connectivityManager =
        context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    private val validNetworks: MutableSet<Network> = HashSet()

    private fun checkValidNetworks() {
        postValue(validNetworks.size > 0)
    }

    override fun onActive() {
        networkCallback = createNetworkCallback()
        val networkRequest = NetworkRequest.Builder()
            .addCapability(NET_CAPABILITY_INTERNET)
            .build()
        connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
    }

    override fun onInactive() {
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }

    private fun createNetworkCallback() = object : ConnectivityManager.NetworkCallback() {

        override fun onAvailable(network: Network) {
            Log.d(TAG, "onAvailable: $network")
            val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
            val hasInternetCapability = networkCapabilities?.hasCapability(NET_CAPABILITY_INTERNET)
            Log.d(TAG, "onAvailable: ${network}, $hasInternetCapability")

            if (hasInternetCapability == true) {
                // Check if this network actually has internet
                CoroutineScope(Dispatchers.IO).launch {
                    val hasInternet = DoesNetworkHaveInternet.execute(network.socketFactory)
                    if (hasInternet) {
                        withContext(Dispatchers.Main) {
                            Log.d(TAG, "onAvailable: adding network. $network")
                            validNetworks.add(network)
                            checkValidNetworks()
                        }
                    }
                }
            }
        }

        override fun onLost(network: Network) {
            Log.d(TAG, "onLost: $network")
            validNetworks.remove(network)
            checkValidNetworks()
        }
    }

    object DoesNetworkHaveInternet {

        fun execute(socketFactory: SocketFactory): Boolean {
            // Make sure to execute this on a background thread.
            return try {
                Log.d(TAG, "PINGING Google...")
                val socket = socketFactory.createSocket() ?: throw IOException("Socket is null.")
                socket.connect(InetSocketAddress("8.8.8.8", 53), 1500)
                socket.close()
                Log.d(TAG, "PING success.")
                true
            } catch (e: IOException) {
                Log.e(TAG, "No Internet Connection. $e")
                false
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

 fun verifyAvailableNetwork(activity:AppCompatActivity):Boolean{
      val connectivityManager=activity.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
      val networkInfo=connectivityManager.activeNetworkInfo
      return  networkInfo!=null && networkInfo.isConnected
}
Run Code Online (Sandbox Code Playgroud)

  • connectivityManager.activeNetworkInfo 已弃用 (11认同)

Vis*_* M. 9

以这种方式调用AsyncTask,它应该可以工作。您无需在InternetCheck AsyncTask中进行任何更改。基本上,您需要传入一个实现InternetCheck类中定义的Consumer接口的对象。

InternetCheck(object : InternetCheck.Consumer {
    override fun accept(internet: Boolean?) {
        Log.d("test", "asdasdas")
    }
})
Run Code Online (Sandbox Code Playgroud)


Nav*_*T P 6

尝试使用此实用方法来检查互联网的可用性。

fun isNetworkAvailable(context: Context): Boolean {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        var activeNetworkInfo: NetworkInfo? = null
        activeNetworkInfo = cm.activeNetworkInfo
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
    }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 如果连接到 wifi 但没有互联网连接,该代码将返回 true (2认同)
  • @NaveenTP 我认为你正在避免 X - Y 问题。 (2认同)

小智 6

在清单的顶部添加这些权限

   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.INTERNET"/>
Run Code Online (Sandbox Code Playgroud)

这个函数应该可以解决问题。它将根据其连接性返回布尔值

fun isOnline(context: Context): Boolean {
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val n = cm.activeNetwork
        if (n != null) {
            val nc = cm.getNetworkCapabilities(n)
    //It will check for both wifi and cellular network
            return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        }
        return false
    } else {
        val netInfo = cm.activeNetworkInfo
        return netInfo != null && netInfo.isConnectedOrConnecting
    }
}
Run Code Online (Sandbox Code Playgroud)

它有一个已弃用的方法以及基于您的 api 版本的最新方法。


Vla*_*lad 5

最短版本

val Context.isConnected: Boolean
    get() {
        return (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
           .activeNetworkInfo?.isConnected == true
    }
Run Code Online (Sandbox Code Playgroud)

  • 这仅检查我们是否有网络,而不检查我们是否“在线”,即连接到互联网。 (2认同)