Installieren Sie APK mit root, Umgang mit neuen Grenzen „/data/local/tmp/“ – Ordner

Hintergrund

So weit, ich war in der Lage, installieren APK-Dateien mit root (innerhalb der app), über diesen code:

pm install -t -f fullPathToApkFile

und wenn ich möchte (versuchen zu) installieren Sie auf sd-Karte :

pm install -t -s fullPathToApkFile

Das problem

Vor kurzem nicht sicher, von welcher Android-version (Problem besteht auf Android P beta zumindest), die oben beschriebenen Methode fehlschlägt, zeigt mir diese Meldung:

avc:  denied  { read } for  scontext=u:r:system_server:s0 tcontext=u:object_r:sdcardfs:s0 tclass=file permissive=0
System server has no access to read file context u:object_r:sdcardfs:s0 (from path /storage/emulated/0/Download/FDroid.apk, context u:r:system_server:s0)
Error: Unable to open file: /storage/emulated/0/Download/FDroid.apk
Consider using a file under /data/local/tmp/
Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
Exception occurred while executing:
java.lang.IllegalArgumentException: Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
    at com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:306)
    at com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:884)
    at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:138)
    at android.os.ShellCommand.exec(ShellCommand.java:103)
    at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21125)
    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:2806)
    at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3841)
    at android.os.Binder.execTransact(Binder.java:731)

Scheint dies auch Auswirkungen auf beliebte apps wie „Titanium backup (pro)“, die fehlschlägt, wiederherstellen von apps.

, Was ich versucht habe

Schauen, was geschrieben wird, es scheint, es fehlt die Berechtigung zum installieren von APK-Dateien, die nicht in /data/local/tmp/.

Also versuchte ich die nächsten Dinge, um zu sehen, ob ich es zu überwinden:

  1. setzen Sie den Zugriff auf die Datei (chmod 777) – hat nicht geholfen.
  2. gewähren von Berechtigungen für die app, von der sowohl Speicher-und REQUEST_INSTALL_PACKAGES (mit ACTION_MANAGE_UNKNOWN_APP_SOURCES Vorsatz) – hat nicht geholfen.
  3. erstellen Sie einen symbolischen Link auf die Datei, so dass es innerhalb der /data/local/tmp/ mit der offiziellen API:

     Os.symlink(fullPathToApkFile, symLinkFilePath)

    Dieser etwas nicht tun.

  4. erstellen Sie einen symbolischen Link mit diesem :

     ln -sf $fullPathToApkFile $symLinkFilePath

    Diese teilweise gearbeitet. Die Datei ist da, wie ich es sehen kann, im Total Commander app, aber wenn ich versuche, um zu überprüfen, ob es dort vorhanden ist, und wenn ich versuche zu installieren die APK von dort, es funktioniert nicht.

  5. Kopieren/verschieben (mit cp oder mv) die Datei auf die /data/local/tmp/ Weg, und dann von dort installieren. Das funktionierte, aber es hat Nachteile: der Umzug ist riskant, weil es vorübergehend blendet die original-Datei und es ändert sich der Zeitstempel der original-Datei. Kopieren ist schlecht, weil der extra Raum nur für die Installation (auch vorübergehend) und da es verschwendet Zeit dafür.

  6. Kopieren Sie die APK-Datei, sagen Sie zu vermeiden, tatsächliche Kopie (also hard-link), mit diesem Befehl (aus hier) :

     cp -p -r -l $fullPathToApkFile $tempFileParentPath"

    Dies hat nicht funktioniert. Es wurde mir diese Fehlermeldung:

     cp: /data/local/tmp/test.apk: Cross-device link
  7. Prüfen, was passiert, in anderen Fällen das installieren von apps. Wenn Sie die Installation über die über die IDE, die es tatsächlich schaffen, die APK-Datei in diesem speziellen Weg, aber wenn Sie die Installation über den Play Store, einfach APK installieren (per Intent) oder adb (über PC), ist es nicht.

  8. Schrieb dazu auch hier: https://issuetracker.google.com/issues/80270303

Die Fragen

  1. Gibt es eine Möglichkeit zur überwindung der Nachteile der Installation von der APK mit root auf diesem speziellen Weg? Vielleicht sogar vermeiden Sie den Umgang dieser Weg überhaupt?

  2. Warum das OS plötzlich das verlangen, auf diesem Weg? Warum nicht den original-Pfad statt, genau wie in den anderen Methoden zum installieren von apps? Was tun mit den anderen Methoden zum installieren von apps zu tun, dass das irgendwie verhindert mit der räumliche Weg?



One Reply
  1. 1

    Einer Lösung, im Fall, dass Sie don ‚ T mind moving-Verfahren, ist auch save&restore der Zeitstempel der original-Datei, die als solche:

        val tempFileParentPath = "/data/local/tmp/"
        val tempFilePath = tempFileParentPath + File(fullPathToApkFile).name
        val apkTimestampTempFile = File(context.cacheDir, "apkTimestamp")
        apkTimestampTempFile.delete()
        apkTimestampTempFile.mkdirs()
        apkTimestampTempFile.createNewFile()
        root.runCommands("touch -r $fullPathToApkFile ${apkTimestampTempFile.absolutePath}")
        root.runCommands("mv $fullPathToApkFile $tempFileParentPath")
        root.runCommands("pm install -t -f $tempFilePath")
        root.runCommands("mv $tempFilePath $fullPathToApkFile")
        root.runCommands("touch -r ${apkTimestampTempFile.absolutePath} $fullPathToApkFile")
        apkTimestampTempFile.delete()

    Es ist immer noch ein bisschen gefährlich, aber besser als das kopieren von Dateien…


    EDIT: Google hat mir gezeigt, eine nette Abhilfe für dieses (hier) :

    Wir unterstützen nicht die installation von APKs aus zufälligen Verzeichnisse auf dem Gerät. Sie müssen entweder installiert sein, die direkt aus der host mit ‚adb install“ oder Sie haben zu streamen, die Inhalte zu installieren —

    $ cat foo.apk | pm install -S APK_SIZE

    Während ich denke, es ist falsch, dass Sie nicht unterstützen, installieren APK-Dateien von zufallspfaden (immer vorher gearbeitet), der workaround scheint zu funktionieren. Alles, was ich brauchte, um zu ändern, in den code der Installation einer APK-Datei ist wie folgt:

    val length = File(fullPathToApkFile ).length()
    commands.add("cat $fullPathToApkFile | pm install -S $length")

    Sache ist, nun habe ich einige andere Fragen :

    1. Hat diese Problemumgehung vermeiden Sie das verschieben/kopieren der APK in das Lager, und ohne die original-Datei ? – scheint es nicht
    2. Wird diese Unterstützung jede APK-Datei, auch große ones? – scheint es ihm gelingt, es zu tun für eine APK, die nimmt 433MB, so dass ich denke, es ist sicher für alle Größen.
    3. Erforderlich ist dies nur von Android P, richtig? – so weit scheint so.
    4. Wieso braucht es die Größe der Datei als parameter ? – Keine Ahnung, aber wenn ich es entfernen, es wird nicht funktionieren

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.