Androidでネットワークのタイプを確認するためのメソッドactiveNetworkInfo.typeを提供する接続マネージャーを使用したい。このメソッドはAPIレベル28で非推奨になりました。API28でネットワークタイプをチェックするソリューションは何ですか。私のコードは次のとおりです。
/**
* 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
}
はいgetType()
はAPI lavel 28で廃止されました
ここで、Use Callersを使用して、チェックに切り替える必要があります NetworkCapabilities.hasTransport(int)
また、 getAllNetworkInfo()
はAPIレベル29で非推奨になりました
次に、 getAllNetworks()
の代わりにUse 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
}
}
COMPLETE CODE
@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
}
いいえ、ここからわかるように: https://developer.Android.com/reference/Android/net/ConnectivityManager.html#getActiveNetworkInfo()
getActiveNetworkInfo()
は、引き続きAndroid API 28で使用可能です。非推奨とは言われていません。
ただし、非推奨ののは、NetworkInfoクラスのgetType()
です。
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()
は、メーター制または帯域幅に関連するアプリがより正確にこの情報を提供するため、これらのアプリが見るべきコールです。
私は自分のニーズに合わせて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
}
}
....
最小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
}
}