【问题标题】:Running dpm with Runtime.exec(...)使用 Runtime.exec(...) 运行 dpm
【发布时间】:2015-08-20 21:35:05
【问题描述】:

This answer 建议 Android 应用可以像这样运行dpm

Runtime.getRuntime().exec("dpm set-device-owner com.test.my_device_owner_app");

这在运行 5.1.1 的 Nexus 4 上静默失败。 shell 返回错误代码 0(成功)并且没有控制台输出。尽管取得了明显的成功,但我的应用程序并没有成为设备所有者。设备刚恢复出厂设置,未配置用户帐户。

作为控制,我尝试运行垃圾命令而不是 dpm。它按预期失败。

这有用吗?是故意削弱的吗?

【问题讨论】:

  • 在您的链接答案中 - cmets 中列出了一些条件 - 它们是否适用于您的设置?
  • @MorrisonChang 我已经完成了所有这些事情,否则我无法安装尝试运行此命令的应用程序。
  • 我有同样的问题,虽然从命令行使用“adb shell ...”它工作正常,但由于某种原因使用 Runtime.getRuntime().exec() 不起作用跨度>

标签: android kiosk-mode android-5.1.1-lollipop


【解决方案1】:

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

【讨论】:

  • 当我从命令行调用“adb shell dpm set-device-owner BLAH”时,一切正常(我的应用程序成为设备所有者 - 我没有收到安全异常,因为我的应用程序是系统应用程序),但是当我从我的程序中调用“Runtime.getRuntime().exec("dpm set-device-owner BLAH");”我得到一个静默失败(不是 SecurityException,尽管我希望得到一些反馈)。知道为什么吗?
  • @user3294126 我猜谷歌认为这是一种安全风险。
【解决方案2】:

作为一些额外信息,我能够捕获输出(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();
}


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    相关资源
    最近更新 更多