如何判断「流动网络资料」是否已启用或禁用(即使已连接 WiFi) ?

我有一个应用程序,我希望能够使用从远程查询获得连接状态报告。

我想知道是否连接了 WiFi,以及是否能通过移动网络进行数据访问。

如果无线网络超出范围,我想知道我是否可以依靠移动网络。

问题在于,当我使用 WiFi 连接时,启用的数据总是返回为真,而且只有在没有使用 WiFi 连接时,我才能正确地查询移动网络。

我看到的所有答案都建议进行投票,看看当前的连接是什么,但我想知道如果我需要移动网络,是否可用,即使我现在可能使用 WiFi 连接。

是否有任何办法告诉移动网络数据是否在没有轮询的情况下启用,以查看是否已连接?

剪辑

因此,当通过 WiFi 连接时,如果我去设置并取消选择“启用数据”,然后在我的应用程序中我这样做:

 boolean mob_avail =
conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isAvailable();

Mob _ avail 返回为“ true”,但是我已经禁用了 Mobile Network Data,所以我认为它应该是“ false”

如果我关闭 WiFi,就没有连接,因为我已经禁用了移动网络数据。

那么,当我使用 WiFi 连接时,如何检查移动网络数据是否已启用?

更新

我查看了 ss1271在评论中建议的 getAllNetworkInfo ()

我输出的信息返回有关移动网络在以下3个条件

无线上网-移动数据开启

无线上网-移动数据关闭

无线上网-流动数据开启

结果如下:

关闭 WiFi:

移动[ HSUPA ] ,状态: 连接/连接,原因: 未知,额外: 互联网,漫游: 假,故障转移: 假, Feature ureId: -1,userDefault: false

无线上网/手机关机

NetworkInfo: type: mobile [ HSUPA ] ,state: DISCONNECTED/DISCONNECTED, 原因: Connection 禁用,额外: (无) ,漫游: 假, 故障转移: false,isReceiable: true,Feature ureId: -1,userDefault: 假的

打开 WiFi/手机

NetworkInfo: type: mobile [ HSPA ] ,state: DISCONNECTED/DISCONNECTED, 原因: Connection 禁用,额外: (无) ,漫游: 假, 故障转移: false,isReceiable: true,Feature ureId: -1,userDefault: 假的

所以你可以看到,每一次 isOpable 都返回 true,并且状态只有在 WiFi 受到影响时才显示为“断开连接”。

澄清

我是 没有期待看到如果我的手机目前连接的移动网络。我 上午试图确定用户是否已经启用/禁用了移动网络上的数据访问。他们可以通过设置-> 无线和网络设置-> 移动网络设置-> 启用数据来打开和关闭

92634 次浏览

您必须使用 ConnectivityManager,并且可以找到 NetworkInfo 的详细信息 给你

你可以试试这样的方法:

ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);


//mobile
State mobile = conMan.getNetworkInfo(0).getState();


//wifi
State wifi = conMan.getNetworkInfo(1).getState();




if (mobile == NetworkInfo.State.CONNECTED || mobile == NetworkInfo.State.CONNECTING)
{
//mobile
}
else if (wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING)
{
//wifi
}

如果你感兴趣,如果你真的连接,使用

NetworkInfo.State.CONNECTED

只是,而不是

NetworkInfo.State.CONNECTED || NetworkInfo.State.CONNECTING

我认为使用 NetworkInfo 类和 isConnected 应该可行:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);


return info != NULL || info.isConnected();

并且检查移动数据也许是连接的。在测试之前我无法确定。我明天才能做。

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);


if(tm .getDataState() == tm .DATA_CONNECTED)
return true;

下面的代码会告诉你“移动数据”是否已经启用,不管现在是否有一个活动的移动数据连接,或者 wifi 是否已经启用。 这段代码只适用于 Android 2.3(Gingerbread)及更高版本。实际上这个代码在早期版本的 Android 上也可以工作; -)

    boolean mobileDataEnabled = false; // Assume disabled
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
Class cmClass = Class.forName(cm.getClass().getName());
Method method = cmClass.getDeclaredMethod("getMobileDataEnabled");
method.setAccessible(true); // Make the method callable
// get the setting for "mobile data"
mobileDataEnabled = (Boolean)method.invoke(cm);
} catch (Exception e) {
// Some problem accessible private API
// TODO do whatever error handling you want here
}

注意: 您需要有权限 android.permission.ACCESS_NETWORK_STATE才能使用此代码。

一种方法是检查用户是否在设置中激活了移动数据,如果 wifi 关闭,这些数据很可能会被使用。 这个工作(测试) ,并且它不使用反射,尽管它在 API 中使用了一个隐藏值:

boolean mobileDataAllowed = Settings.Secure.getInt(getContentResolver(), "mobile_data", 1) == 1;

根据 API 的不同,您需要检查 Settings. Global 而不是 Settings. Secure,正如@user1444325所指出的那样。

来源: 调用 Android API 来确定用户设置“ Data Enable”

To identify which SIM or slot is making data connection active in mobile, we need to register action android:name="android.net.conn.CONNECTIVITY_CHANGE"  with permission
uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" &    uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"


public void onReceive(Context context, Intent intent)
if (android.net.conn.CONNECTIVITY_CHANGE.equalsIgnoreCase(intent
.getAction())) {


IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service =  IConnectivityManager.Stub.asInterface(b);
NetworkState[] states = service.getAllNetworkState();


for (NetworkState state : states) {


if (state.networkInfo.getType() == ConnectivityManager.TYPE_MOBILE
&& state.networkInfo.isConnected()) {


TelephonyManager mTelephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
int slotList =  { 0, 1 };
int[] subId = SubscriptionManager.getSubId(slotList[0]);
if(mTelephonyManager.getDataEnabled(subId[0])) {
// this means data connection is active for SIM1 similary you
//can chekc for SIM2 by slotList[1]
.................
}
}


}

我已经升级了 Allesio 的应答。设置。安全的 mobile _ data int 已经从4.2.2移动到 Settings. Global。

如果您想知道移动网络是否已启用,即使启用并连接了 wifi,也请尝试此代码。

更新检查是否有 SIM 卡。谢谢指出 Murat。

boolean mobileYN = false;


TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
{
mobileYN = Settings.Global.getInt(context.getContentResolver(), "mobile_data", 1) == 1;
}
else{
mobileYN = Settings.Secure.getInt(context.getContentResolver(), "mobile_data", 1) == 1;
}
}
    ConnectivityManager cm = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
String networkType = "";
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
networkType = "WIFI";
}
else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {


networkType = "mobile";
}

下面是 Xamarin 对这个问题的解决方案:

    public static bool IsMobileDataEnabled()
{
bool result = false;


try
{
Context context = //get your context here or pass it as a param


if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1)
{
//Settings comes from the namespace Android.Provider
result = Settings.Global.GetInt(context.ContentResolver, "mobile_data", 1) == 1;
}
else
{
result = Settings.Secure.GetInt(context.ContentResolver, "mobile_data", 1) == 1;
}
}
catch (Exception ex)
{
//handle exception
}


return result;
}

附注: 请确保您拥有此代码的所有权限。

@ sNash 的函数工作得很好,但是在少数设备中,我发现即使数据被禁用,它也会返回真值。 所以我找到了一个替代的解决方案,在 Android API 中。

电话经理的 getDataState () 方法将非常有用。

我用上面的函数更新了@snash 的函数。

private boolean checkMobileDataIsEnabled(Context context){
boolean mobileYN = false;


TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
TelephonyManager tel = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//          if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
//          {
//              mobileYN = Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1;
//          }
//          else{
//              mobileYN = Settings.Secure.getInt(context.getContentResolver(), "mobile_data", 0) == 1;
//          }
int dataState = tel.getDataState();
Log.v(TAG,"tel.getDataState() : "+ dataState);
if(dataState != TelephonyManager.DATA_DISCONNECTED){
mobileYN = true;
}


}


return mobileYN;
}

根据机器人文档 https://developer.android.com/training/monitoring-device-state/connectivity-monitoring#java

ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);


NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();

使用 TelephonyManager

TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);


tm.isDataEnabled()

根据机器人文档

Https://developer.android.com/reference/android/telephony/telephonymanager.html#isdataenabled

下面是另外两个答案中的一个简单解决方案:

        TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return tm.isDataEnabled();


} else {
return tm.getSimState() == TelephonyManager.SIM_STATE_READY && tm.getDataState() != TelephonyManager.DATA_DISCONNECTED;
}

有一个检查数据连接是否打开的变通方法。但我不确定它是否适用于所有设备。你得检查一下。(它可以在 Android 的一款设备上运行)

long data = TrafficStats.getMobileRxBytes();
if(data > 0){
//Data is On
}
else{
//Data is Off
}

如果您不知道此方法,它将返回自设备启动以来通过移动网络接收的字节总数。当您关闭移动数据连接时,它将返回 Zero (0)。当您打开时,它将再次返回字节总数。但是您需要意识到,在使用此变通方法时可能会出现一个问题。

  • 重新启动电话时,此方法也将返回0,因为计算从0字节开始。
private boolean haveMobileNetworkConnection() {
boolean haveConnectedMobile = false;


ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();


for (NetworkInfo ni : netInfo) {


if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedMobile;
}

注意: 您需要具有 android.permission. ACCESS _ NETWORK _ STATE 权限才能使用此代码

有一个简单的 API 似乎在起作用

TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isDataEnabled();


由于 ConnectivityManager.allNetworkInfo已被废弃,Android 建议使用 getNetworkCapabilities

fun isOnMobileData(): Boolean {
val connectivityManager =
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val all = connectivityManager.allNetworks


return all.any {
val capabilities = connectivityManager.getNetworkCapabilities(it)
capabilities?.hasTransport(TRANSPORT_CELLULAR) == true
}
}