web-dev-qa-db-ja.com

Android Runtime.getRuntimeを使用してシェルコマンドを実行する

私はデバイス管理アプリに取り組んでいます(製造元によって署名されています)。 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);

しかし、「cat unknown option 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");
8
noname

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");
    }

ソース したがって、システムアプリであっても、インストール用のシェルコマンドが機能しない可能性があります。コミットメッセージから、これは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");
            }

ソース

そのため、アプリがシステムアプリの場合、最善の方法はPackageInstallerを使用することです。

4
noname

packageInstallerSession.Javaから:

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");
                }

アプリがsystem/appの下にある場合は、system/priv-appに配置する必要があります。例外の起源が何らかの形で役立つことを願っています。

1
Sina