Администратор владельца устройства / DevicePolicyManager, возможно ли автоматическое включение мобильных данных и роуминга данных на Android? - PullRequest
0 голосов
/ 25 мая 2020

Итак, я разрабатываю приложение, которое работает как владелец устройства на определенном c Android устройстве. Это приложение недоступно в магазине воспроизведения, но передается с приложением подготовки с другого устройства через NF C. Поскольку эти устройства будут очень специфичными c для определенных задач (сканирование тегов NF C), я хочу включить и отключить несколько вещей с самого начала.

Я хочу отключить звук:

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 работает (позже в коде) Любая возможность включить мобильную передачу данных и роуминг данных в качестве администратора / владельца устройства? Я имею в виду, что в этом вся цель быть администратором устройства, верно?

Вот полный код для справки: (части, которые заставляют приложение sh закомментированы)

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 Ответ

1 голос
/ 25 мая 2020

К сожалению, владелец устройства не имеет доступа к статусу мобильных данных (вы правы, странное ограничение для приложения владельца устройства!).

Однако вы все равно можете получить статус мобильных данных и заставить пользователя чтобы включить или выключить его, если статус неправильный. Вот примеры кода (спасибо 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 (контекст контекста) .

...