Как определить, включена ли функция "Данные мобильной сети" (даже если она подключена через WiFi)?
У меня есть приложение, которое я хочу использовать для получения отчета о состоянии соединения из удаленного запроса.
Я хочу знать, подключен ли WiFi и включен ли доступ к данным через мобильную сеть.
Если WiFi выходит за пределы диапазона, я хочу знать, могу ли я положиться на мобильную сеть.
Проблема в том, что включенные данные всегда возвращаются как истинные, когда я подключен по WiFi, и я могу правильно запрашивать мобильную сеть, только если не подключен по WiFi.
все ответы, которые я видел, предполагают опрос, чтобы увидеть текущее соединение, но я хочу знать, доступна ли мобильная сеть, если она мне понадобится, даже если в настоящее время я могу быть подключен через WiFi.
Можно ли в любом случае сказать, включены ли данные мобильной сети без опроса, чтобы узнать, подключен ли?
РЕДАКТИРОВАТЬ
Поэтому при подключении по Wi-Fi. Если перейти к настройкам и отменить выбор "Данные включены", а затем в своем приложении я делаю это:
boolean mob_avail =
conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isAvailable();
mob_avail возвращается как 'true', но я отключил данные мобильной сети, поэтому я ожидал, что он будет 'false'
Если я отключаю Wi-Fi, соединение (правильно) отсутствует, так как я отключил данные мобильной сети.
так как я могу проверить, включены ли данные мобильной сети, когда я подключен по WiFi?
ОБНОВИТЬ
Я взглянул на getAllNetworkInfo(), как это предлагается в комментариях ss1271.
Я вывел возвращенную информацию о мобильной сети при следующих 3 условиях
WiFi Off - мобильные данные включены
WiFi включен - мобильные данные выключены
WiFi On - мобильные данные на
и получил следующие результаты:
С выключенным WiFi:
мобильный [HSUPA], состояние: ПОДКЛЮЧЕНО / ПОДКЛЮЧЕНО, причина: неизвестна, дополнительно: интернет, роуминг: ложь, аварийное переключение: ложь, isAvailable: истина, featureId: -1, userDefault: ложь
С включенным WiFi / мобильным телефоном
NetworkInfo: тип: mobile[HSUPA], состояние: DISCONNECTED/DISCONNECTED, причина: connectionDisabled, extra: (нет), роуминг: false, отработка отказа: false, isAvailable: true, featureId: -1, userDefault: false
С включенным WiFi / Mobile
NetworkInfo: тип: mobile[HSPA], состояние: DISCONNECTED/DISCONNECTED, причина: connectionDisabled, extra: (нет), роуминг: false, отработка отказа: false, isAvailable: true, featureId: -1, userDefault: false
Итак, как вы можете видеть, isAvailable каждый раз возвращал true, а состояние показывалось только как Disconnected, когда WiFi был включен.
ПОЯСНЕНИЯ
Я не проверяю, подключен ли мой телефон к сети мобильной связи. Я пытаюсь установить, включил ли пользователь / отключил доступ к данным через мобильную сеть. Они могут включить и выключить это, зайдя в Настройки -> Настройки беспроводной сети и сети -> Настройки мобильной сети -> Данные включены
11 ответов
Следующий код сообщит вам, включены ли "мобильные данные" или нет, независимо от того, активно ли в данный момент мобильное соединение для передачи данных или включен или нет Wi-Fi. Этот код работает только на 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
чтобы иметь возможность использовать этот код.
Я обновил ответ Аллезио. Параметр mobile_data int для параметра Settings.Secure перемещен в файл Settings.Global с версии 4.2.2.
Попробуйте этот код, если вы хотите знать, включена ли мобильная сеть, даже когда Wi-Fi включен и подключен.
Обновлен, чтобы проверить, доступна ли 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;
}
}
Один из способов - проверить, активированы ли у пользователя мобильные данные в настройках, которые, скорее всего, будут использоваться в случае отключения Wi-Fi. Это работает (проверено) и не использует отражения, хотя и использует скрытое значение в API:
boolean mobileDataAllowed = Settings.Secure.getInt(getContentResolver(), "mobile_data", 1) == 1;
В зависимости от API, вам нужно проверить Settings.Global вместо Settings.Secure, как указано @user1444325.
Источник: вызов API Android для определения настроек пользователя "Данные включены"
Функция @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;
}
Поскольку 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
}
}
Использовать TelephonyManager
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
tm.isDataEnabled()
Согласно документации Android
https://developer.android.com/reference/android/telephony/TelephonyManager.html
Вы можете попробовать что-то вроде этого:
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
Вот простое решение из двух других ответов:
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;
}
Я думаю, что использование класса 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;
Вот 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: убедитесь, что у вас есть все разрешения для этого кода.
Есть простой API, который вроде бы работает
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isDataEnabled();
Что ж, есть обходной путь, чтобы проверить, включено ли соединение для передачи данных. Но я не уверен, будет ли он работать на каждом устройстве. Вы должны это проверить. (Работало на устройстве Android One)
long data = TrafficStats.getMobileRxBytes();
if(data > 0){
//Data is On
}
else{
//Data is Off
}
Если вы не знаете об этом методе, он возвращает общее количество байтов, полученных через мобильную сеть с момента загрузки устройства. При отключении мобильной передачи данных возвращается ноль (0). При включении он снова вернет общее количество байтов. Но вы должны знать, что при использовании этого обходного пути может возникнуть проблема.
- Этот метод также вернет 0 при перезагрузке телефона, поскольку расчет начинается с 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";
}
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, чтобы использовать этот код.
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]
.................
}
}
}
Согласно документации для Android https://developer.android.com/training/monitoring-device-state/connectivity-monitoring
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
Вы должны использовать ConnectivityManager, а подробности NetworkInfo можно найти здесь