Администратор владельца устройства / DevicePolicyManager, можно ли автоматически включить мобильные данные и роуминг данных на Android?
Итак, я разрабатываю приложение, которое работает как владелец устройства на конкретном устройстве Android. Это приложение недоступно в магазине воспроизведения, но передается с приложением подготовки с другого устройства через NFC. Поскольку эти устройства будут очень специфичными для определенных задач (сканирование тегов NFC), я хочу включить и отключить несколько вещей с самого начала.
Хочу отключить звук:
devicePolicyManager.setMasterVolumeMuted(adminComponentName, true);
Но это, похоже, совсем не работает, но и не исключение.
Но что я действительно хочу сделать, так это включить мобильные данные и роуминг, SIM-карты, которые мы используем, поддерживают это.
devicePolicyManager.setSecureSetting(adminComponentName, Settings.Global.DATA_ROAMING, String.valueOf(1));
devicePolicyManager.setSecureSetting(adminComponentName,"mobile_data",String.valueOf(1));
Но, к сожалению, эти две строки кода вызывают исключение безопасности:
java.lang.SecurityException: Permission denial: Device owners cannot update mobile_data
Интересно, что вставка APN работает (позже в коде). Есть ли шанс включить мобильные данные и роуминг данных в качестве администратора / владельца устройства? Я имею в виду, что в этом вся цель быть администратором устройства, верно?
Вот полный код для справки: (части, вызывающие сбой приложения, закомментированы)
public static void enableRestrictedAppsAndSettings(Activity activity) {
ComponentName adminComponentName = DeviceAdminReceiver.getComponentName(activity);
DevicePolicyManager devicePolicyManager = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// disable keyguard and sound
devicePolicyManager.setKeyguardDisabled(adminComponentName, true);
devicePolicyManager.setMasterVolumeMuted(adminComponentName, true);
devicePolicyManager.setSecureSetting(adminComponentName, Settings.Secure.LOCATION_MODE, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
//devicePolicyManager.setSecureSetting(adminComponentName, Settings.Global.DATA_ROAMING, String.valueOf(1));
//devicePolicyManager.setSecureSetting(adminComponentName,"mobile_data",String.valueOf(1));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (devicePolicyManager.isDeviceOwnerApp(activity.getApplicationContext().getPackageName())) {
devicePolicyManager.enableSystemApp(adminComponentName,"com.sec.android.app.camera");
devicePolicyManager.clearUserRestriction(adminComponentName, UserManager.DISALLOW_DATA_ROAMING);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
L.debug("KIOSK", "APN");
ApnSetting apn;
TelephonyManager manager = (TelephonyManager)activity.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getSimState() == TelephonyManager.SIM_STATE_READY) {
String mcc = manager.getSimOperator().substring(0, 3);
String mnc = manager.getSimOperator().substring(3);
L.debug("KIOSK " + mcc + " "+mnc);
apn = new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
.setApnName("em")
.setEntryName("em")
.setOperatorNumeric(mcc + mnc) // this is a must its consists from Telephony.Carriers.MCC + Telephony.Carriers.MNC, In my case, I had to pad the MNC with a leading zero
.setProtocol(ApnSetting.PROTOCOL_IPV4V6) // this is a must
.setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) // this is a must
.setCarrierEnabled(true)
.build();
devicePolicyManager.removeOverrideApn(adminComponentName,0);
devicePolicyManager.addOverrideApn(adminComponentName, apn);
devicePolicyManager.setOverrideApnsEnabled(adminComponentName, true);
}
}
}
}
1 ответ
К сожалению, владелец устройства не имеет доступа к статусу мобильных данных (вы правы, странное ограничение для приложения владельца устройства!).
Однако вы все равно можете получить статус мобильных данных и заставить пользователя включить или выключить его, если статус неправильный. Вот примеры кода (спасибо Test, включены ли фоновые данные и пакетные данные).
public static boolean isMobileDataEnabled(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
Class clazz = Class.forName(cm.getClass().getName());
Method method = clazz.getDeclaredMethod("getMobileDataEnabled");
method.setAccessible(true); // Make the method callable
// get the setting for "mobile data"
return (Boolean) method.invoke(cm);
} catch (Exception e) {
// Let it will be true by default
return true;
}
}
Этот код работает на Android 5-9 (еще не тестировался на Android 10).
Таким образом, вы запускаете фоновую службу, которая выполняет эту проверку один раз в несколько секунд и требует, чтобы пользователь включил / выключил мобильные данные в строке состояния.
Вы можете увидеть, как это делается, клонировав этот Android MDM с открытым исходным кодом (это мой проект). Метод находится здесь: Utils.isMobileDataEnabled(контекстный контекст).