activeNetworkInfo.type устарела на уровне API 28
Я хочу использовать диспетчер подключений, который предоставляет метод activeNetworkInfo.type для проверки типа сети в Android. Этот метод устарел на уровне API 28. Итак, что такое решение для проверки типа сети в API 28. мой код:
/**
* 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
}
Мой Gradle это как:
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
}
Ответы
Ответ 1
Да getType()
устарело в уровне API 28
Теперь нам нужно использовать Use Callers, чтобы переключиться на проверку NetworkCapabilities.hasTransport(int)
Также getAllNetworkInfo()
устарело на уровне API 29
Теперь нам нужно использовать getAllNetworks()
вместо getNetworkInfo(android.net.Network)
.
getNetworkInfo()
- Возвращает информацию о состоянии соединения для определенной сети.
getAllNetworks()
- Возвращает массив всей сети, отслеживаемой в настоящее время платформой.
ОБРАЗЕЦ КОДА
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
}
}
ПОЛНЫЙ КОД
@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
}
Ответ 2
Нет, как видно здесь: https://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()
getActiveNetworkInfo()
по-прежнему доступна в Android API 28, и нигде не говорится, что она устарела.
Но не рекомендуется использовать getType()
класса NetworkInfo.
https://developer.android.com/reference/android/net/NetworkInfo#getType()
Этот метод устарел на уровне API 28.
Вызывающие абоненты должны переключиться на проверку NetworkCapabilities.hasTransport(int)
вместо этого с одной из NetworkCapabilities#TRANSPORT_* constants: getType()
и getTypeName()
не могут учитывать сети, использующие несколько транспортов. Обратите внимание, что обычно приложения не должны заботиться о транспорте; NetworkCapabilities.NET_CAPABILITY_NOT_METERED
и NetworkCapabilities.getLinkDownstreamBandwidthKbps()
- это вызовы, на которые должны смотреть приложения, связанные с измерением или пропускной способностью, поскольку они предоставляют эту информацию с гораздо большей точностью.
Ответ 3
Я адаптировал ответ Nilesh Rathod для своих нужд:
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
}
Затем я проверяю соединение с 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
}
}
....
Ответ 4
Если вы используете минимальный уровень API 23, вы можете использовать эту сокращенную версию 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
}
}