Android 如何判断';移动网络数据&x27;是否启用或禁用(即使通过WiFi连接)?

Android 如何判断';移动网络数据&x27;是否启用或禁用(即使通过WiFi连接)?,android,networking,network-connection,Android,Networking,Network Connection,我有一个应用程序,我希望能够使用它从远程查询中获取连接状态报告 我想知道是否连接了WiFi,是否通过移动网络启用了数据访问 如果WiFi超出范围,我想知道我是否可以依赖移动网络 问题是,当我通过WiFi连接时,启用的数据总是返回为true,并且我只能在未通过WiFi连接时正确查询移动网络 我看到的所有答案都建议进行投票,看看当前的连接是什么,但我想知道,如果我需要,移动网络是否可用,即使我目前可能通过WiFi连接 是否有任何方法可以告诉移动网络数据是否已启用,而无需轮询以查看是否已连接 编辑 因

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

我想知道是否连接了WiFi,是否通过移动网络启用了数据访问

如果WiFi超出范围,我想知道我是否可以依赖移动网络

问题是,当我通过WiFi连接时,启用的数据总是返回为true,并且我只能在未通过WiFi连接时正确查询移动网络

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

是否有任何方法可以告诉移动网络数据是否已启用,而无需轮询以查看是否已连接

编辑

因此,当通过WiFi连接时,如果我转到“设置”并取消选择“数据启用”,然后在我的应用程序中执行以下操作:

 boolean mob_avail = 
 conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isAvailable();
mob_avail返回为“true”,但我已禁用移动网络数据,因此我希望它为“false”

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

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

更新

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

我在以下3种情况下输出返回的关于移动网络的信息

WiFi关闭-移动数据打开

WiFi开启-移动数据关闭

无线上网-移动数据上网

并得到以下结果:

关闭WiFi时:

移动[HSUPA],状态:已连接/已连接,原因:未知,额外: internet,漫游:false,故障转移:false,isAvailable:true, featureId:-1,用户默认值:false

打开/关闭WiFi时

NetworkInfo:type:mobile[HSUPA],状态:DISCONNECTED/DISCONNECTED, 原因:已禁用连接,额外:(无),漫游:false, 故障转移:false,isAvailable:true,featureId:-1,userDefault: 假的

无线上网/移动上网

网络信息:类型:移动[HSPA],状态:已断开/已断开, 原因:已禁用连接,额外:(无),漫游:false, 故障转移:false,isAvailable:true,featureId:-1,userDefault: 假的

所以,正如您所看到的,isAvailable每次都返回true,并且状态仅在WiFi生效时显示为断开连接

澄清


我正在查看我的手机当前是否通过移动网络连接。IAM试图确定用户是否启用/禁用了移动网络上的数据访问。他们可以通过进入“设置”->“无线和网络设置”->“移动网络设置”->“数据启用”来打开和关闭此功能。您必须使用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
我认为使用和断开连接应该有效:

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(姜饼)及更高版本。实际上,这段代码也适用于早期版本的Android;-)


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

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

boolean mobileDataAllowed = Settings.Secure.getInt(getContentResolver(), "mobile_data", 1) == 1;
根据API的不同,您需要检查Settings.Global而不是Settings.Secure,正如@user1444325所指出的那样

资料来源:
我已经升级了Allesio的答案。Settings.Secure的mobile_data int已从4.2.2移到Settings.Global。

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

已更新以检查SIM卡是否可用。谢谢你指出穆拉特

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;
    }
}

以下是解决此问题的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的功能非常好。但在我发现的少数设备中,即使数据被禁用,它也会返回true。 所以我找到了另一个解决方案,它是在Android API中

这种方法将非常有用

我用上面的函数更新了@snash的函数。当禁用蜂窝数据时,Lower函数返回false,否则返回true

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;
    }

根据android文档

使用电话管理器

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

tm.isDataEnabled()

根据android文档


以下是来自其他两个答案的简单解决方案:

        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 one设备上运行)

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

  • 重新启动手机时,此方法也将返回0,因为计算从0字节开始

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

有一个简单的API似乎正在工作

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

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

NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
                      activeNetwork.isConnectedOrConnecting();
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

tm.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;
        }
long data = TrafficStats.getMobileRxBytes();
if(data > 0){
    //Data is On
}
else{
    //Data is Off
}
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;
    }
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isDataEnabled();

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
    }
}