使用 Runtime.getRuntime 在 Android 上运行 shell 命令

2024-01-14

我正在开发一个设备管理应用程序(已由制造商签名)。我使用它来安装其他应用程序,使用以下适用于 android 9 的 adb shell 命令:-

cat /sdcard/Download/myfolder/newapp.apk | pm install -S 1528293

我只是这样传递它:-

String command = "cat /sdcard/Download/myfolder/newapp.apk | pm install -S 1528293"
Runtime.getRuntime().exec(command);

但我收到错误“猫未知选项 S”。

当我从 adb shell 运行相同的命令时,它工作得非常好。 不知道我做错了什么,需要一些帮助。

编辑1:- 我尝试运行如下命令:-

String[] commandInstall = {
                "/system/bin/sh",
                "-c",
                "cat /sdcard/Download/myfolder/newapp.apk | pm install -S 1528293"
        };
Process process = Runtime.getRuntime().exec(commandInstall);

但现在我收到错误:-

ava.lang.SecurityException: Reverse mode only supported from shell
    at com.android.server.pm.PackageInstallerSession.doWriteInternal(PackageInstallerSession.java:679)
    at com.android.server.pm.PackageInstallerSession.write(PackageInstallerSession.java:612)
    at android.content.pm.PackageInstaller$Session.write(PackageInstaller.java:852)
    at com.android.server.pm.PackageManagerShellCommand.doWriteSplit(PackageManagerShellCommand.java:2447)
    at com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:915)
    at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:158)
    at android.os.ShellCommand.exec(ShellCommand.java:103)
    at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21330)
    at android.os.Binder.shellCommand(Binder.java:634)
    at android.os.Binder.onTransact(Binder.java:532)
    at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2821)
    at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3856)
    at android.os.Binder.execTransact(Binder.java:731)

编辑2:- 在android 9之前,我可以执行以下操作来安装应用程序:-

Runtime.getRuntime().exec("pm install -r app.apk");

查看PackageInstallerSession的源代码我发现它被更改为:-

switch (Binder.getCallingUid()) {
    case android.os.Process.SHELL_UID:
    case android.os.Process.ROOT_UID:
        break;
    default:
        throw new SecurityException("Reverse mode only supported from shell");
    }

Source https://github.com/aosp-mirror/platform_frameworks_base/blame/e80b45506501815061b079dcb10bf87443bd385d/services/core/java/com/android/server/pm/PackageInstallerSession.java因此,即使它是系统应用程序,用于安装的 shell 命令也可能不起作用。从提交消息来看,这样做是为了让 PackageInstaller 完成这项工作。

然而,似乎这在某个时候再次被更改,但可能不包含在 android 9 中:-

    switch (Binder.getCallingUid()) {
                case android.os.Process.SHELL_UID:
                case android.os.Process.ROOT_UID:
                case android.os.Process.SYSTEM_UID:
                    break;
                default:
                    throw new SecurityException(
                            "Reverse mode only supported from shell or system");
            }

Source https://github.com/aosp-mirror/platform_frameworks_base/blob/master/services/core/java/com/android/server/pm/PackageInstallerSession.java

因此,如果应用程序是系统应用程序,那么最好的方法是使用 PackageInstaller。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Runtime.getRuntime 在 Android 上运行 shell 命令 的相关文章