web-dev-qa-db-fra.com

activeNetworkInfo.type est obsolète au niveau de l'API 28

enter image description here Je veux utiliser le gestionnaire de connectivité qui fournit la méthode activeNetworkInfo.type pour vérifier le type de réseau dans Android. Cette méthode est obsolète au niveau de l'API 28. Quelle est donc la solution pour vérifier le type de réseau dans l'API 28. Mon code est:

/**
 * Check Wi Fi connectivity
 */
fun isWiFiConnected(context: Context): Boolean {
    val connManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return connManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
}

Mon Gradle est comme:

compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
    }
11
Pitty

Oui getType() est déconseillé dans l'API lavel 28

Maintenant, nous devons utiliser Utiliser les appelants doivent passer à la vérification NetworkCapabilities.hasTransport (int)

getAllNetworkInfo() est également déconseillé au niveau API 29

Maintenant, nous devons utiliser Use getAllNetworks() au lieu de getNetworkInfo(Android.net.Network) .

getNetworkInfo()

  • Renvoie des informations sur l'état de la connexion d'un réseau particulier.

getAllNetworks()

  • Renvoie un tableau de tous les réseaux actuellement suivis par le framework.

EXEMPLE DE CODE

fun isWiFiConnected(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.M) {
        val network = connectivityManager.activeNetwork
        val capabilities = connectivityManager.getNetworkCapabilities(network)
        capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
    } else {
        connectivityManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
    }
}

CODE COMPLET

@Suppress("DEPRECATION")
fun isInternetAvailable(context: Context): Boolean {
    var result = false
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm?.run {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                result = when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            }
        }
    } else {
        cm?.run {
            cm.activeNetworkInfo?.run {
                if (type == ConnectivityManager.TYPE_WIFI) {
                    result = true
                } else if (type == ConnectivityManager.TYPE_MOBILE) {
                    result = true
                }
            }
        }
    }
    return result
}
15
Nilesh Rathod

Non, comme vu d'ici: https://developer.Android.com/reference/Android/net/ConnectivityManager.html#getActiveNetworkInfo ()

getActiveNetworkInfo() est toujours disponible dans Android API 28, et ne dit nulle part qu'il est obsolète.

Mais celui déconseillé est getType() de la classe NetworkInfo .

https://developer.Android.com/reference/Android/net/NetworkInfo#getType ()

Cette méthode est déconseillée au niveau 28 de l'API.

Les appelants doivent passer à la vérification de NetworkCapabilities.hasTransport(int) à la place avec l'un des NetworkCapabilities#TRANSPORT_* constants : getType() et getTypeName() ne peuvent pas tenir compte des réseaux utilisant plusieurs transports. Notez que généralement les applications ne devraient pas se soucier du transport; NetworkCapabilities.NET_CAPABILITY_NOT_METERED Et NetworkCapabilities.getLinkDownstreamBandwidthKbps() sont des appels que les applications concernées par la mesure ou la bande passante devraient regarder, car elles offrent ces informations avec une bien meilleure précision.

3
shizhen

J'ai adapté la réponse de Nilesh Rathod à mes besoins:

enum class ConnectivityMode {
    NONE,
    WIFI,
    MOBILE,
    OTHER,
    MAYBE
}

var connectivityMode = ConnectivityMode.NONE

private fun checkConnectivity(context: Context): ConnectivityMode {

    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    cm?.run {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getNetworkCapabilities(activeNetwork)?.run {
                return when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> ConnectivityMode.WIFI
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> ConnectivityMode.MOBILE
                    hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> ConnectivityMode.OTHER
                    hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> ConnectivityMode.MAYBE
                    else -> ConnectivityMode.NONE
                }
            }
        } else {
            @Suppress("DEPRECATION")
            activeNetworkInfo?.run {
                return when (type) {
                    ConnectivityManager.TYPE_WIFI -> ConnectivityMode.WIFI
                    ConnectivityManager.TYPE_MOBILE -> ConnectivityMode.MOBILE
                    ConnectivityManager.TYPE_ETHERNET -> ConnectivityMode.OTHER
                    ConnectivityManager.TYPE_BLUETOOTH -> ConnectivityMode.MAYBE
                    else -> ConnectivityMode.NONE
                }
            }
        }
    }
    return ConnectivityMode.NONE
}

Ensuite, je vérifie la connexion avec okhttp:

fun updateData(manual: Boolean, windowContext: Context) = runBlocking {
    connectivityMode = checkConnectivity(MyApplication.context)
    if (connectivityMode != ConnectivityMode.NONE) {
        val conn : Boolean = GlobalScope.async {
            var retval = false
            try {
                val request = Request.Builder().url(WORK_URL).build()
                val response =  client.newCall(request).execute()
                Log.i(TAG, "code = ${response?.code}")
                if (response?.code == 200) {
                    // I use the response body since it is a small file and already downloaded
                    val input = response.body?.byteStream()
                    if (input != null) {
                        // do stuff
                        response.body?.close()
                        retval = true
                    }
                }
            }
            catch(exception: Exception) {
                Log.e(TAG, "error ${exception.message ?: ""}")
            }
            retval
        }.await()
        if (!conn) {
            connectivityMode = ConnectivityMode.NONE
        }
    }
    ....
0
Dominique Lorre

Si vous utilisez le niveau minimal d'API 23, vous pouvez utiliser cette version raccourcie de Kotlin.

fun isNetworkAvailable(context: Context): Boolean {
    (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
        return getNetworkCapabilities(activeNetwork)?.run {
            when {
                hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                else -> false
            }
        } ?: false
    }
}
0
Donny Rozendal