检查API29上的互联网连接

时间:2019-06-21 19:48:18

标签: java android

我使用以下方法检查Internet连接:

public boolean isInternetConnected() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.isConnected();
}

但是,我发现NetworkInfogetActiveNetworkInfo()isConnected()现在都已弃用。我已经在SO上检查了几个线程:

ConnectivityManager getNetworkInfo(int) deprecated

activeNetworkInfo.type is deprecated in API level 28

尽管如此,它们都提供了不赞成使用的方法的答案。我一直到处没有运气。是否有任何简单的方法来检查Internet连接,还是我应该继续使用我的方法而不考虑已弃用的方法,因为它可以使用API​​29?

谢谢。

3 个答案:

答案 0 :(得分:0)

看看.hasTransport

val networkAvailability = cm.getNetworkCapabilities(cm.activeNetwork)
if(networkAvailability !=null && networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
{
    //has network
    if (networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { //wifi
    } else if (networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { //cellular
    }
}

答案 1 :(得分:0)

这是我的SDK 29解决方案:名为@Entity(primaryKeys = {"groupId", "sentenceId"}) public class GroupIdsWithSentenceIdsJoin { @NotNull @ColumnInfo(name = "groupId", index = true) private String groupId; @NotNull @ColumnInfo(name = "sentenceId", index = true) private String sentenceId; @Ignore public GroupIdsWithSentenceIdsJoin(@NotNull String groupId, @NotNull String sentenceId) { this.groupId = groupId; this.sentenceId = sentenceId; } public GroupIdsWithSentenceIdsJoin() { } public String getGroupId() { return groupId; } public void setGroupId(String groupId) { this.groupId = groupId; } public String getSentenceId() { return sentenceId; } public void setSentenceId(String sentenceId) { this.sentenceId = sentenceId; } } 的类,用于观察网络的变化。它提供诸如NetworkWatcher之类的原始变量,并提供通过FlowLiveData观察网络随时间变化的选项。

isWifiOn

例如,您可以在应用程序中订阅有关电话网络状态的更新,例如:

@ExperimentalCoroutinesApi
class NetworkWatcher
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
private constructor(
    application: Application
) {

    private val connectivityManager =
        application.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                as ConnectivityManager

    // general availability of Internet over any type
    var isOnline = false
        get() {
            updateFields()
            return field
        }

    var isOverWifi = false
        get() {
            updateFields()
            return field
        }

    var isOverCellular = false
        get() {
            updateFields()
            return field
        }

    var isOverEthernet = false
        get() {
            updateFields()
            return field
        }

    companion object {
        @Volatile
        private var INSTANCE: NetworkWatcher? = null

        fun getInstance(application: Application): NetworkWatcher {
            synchronized(this) {
                if (INSTANCE == null) {
                    INSTANCE = NetworkWatcher(application)
                }
                return INSTANCE!!
            }
        }
    }

    @Suppress("DEPRECATION")
    private fun updateFields() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            val networkAvailability =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)

            if (networkAvailability != null &&
                networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
            ) {
                //has network
                isOnline = true

                // wifi
                isOverWifi =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)

                // cellular
                isOverCellular =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)

                // ethernet
                isOverEthernet =
                    networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
            } else {
                isOnline = false
                isOverWifi = false
                isOverCellular = false
                isOverEthernet = false
            }
        } else {

            val info = connectivityManager.activeNetworkInfo
            if (info != null && info.isConnected) {
                isOnline = true

                val wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                isOverWifi = wifi != null && wifi.isConnected

                val cellular = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
                isOverCellular = cellular != null && cellular.isConnected

                val ethernet = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET)
                isOverEthernet = ethernet != null && ethernet.isConnected

            } else {
                isOnline = false
                isOverWifi = false
                isOverCellular = false
                isOverEthernet = false
            }
        }
    }

    fun watchNetwork(): Flow<Boolean> = watchWifi()
        .combine(watchCellular()) { wifi, cellular -> wifi || cellular }
        .combine(watchEthernet()) { wifiAndCellular, ethernet -> wifiAndCellular || ethernet }

    fun watchNetworkAsLiveData(): LiveData<Boolean> = watchNetwork().asLiveData()

    fun watchWifi(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_WIFI)

    fun watchWifiAsLiveData() = watchWifi().asLiveData()

    fun watchCellular(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_CELLULAR)

    fun watchCellularAsLiveData() = watchCellular().asLiveData()

    fun watchEthernet(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_ETHERNET)

    fun watchEthernetAsLiveData() = watchEthernet().asLiveData()

    private fun callbackFlowForType(@IntRange(from = 0, to = 7) type: Int) = callbackFlow {

        offer(false)

        val networkRequest = NetworkRequest.Builder()
            .addTransportType(type)
            .build()

        val callback = object : ConnectivityManager.NetworkCallback() {
            override fun onLost(network: Network?) {
                offer(false)
            }

            override fun onUnavailable() {
                offer(false)
            }

            override fun onLosing(network: Network?, maxMsToLive: Int) {
                // do nothing
            }

            override fun onAvailable(network: Network?) {
                offer(true)
            }
        }

        connectivityManager.registerNetworkCallback(networkRequest, callback)

        awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
    }
}

或者要回答您的问题,只需阅读Wifi值,例如:

GlobalScope.launch {
    NetworkWatcher.getInstance(this@MyApplication).watchNetwork().collect { connected ->
        Log.d("TAG", "Network In App: $connected")
    }
}

旁注:我不是一直使用if (NetworkWatcher.getInstance(this@BaseApp).isOverWifi) { // do stuff } ,而是使用诸如Koin之类的DI框架将NetworkWatcher注入我需要的地方。

答案 2 :(得分:0)

在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

现在检查网络状态:

 @IntRange(from = 0, to = 3)
fun getConnectionType(context: Context): Int {
    var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        val capabilities =
            cm.getNetworkCapabilities(cm.activeNetwork)
        if (capabilities != null) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                result = 2
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                result = 1
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
                result = 3
            }

        }
    } else {

        val activeNetwork = cm.activeNetworkInfo
        if (activeNetwork != null) {
            // connected to the internet
            if (activeNetwork.type === ConnectivityManager.TYPE_WIFI) {
                result = 2
            } else if (activeNetwork.type === ConnectivityManager.TYPE_MOBILE) {
                result = 1
            } else if (activeNetwork.type === ConnectivityManager.TYPE_VPN) {
                result = 3
            }
        }
    }
    return result
}