Ausführen von Shell-Befehlen unter Android mit Runtime.getRuntime

8

Ich arbeite an einer Geräte-Admin-App (vom Hersteller signiert). Ich verwende es, um andere Apps mit dem folgenden Befehl adb shell für Android 9 zu installieren: -

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

und ich gebe es einfach so weiter: -

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

Aber ich bekomme den Fehler "Katze unbekannt Option S".

Der gleiche Befehl funktioniert einwandfrei, wenn ich ihn über die ADB-Shell ausführe. Ich weiß nicht, was ich falsch mache und könnte Hilfe gebrauchen.

EDIT 1: - Ich habe versucht, den Befehl wie folgt auszuführen: -

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

Aber jetzt bekomme ich den Fehler: -

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)

Edit 2: - Vor Android 9 konnte ich für die Installation von Apps einfach Folgendes tun: -

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

Antworten:

4

Beim Betrachten des Quellcodes von PackageInstallerSession stellte ich fest, dass er geändert wurde in: -

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

Quelle Selbst wenn es sich um eine System-App handelt, funktioniert der Shell-Befehl für die Installation möglicherweise nicht. Aus den Commit-Nachrichten geht hervor, dass dies getan wurde, damit PackageInstaller diesen Job ausführen kann.

Es scheint jedoch, dass dies irgendwann wieder geändert wurde, aber wahrscheinlich nicht in Android 9 enthalten ist: -

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

Quelle

Wenn es sich bei der App also um eine System-App handelt, ist die Verwendung von PackageInstaller der beste Weg.

kein Name
quelle
Genau, überprüfen Sie meinen schlankeren Versuch, Android-Browser-Daten zu löschen, über ADB-Shell funktioniert gut, aber wenn es pragmatisch sogar seine System-App oder in gerooteten Geräten. Diese cmd sind nicht erlaubt, stackoverflow.com/questions/10934304/…
UdayaLakmal
1

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

Wenn sich Ihre App unter System / App befindet, müssen Sie sie möglicherweise in System / Priv-App einfügen. Hoffe der Ursprung der Ausnahme hilft dir irgendwie.

Sina
quelle
Ich habe das gesehen und die aufrufende UID und die System-UID sollten gleich sein. Außerdem heißt es in der Fehlermeldung: - Reverse-Modus wird nur von der Shell unterstützt. Vielleicht hat sich in Android p etwas geändert.
Noname