This answer suggests that an Android app can run dpm
like this:
Runtime.getRuntime().exec("dpm set-device-owner com.test.my_device_owner_app");
This fails silently on my Nexus 4 running 5.1.1. The shell returns an error code of 0 (success) and there is no console output. Despite the apparent success, my app does not become the device owner. The device is fresh from a factory reset, with no user account configured.
As a control, I tried running a garbage command instead of dpm
. It fails as expected.
Did this ever work? Was it intentionally nerfed?
dpm
incorrectly exits with a status code of 0 when you get the command syntax wrong. The correct syntax is dpm set-device-owner package/.ComponentName
. When you get the syntax right, exec(...)
throws a SecurityException
:
java.lang.SecurityException: Neither user 10086 nor current process has android.permission.MANAGE_DEVICE_ADMINS.
at android.os.Parcel.readException(Parcel.java:1546)
at android.os.Parcel.readException(Parcel.java:1499)
at android.app.admin.IDevicePolicyManager$Stub$Proxy.setActiveAdmin(IDevicePolicyManager.java:2993)
at com.android.commands.dpm.Dpm.runSetDeviceOwner(Dpm.java:110)
at com.android.commands.dpm.Dpm.onRun(Dpm.java:82)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
at com.android.commands.dpm.Dpm.main(Dpm.java:38)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:249)
Adding this permission to the manifest does not help, so maybe it's a system-only permission.
It's already a pain in the butt to deploy a kiosk mode app on a device without NFC, since you have to enable developer mode and install the app via adb
. I guess the provisioner will just have to run dpm
manually.