运行 dpm 与 Runtime.exec(...)
Running dpm with Runtime.exec(...)
This answer 建议 Android 应用可以 运行 dpm
像这样:
Runtime.getRuntime().exec("dpm set-device-owner com.test.my_device_owner_app");
这在我的 Nexus 4 运行ning 5.1.1 上静默失败。 shell returns 错误代码 0(成功)并且没有控制台输出。尽管取得了明显的成功,但我的应用程序并未成为设备所有者。设备刚刚恢复出厂设置,未配置用户帐户。
作为对照,我尝试 运行ning 垃圾命令而不是 dpm
。它按预期失败了。
这有用吗?是故意削弱的吗?
当您的命令语法错误时,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 的设备上部署 kiosk 模式应用程序已经很麻烦了,因为您必须启用开发人员模式并通过 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();
}
This answer 建议 Android 应用可以 运行 dpm
像这样:
Runtime.getRuntime().exec("dpm set-device-owner com.test.my_device_owner_app");
这在我的 Nexus 4 运行ning 5.1.1 上静默失败。 shell returns 错误代码 0(成功)并且没有控制台输出。尽管取得了明显的成功,但我的应用程序并未成为设备所有者。设备刚刚恢复出厂设置,未配置用户帐户。
作为对照,我尝试 运行ning 垃圾命令而不是 dpm
。它按预期失败了。
这有用吗?是故意削弱的吗?
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 的设备上部署 kiosk 模式应用程序已经很麻烦了,因为您必须启用开发人员模式并通过 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();
}