【问题标题】:Device Owner Admin / DevicePolicyManager, Possible to turn on Mobile Data & Data Roaming automatically on Android?设备所有者管理员 / DevicePolicyManager,可以在 Android 上自动打开移动数据和数据漫游吗?
【发布时间】:2020-05-25 16:57:13
【问题描述】:

所以我正在开发一个在特定 Android 设备上作为设备所有者工作的应用程序。此应用程序在 Play 商店中不可用,但通过 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);
                    }
                }

            }
        }

【问题讨论】:

    标签: android device-admin device-owner android-device-owner


    【解决方案1】:

    不幸的是,设备所有者无法访问移动数据状态(您说得对,设备所有者应用的奇怪限制!)。

    但是,您仍然可以获取移动数据状态并在状态错误时强制用户打开或关闭它。这是代码示例(感谢Test if background data and packet data is enabled or not)。

    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 上测试)。

    因此,您运行一个后台服务,该服务每隔几秒执行一次此检查,并要求用户在状态栏中打开/关闭移动数据。

    你可以通过克隆这个open source Android MDM(这是我的项目)来查看它是如何完成的。方法在这里:Utils.isMobileDataEnabled(Context context)

    【讨论】:

    • 谢谢,我正在使用代码,它运行良好。您似乎对设备所有者应用程序非常有经验,我仍在弄清楚设备所有者拥有什么样的权力。我仍然有问题,设备的键盘错误(英国而不是德语)所以我正在寻找一种方法让我的应用程序安装新键盘或三星键盘的新语言,因为我们使用的是三星设备.
    • 我怀疑设备所有者可以安装新的键盘或语言。基本上,设备所有者可以做什么,记录在这里:developer.android.com/reference/android/app/admin/… 据我所知,键盘和语言由 /system/build.prop 的参数管理:persist.sys.language,persist.sys.region,ro .product.locale.language,ro.product.locale.country。但您必须能够创建自定义 ROM(或拥有 root 权限)才能更改这些参数。
    猜你喜欢
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 2017-10-16
    • 2012-05-21
    • 2016-03-09
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多