Android getAllNetworkInfo() 已弃用。啥是替代方案?
Posted
技术标签:
【中文标题】Android getAllNetworkInfo() 已弃用。啥是替代方案?【英文标题】:Android getAllNetworkInfo() is Deprecated. What is the alternative?Android getAllNetworkInfo() 已弃用。什么是替代方案? 【发布时间】:2015-11-21 10:09:26 【问题描述】:我想使用ConnectivityManager
提供getAllNetworkInfo()
方法来检查android 中的网络可用性。此方法在 API 级别 23 中已弃用。开发人员文档建议改用getAllNetworks()
。我尝试过,但无法从旧代码中获得确切的功能。请有人指导我如何使用getAllNetworks()
方法?
public boolean isConnectingToInternet()
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
@SuppressWarnings("deprecation")
NetworkInfo[] info = connectivity.getAllNetworkInfo();
//use getAllNetworks() instead
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
return true;
return false;
【问题讨论】:
ConnectivityManager getNetworkInfo(int) deprecated的可能重复 在这里回答 - ***.com/questions/32547006/… 【参考方案1】:当我更新已弃用的代码但仍想支持向后 Api 时。我用这个:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.WANTED API VERSION)
//code
else
//code
通过这种方式,每个设备都为其使用适当的代码。 示例:
public class ConnectionDetector
private Context mContext;
public ConnectionDetector(Context context)
this.mContext = context;
/**
* Checking for all possible internet providers
* **/
public boolean isConnectingToInternet()
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
Network[] networks = connectivityManager.getAllNetworks();
NetworkInfo networkInfo;
for (Network mNetwork : networks)
networkInfo = connectivityManager.getNetworkInfo(mNetwork);
if (networkInfo.getState().equals(NetworkInfo.State.CONNECTED))
return true;
else
if (connectivityManager != null)
//noinspection deprecation
NetworkInfo[] info = connectivityManager.getAllNetworkInfo();
if (info != null)
for (NetworkInfo anInfo : info)
if (anInfo.getState() == NetworkInfo.State.CONNECTED)
LogUtils.d("Network",
"NETWORKNAME: " + anInfo.getTypeName());
return true;
Toast.makeText(mContext,mContext.getString(R.string.please_connect_to_internet),Toast.LENGTH_SHORT).show();
return false;
【讨论】:
你所有的设备都是男性吗? :O ;-) 请注意,NetworkInfo#getState 也已弃用。【参考方案2】:我已经制作了可以帮助您检查的实用程序:
如果网络已连接。 如果已连接 WiFi。 如果移动数据已连接。它根据运行平台使用旧 API 或新 API:
import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.os.Build;
import android.support.annotation.NonNull;
public class NetworkUtils
public static boolean isConnected(@NonNull Context context)
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
public static boolean isWifiConnected(@NonNull Context context)
return isConnected(context, ConnectivityManager.TYPE_WIFI);
public static boolean isMobileConnected(@NonNull Context context)
return isConnected(context, ConnectivityManager.TYPE_MOBILE);
private static boolean isConnected(@NonNull Context context, int type)
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
NetworkInfo networkInfo = connMgr.getNetworkInfo(type);
return networkInfo != null && networkInfo.isConnected();
else
return isConnected(connMgr, type);
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean isConnected(@NonNull ConnectivityManager connMgr, int type)
Network[] networks = connMgr.getAllNetworks();
NetworkInfo networkInfo;
for (Network mNetwork : networks)
networkInfo = connMgr.getNetworkInfo(mNetwork);
if (networkInfo != null && networkInfo.getType() == type && networkInfo.isConnected())
return true;
return false;
更新:
有关@TargetApi
和@RequiresApi
的更多信息:
https://***.com/a/40008157/421467
https://developer.android.com/reference/kotlin/androidx/annotation/RequiresApi
【讨论】:
请记住,在一些奇怪的设备上:connMgr.getNetworkInfo(mNetwork)
可能会抛出 NullPointerExcecption。今天发生在我身上,似乎是由 IConnectivityManager 内的本机方法抛出的。解决方法是在你的 for 循环中尝试/捕获它,并决定回退到这个特定网络的不推荐使用的方法。
@MariusC 感谢您的回复,请将崩溃的堆栈跟踪发送到 gmail.com 的 yakiv.mospan。将 Nullpointer 包装在 try-catch 中是非常糟糕的做法。我们也需要避免 Nullpointer 本身。也许mNetwork
有问题,也许那个奇怪的设备不支持getAllNetwokrs
返回的某些网络?
@MariusC 顺便说一句,它是什么设备,它在其他设备上工作,你确定你有权限ACCESS_NETWORK_STATE
吗?
嗨 Yakiv,请在下面找到我在 Android 框架项目上打开的与该错误相关的票:github.com/android/platform_frameworks_base/issues/123
另外...我知道抓住它是一种不好的做法,而且这是一个丑陋的解决方法,但到目前为止,这是我能做的最好的事情,你无法避免这种情况,因为正在发生随机,您不能在 Network 实例上提供任何信息来避免这种情况。【参考方案3】:
如果有人需要 Kotlin 版本,(下面是与 Maor Hadad 相同的代码)
fun Context.isNetworkConnected(): Boolean
val manager = getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
val allNetworks = manager?.allNetworks?.let it ?: return false
allNetworks.forEach network ->
val info = manager.getNetworkInfo(network)
if (info.state == NetworkInfo.State.CONNECTED) return true
else
val allNetworkInfo = manager?.allNetworkInfo?.let it ?: return false
allNetworkInfo.forEach info ->
if (info.state == NetworkInfo.State.CONNECTED) return true
return false
此代码是 Context 的扩展方法。
在任何kotlin文件(.kt)中写下这段代码,然后你就可以在任何实现了Context的类(如Activity)中使用该方法。
【讨论】:
这是一个更实用的方法return manager.allNetworks.any NetworkInfo.State.CONNECTED == manager.getNetworkInfo(it).state
。但是,这并不能解决问题,因为NetworkInfo.html#getstate 也已弃用。【参考方案4】:
试试下面的代码:
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = connectivityManager.getAllNetworks();
NetworkInfo networkInfo;
Network network;
for (int i = 0; i < networks.length; i++)
network = networks[i];
networkInfo = connectivityManager.getNetworkInfo(network);
if ((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) && (networkInfo.getState().equals(NetworkInfo.State.CONNECTED)))
ConnectivityManager.setProcessDefaultNetwork(network);
break;
【讨论】:
感谢您的回答。但是,这里不推荐使用 setProcessDefaultNetwork() connectivityManager.getAllNetworks() 和 connectivityManager.getNetworkInfo(network) 需要 API 21【参考方案5】:试试这个
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
if (cm != null)
for (Network netinfo : networks)
NetworkInfo ni = cm.getNetworkInfo(netinfo);
if (ni.isConnected() && ni.isAvailable())
connected = true;
【讨论】:
该问题表明NetworkInfo
已折旧,因此这不会回答有关替代方案的问题。【参考方案6】:
试试这个。这是最简单的方法。
public static boolean isNetworkAvailable(Activity activity)
ConnectivityManager connectivity = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null)
return false;
else
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
return true;
return false;
【讨论】:
再一次,问题询问NetworkInfo
的替代方案是什么......显然没有人(无论如何在这里)阅读问题和/或可以提供答案。当一个人在寻找答案时会感到沮丧。以上是关于Android getAllNetworkInfo() 已弃用。啥是替代方案?的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )