首页 文章

如何判断'Mobile Network Data'是启用还是禁用(即使通过WiFi连接)?

提问于
浏览
59

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

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

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

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

我看到的所有答案建议轮询以查看当前的连接是什么,但我想知道我是否需要移动网络,即使我目前可能通过WiFi连接 .

无论如何判断移动网络数据是否在没有轮询的情况下启用以查看是否已连接?

EDIT

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

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

mob_avail返回为'true',但我已禁用移动网络数据,所以我希望它是'false'

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

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

UPDATE

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

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

WiFi关闭 - 移动数据

WiFi On - 移动数据关闭

WiFi On - 移动数据

并得到以下结果:

WiFi关闭:移动[HSUPA],状态:已连接/已连接,原因:未知,额外:互联网,漫游:错误,故障转移:false,isAvailable:true,featureId:-1,userDefault:false使用WiFi On / Mobile OFF NetworkInfo:type:mobile [HSUPA],state:DISCONNECTED / DISCONNECTED,reason:connectionDisabled,extra:(none),漫游:false,failover:false,isAvailable:true,featureId:-1,userDefault:false使用WiFi On / Mobile在NetworkInfo上:type:mobile [HSPA],state:DISCONNECTED / DISCONNECTED,reason:connectionDisabled,extra:(none),漫游:false,failover:false,isAvailable:true,featureId:-1,userDefault:false

因此,您可以看到isAvailable每次都返回true,并且当WiFi处于影响状态时,状态仅显示为Disconnected .

CLARIFICATION

我是 NOT 想看看我的手机目前是否通过移动网络连接 . 我试图确定用户是否通过移动网络启用/禁用了数据访问 . 他们可以通过转到设置 - >无线和网络设置 - >移动网络设置 - >数据启用来打开和关闭此功能

11 回答

  • 20

    以下代码将告诉您"mobile data"是否已启用,无论此时是否有活动数据连接处于活动状态,或者无论是否启用了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 才能使用此代码 .

  • 2

    我've upgraded Allesio'的回答 . 自4.2.2以来,Settings.Secure的mobile_data int已移至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;
        }
    }
    
  • 0

    一种方法是检查用户是否在设置中激活了移动数据,如果wifi关闭,则很可能会使用该数据 . 这可以工作(测试),虽然它在API中使用隐藏值,但它不使用反射:

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

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

    资料来源:Android API call to determine user setting "Data Enabled"

  • 28

    你可以试试这样的东西:

    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
    
  • 0

    @ sNash的功能很棒 . 但在少数设备中,我发现即使数据被禁用,它也会返回true . 所以我找到了一个Android API的备用解决方案 .

    getDataState()的方法TelephonyManager将非常有用 .

    我使用上面的函数更新了@ snash的函数 . 当蜂窝数据被禁用时,下面的函数返回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;
        }
    
  • 2

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

  • 0

    我认为使用NetworkInfo class和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;
    
  • 0
    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]
                   .................
              }
    }
    
    }
    
  • 0
    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";
        }
    
  • 0

    以下是针对此问题的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;
        }
    

    PS:确保您拥有此代码的所有权限 .

  • 107

    根据android文档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();
    

相关问题