【问题标题】:Work around for Device admin api does not own profile解决设备管理员 api 不拥有配置文件的问题
【发布时间】:2018-01-14 20:27:15
【问题描述】:

我正在通过设备管理 api 工作,并且在调用 DevicePolicyManager 上的 setPermissionGrantState 函数时,我得到了

Unable to start receiver com.xx.admin.receivers.AdminReceiver: java.lang.SecurityException: Admin ComponentInfo{com.xx/com.xx.admin.receivers.AdminReceiver} does not own the profile.

我了解某些功能只能由设备/配置文件所有者运行。此外,NFC provisioning and dpm command 是通过它的方式。但这几乎不是我分发应用程序时想要进行的方式。有没有什么方法可以通过请求用户允许我的应用程序拥有具有/不具有 root 的个人资料所有权来自动执行此授权。

这是我的接收器

class AdminReceiver : DeviceAdminReceiver() {

    var manager: DevicePolicyManager? = null
    override fun onEnabled(context: Context?, intent: Intent?) {
        super.onEnabled(context, intent)
        manager = getManager(context)
        manager!!.setPermissionGrantState(getComponentName(context!!)
                , "com.abc.app"
                , Manifest.permission.WRITE_EXTERNAL_STORAGE
                , DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED)


    }

    fun getComponentName(context: Context): ComponentName {
        return ComponentName(context.applicationContext, AdminReceiver::class.java)
    }

}

【问题讨论】:

    标签: android kotlin device-admin


    【解决方案1】:

    NFC 配置仅在设置设备所有者时需要。

    我会说 dpm 命令通常也用于测试/设置设备所有者(这就是我使用它的目的),但您也可以设置配置文件所有者。

    您可以使用以下代码以编程方式设置托管配置文件。您要管理的应用程序必须安装在此配置文件中。此代码基于 android-AppRestrictionEnforcer。

    /**
     * Initiates the managed profile provisioning. If we already have a managed profile set up on
     * this device, we will get an error dialog in the following provisioning phase.
     */
    private void provisionManagedProfile() {
        Activity activity = getActivity();
        if (null == activity) {
            return;
        }
        Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
        if (Build.VERSION.SDK_INT >= 24) {
            intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
                    CustomDeviceAdminReceiver.getComponentName(activity));
        } else {
            //noinspection deprecation
            intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
                    activity.getApplicationContext().getPackageName());
            intent.putExtra(EXTRA_DEVICE_ADMIN, CustomDeviceAdminReceiver.getComponentName(activity));
        }
        if (intent.resolveActivity(activity.getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_PROVISION_MANAGED_PROFILE);
            activity.finish();
        } else {
            Toast.makeText(activity, "Device provisioning is not enabled. Stopping.",
                    Toast.LENGTH_SHORT).show();
        }
    }
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {
            if (resultCode == Activity.RESULT_OK) {
                Toast.makeText(getActivity(), "Provisioning done.", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getActivity(), "Provisioning failed.", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
    

    【讨论】:

    • 这不起作用...我请求了设备管理员,然后请求了此托管配置文件。没用。
    【解决方案2】:

    需要在设置设备或工作资料时设置设备所有者或个人资料所有者应用。与设备管理员不同,它在设置后无法更改,除非恢复出厂设置(或删除工作配置文件)。要将您的应用配置为设备所有者或个人资料所有者,请参阅Android EMM Developers documentation

    在您自己的应用程序中实现此功能相当复杂,您应该考虑使用Android Management API,它提供与更简单的云 API 相同的功能。例如setPermissionGrantState 的等价物是PermissionGrant

    【讨论】:

    • 嘿,谢谢,虽然它抽象了 API,但它没有提供解决方法,因为设备仍然需要恢复出厂设置,如果我不拥有设备并且如果我需要,这将不可行在 Google Play 上分发
    • 确实,如果没有恢复出厂设置,您无法在整个设备上获得设备所有者权限,这是一项安全功能,因为设备所有者可以完全控制设备。但是,您可以在设备中创建工作配置文件,只使用您想要控制的应用程序,您将拥有配置文件所有者权限。
    猜你喜欢
    • 2015-06-03
    • 2019-11-07
    • 2019-08-04
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多