我想使用连接管理器,它提供了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
}
我的摇篮就像:
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
}
答案 0 :(得分:6)
稍简单的版本(minSdkVersion 23 +)
fun isNetworkAvailable(context: Context) =
(context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
getNetworkCapabilities(activeNetwork)?.run {
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
} ?: false
}
答案 1 :(得分:4)
Yes getType()
is depricated in API lavel 28
现在我们需要使用“使用呼叫者”,应该切换到检查NetworkCapabilities.hasTransport(int)
也 getAllNetworkInfo()
is depricated in API lavel 23
现在我们需要改用Use 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
}
}
答案 2 :(得分:4)
我正在使用此Kotlin功能检查互联网连接:
请注意版本检查(版本> = M)
private fun isInternetConnected():Boolean{
val connectivityManager = this.getSystemService(android.content.Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val activeNetwork = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
return when {
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
else -> false
}
}
else {
return connectivityManager.activeNetworkInfo != null &&
connectivityManager.activeNetworkInfo!!.isConnectedOrConnecting
}
}
答案 3 :(得分:3)
我只是想知道设备是否连接到互联网,无论连接类型如何:
@Suppress("DEPRECATION")
fun isOnline(context: Context?): Boolean {
var connected = false
@Suppress("LiftReturnOrAssignment")
context?.let {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = cm.activeNetwork ?: return false
val actNw = cm.getNetworkCapabilities(networkCapabilities) ?: return false
connected = actNw.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
} else {
val netInfo = cm.activeNetworkInfo
connected = netInfo?.isConnectedOrConnecting == true
}
}
return connected
}
答案 4 :(得分:2)
否,从这里可以看到: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()
是那些 与计量或带宽有关的应用程序应注意 他们以更高的准确性提供了这些信息。
答案 5 :(得分:2)
我已根据需要调整了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
}
}
....
答案 6 :(得分:2)
这是我的SDK 29解决方案:名为NetworkWatcher
的类,用于观察网络的变化。它提供诸如isWifiOn
之类的原始变量,并提供通过Flow和LiveData观察网络随时间变化的选项。
@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) }
}
}
例如,您可以在应用程序中订阅有关电话网络状态的更新,例如:
GlobalScope.launch {
NetworkWatcher.getInstance(this@MyApplication).watchNetwork().collect { connected ->
Log.d("TAG", "Network In App: $connected")
}
}
或者要回答您的问题,只需阅读Wifi值,例如:
if (NetworkWatcher.getInstance(this@BaseApp).isOverWifi) {
// do stuff
}
旁注:我不是一直使用getInstance()
,而是使用诸如Koin之类的DI框架将NetworkWatcher注入我需要的地方。
答案 7 :(得分:0)
如果您使用的是最低API级别23,则可以使用此简短的Kotlin版本。
ionic integrations enable cordova --add
答案 8 :(得分:0)
最近,我不得不编写一个小函数来检查单个WebView内部的网络连接。我还注意到API发生了很大的变化,尤其是当Kotlin进来时,找到有效的参考花了几分钟。
这是我的小型NetworkConnectivityManager
类,具有用于检查网络可用性的简单功能。
import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
class NetworkConnectivityManager(context: Context) {
private val connectivityManager =
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
@Suppress("DEPRECATION")
fun isNetworkAvailable(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
nc != null
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
}
答案 9 :(得分:0)
Java代码:
public static boolean isConnectingToInternet(Context mContext) {
if (mContext == null) return false;
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final Network network = connectivityManager.getActiveNetwork();
if (network != null) {
final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);
return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
}
} else {
NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
for (NetworkInfo tempNetworkInfo : networkInfos) {
if (tempNetworkInfo.isConnected()) {
return true;
}
}
}
}
return false;
}
答案 10 :(得分:0)
我希望这对您有用! 此代码可在api 21及更高版本中使用
//创建一个新类并添加以下内容
public class CheckNetwork {
public static boolean isNetworkConnected;
private Context context;
public CheckNetwork(Context context) {
this.context = context;
}
public boolean isOnline(){
isNetworkConnected = false;
ConnectivityManager connectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] allNetworks = connectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)
for (Network network : allNetworks) {
NetworkCapabilities networkCapabilities = connectivityMgr.getNetworkCapabilities(network);
if (networkCapabilities != null) {
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
isNetworkConnected = true;
}
}
return isNetworkConnected;
}
}
//在MainActivity中
CheckNetwork myNetwork = new CheckNetwork(this);
//在OnCreateMethod中
myNetwork.isOnline();
if (myNetwork.isNetworkConnected){
Toast.makeText(this, "Please check your Internet Connection", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Your Internet Connction is Ok", Toast.LENGTH_SHORT).show();
}
答案 11 :(得分:0)
这是Kotlin实现的两种新旧api方法:
@Suppress("DEPRECATION")
fun isConnectedOld(context: Context): Boolean {
val connManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connManager.activeNetworkInfo
return networkInfo.isConnected
}
@RequiresApi(Build.VERSION_CODES.M)
fun isConnectedNewApi(context: Context): Boolean {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
return capabilities?.hasCapability(NET_CAPABILITY_INTERNET) == true
}
和常用方法:
fun isConnected(context: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
isConnectedNewApi(context)
} else{
isConnectedOld(context)
}
}
答案 12 :(得分:0)
完整的解决方案 在包中创建这些类,可以说连通性
导入android.content.Context 导入android.content.Context.CONNECTIVITY_SERVICE 导入android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkInfo
import android.os.Build
import androidx.annotation.RequiresApi
interface ConnectivityProvider {
interface ConnectivityStateListener {
fun onStateChange(state: NetworkState)
}
fun addListener(listener: ConnectivityStateListener)
fun removeListener(listener: ConnectivityStateListener)
fun getNetworkState(): NetworkState
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
sealed class NetworkState {
object NotConnectedState : NetworkState()
sealed class ConnectedState(val hasInternet: Boolean) : NetworkState() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
data class Connected(val capabilities: NetworkCapabilities) : ConnectedState(
capabilities.hasCapability(NET_CAPABILITY_INTERNET)
)
@Suppress("DEPRECATION")
data class ConnectedLegacy(val networkInfo: NetworkInfo) : ConnectedState(
networkInfo.isConnectedOrConnecting
)
}
}
companion object {
fun createProvider(context: Context): ConnectivityProvider {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityProviderImpl(cm)
} else {
ConnectivityProviderLegacyImpl(context, cm)
}
}
}
}
抽象类ConnectivityProviderBaseImpl
abstract class ConnectivityProviderBaseImpl : ConnectivityProvider {
private val handler = Handler(Looper.getMainLooper())
private val listeners = mutableSetOf<ConnectivityStateListener>()
private var subscribed = false
override fun addListener(listener: ConnectivityStateListener) {
listeners.add(listener)
listener.onStateChange(getNetworkState()) // propagate an initial state
verifySubscription()
}
override fun removeListener(listener: ConnectivityStateListener) {
listeners.remove(listener)
verifySubscription()
}
private fun verifySubscription() {
if (!subscribed && listeners.isNotEmpty()) {
subscribe()
subscribed = true
} else if (subscribed && listeners.isEmpty()) {
unsubscribe()
subscribed = false
}
}
protected fun dispatchChange(state: NetworkState) {
handler.post {
for (listener in listeners) {
listener.onStateChange(state)
}
}
}
protected abstract fun subscribe()
protected abstract fun unsubscribe()
}
ConnectivityProviderImpl类
@RequiresApi(Build.VERSION_CODES.N)
class ConnectivityProviderImpl(private val cm: ConnectivityManager) :
ConnectivityProviderBaseImpl() {
private val networkCallback = ConnectivityCallback()
override fun subscribe() {
cm.registerDefaultNetworkCallback(networkCallback)
}
override fun unsubscribe() {
cm.unregisterNetworkCallback(networkCallback)
}
override fun getNetworkState(): NetworkState {
val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
return if (capabilities != null) {
Connected(capabilities)
} else {
NotConnectedState
}
}
private inner class ConnectivityCallback : NetworkCallback() {
override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
dispatchChange(Connected(capabilities))
}
override fun onLost(network: Network) {
dispatchChange(NotConnectedState)
}
}
}
@Suppress(“ DEPRECATION”)
class ConnectivityProviderLegacyImpl(
private val context: Context,
private val cm: ConnectivityManager
) : ConnectivityProviderBaseImpl() {
private val receiver = ConnectivityReceiver()
override fun subscribe() {
context.registerReceiver(receiver, IntentFilter(CONNECTIVITY_ACTION))
}
override fun unsubscribe() {
context.unregisterReceiver(receiver)
}
override fun getNetworkState(): NetworkState {
val activeNetworkInfo = cm.activeNetworkInfo
return if (activeNetworkInfo != null) {
ConnectedLegacy(activeNetworkInfo)
} else {
NotConnectedState
}
}
private inner class ConnectivityReceiver : BroadcastReceiver() {
override fun onReceive(c: Context, intent: Intent) {
// on some devices ConnectivityManager.getActiveNetworkInfo() does not provide the correct network state
// https://issuetracker.google.com/issues/37137911
val networkInfo = cm.activeNetworkInfo
val fallbackNetworkInfo: NetworkInfo? = intent.getParcelableExtra(EXTRA_NETWORK_INFO)
// a set of dirty workarounds
val state: NetworkState =
if (networkInfo?.isConnectedOrConnecting == true) {
ConnectedLegacy(networkInfo)
} else if (networkInfo != null && fallbackNetworkInfo != null &&
networkInfo.isConnectedOrConnecting != fallbackNetworkInfo.isConnectedOrConnecting
) {
ConnectedLegacy(fallbackNetworkInfo)
} else {
val state = networkInfo ?: fallbackNetworkInfo
if (state != null) ConnectedLegacy(state) else NotConnectedState
}
dispatchChange(state)
}
}
}
用法:-家庭活动
class HomeActivity : BaseActivity(), ConnectivityProvider.ConnectivityStateListener {
val provider: ConnectivityProvider by lazy { ConnectivityProvider.createProvider(this@HomeActivity) }
override fun onStart() {
super.onStart()
provider.addListener(this)
}
override fun onStop() {
super.onStop()
provider.removeListener(this)
}
override fun onStateChange(state: ConnectivityProvider.NetworkState) {
val hasInternet = state.hasInternet()
}
companion object {
fun ConnectivityProvider.NetworkState.hasInternet(): Boolean {
return (this as? ConnectivityProvider.NetworkState.ConnectedState)?.hasInternet == true
}
}
单击按钮或任何api调用
if(provider.getNetworkState().hasInternet()){
// do work
}
}
如果您要在家庭活动的片段中使用Check Internet
if ((activity as HomeActivity).provider.getNetworkState().hasInternet()) {
// api call
}
答案 13 :(得分:0)
对于版本 >= Build.VERSION_CODES.M
:
private fun isConnected(context: Context): Boolean {
val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
val capabilities = manager?.getNetworkCapabilities(manager.activeNetwork) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
}