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


8

私はデバイス管理アプリに取り組んでいます(製造元によって署名されています)。私はそれを使用して、以下の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シェルから実行すると、まったく問題なく動作します。私が何を間違っているのかわからないので、助けを借りてください。

編集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");

回答:


4

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にこの仕事をさせるために行われたようです。

しかし、これはある時点で再び変更されたようですが、おそらくアンドロイド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を使用することです。


正確には、Androidブラウザーのデータをクリアするための私のスリムな試みをチェックしてください。adbシェルを介して正常に機能しますが、実際には、システムアプリやルート化されたデバイスでも実行できます。これらの
コマンド

1

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に配置する必要があります。例外の原因が何らかの形で役立つことを願っています。


私はこれを見て、呼び出し元のuidとシステムuidは同じになるはずです。さらに、エラーメッセージには次のように表示されます:-シェルからのみサポートされるリバースモード。だからおそらくアンドロイドpで何かが変更されました。
noname
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.