Запуск 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();
}


Другие вопросы по тегам