Запуск dpm с помощью Runtime.exec(...)
Этот ответ предполагает, что приложение для Android может работать dpm
как это:
Runtime.getRuntime().exec("dpm set-device-owner com.test.my_device_owner_app");
Это молча терпит неудачу на моем Nexus 4, работающем 5.1.1. Оболочка возвращает код ошибки 0 (успех), и консоль не выводится. Несмотря на очевидный успех, мое приложение не становится владельцем устройства. Устройство только что восстановлено с заводского сброса, учетная запись пользователя не настроена.
В качестве контроля я попытался запустить команду мусора вместо dpm
, Это терпит неудачу как ожидалось.
Это когда-нибудь работало? Было ли это намеренно нерф?
2 ответа
dpm
некорректно завершается с кодом состояния 0, если вы неправильно указали синтаксис команды. Правильный синтаксис dpm set-device-owner package/.ComponentName
, Когда вы получите правильный синтаксис, exec(...)
бросает 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)
Добавление этого разрешения в манифест не помогает, поэтому, возможно, это разрешение только для системы.
Это уже боль в развертывании приложения в режиме киоска на устройстве без NFC, так как вы должны включить режим разработчика и установить приложение через adb
, Я думаю, что провайдер просто должен бежать dpm
вручную.
В качестве дополнительной информации я смог зафиксировать и записать вывод (stdout и stderr) в logcat.
DevicePolicyManager dpm = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
Runtime rt = Runtime.getRuntime();
Process proc = null;
try {
proc = rt.exec("dpm set-device-owner com.myapp/.DeviceOwnerReceiver");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}