Wie installiere/aktualisiere/entferne ich APK mit der Klasse „PackageInstaller“ in Android L?

Lesezeit: 9 Minuten

Bitte überprüfen Sie die folgenden Klassen und geben Sie mir den Vorschlag, wie man sie verwendet
https://developer.android.com/reference/android/content/pm/PackageInstaller.html
https://developer.android.com/reference/android/content/pm/PackageInstaller.Session.html

Geben Sie mir also bitte ein Beispiel zum Installieren/Aktualisieren/Entfernen von Apps. Kann es sein, dass die neue Anwendung im Geräteprofilbesitzer installiert wird?

  • Sagen Sie einfach, was Sie brauchen, um eine App auf dem Gerät zu installieren

    – Naveen Tamrakar

    12. November 2014 um 10:42 Uhr

  • Hallo Naveen Tamrakar, ich möchte eine apk auf dem Gerät mithilfe der in Android Lollipop eingeführten Klasse PackageInsatller im Hintergrund installieren.

    – Sud

    12. November 2014 um 10:57 Uhr


  • @Sud glaube nicht, dass es im Hintergrund funktioniert, es funktioniert nur mit einer Absicht.

    – Zaitmann

    28. November 2014 um 11:26 Uhr

  • @zaitsman: Kannst du das bitte im Detail erklären?

    – Sud

    4. Dezember 2014 um 9:43 Uhr

  • @zaitsman: Ich frage nach der Verwendung der PackageInstaller-Klasse (eingeführt in Android Lollipop) zum Installieren von apk

    – Sud

    12. Januar 2015 um 12:13 Uhr

Wie installiereaktualisiereentferne ich APK mit der Klasse „PackageInstaller in Android
amalBit

Es ist ohne Systemberechtigungen möglich Ab Android M.

if ((mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
        == PackageManager.PERMISSION_GRANTED)
        || (installerUid == Process.ROOT_UID)
        || mIsInstallerDeviceOwner) {
    mPermissionsAccepted = true;
} else {
    mPermissionsAccepted = false;
}

Unbeaufsichtigte Installation und Deinstallation von Apps durch den Gerätebesitzer:

Ein Geräteeigentümer kann jetzt Anwendungen mithilfe der PackageInstaller-APIs unabhängig von Google Play for Work im Hintergrund installieren und deinstallieren.

Mehr in diesem Link.


Dies ist ab Android 6.0 möglich.

  • Machen Sie Ihre App zum Geräteeigentümer.

Sobald Ihre App die Gerätebesitzer-Berechtigung erhält, können wir sie ohne Benutzereingriff im Hintergrund installieren, deinstallieren und aktualisieren.

public static boolean installPackage(Context context, InputStream in, String packageName)
        throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
            PackageInstaller.SessionParams.MODE_FULL_INSTALL);
    params.setAppPackageName(packageName);
    // set params
    int sessionId = packageInstaller.createSession(params);
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);
    OutputStream out = session.openWrite("COSU", 0, -1);
    byte[] buffer = new byte[65536];
    int c;
    while ((c = in.read(buffer)) != -1) {
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    in.close();
    out.close();

    session.commit(createIntentSender(context, sessionId));
    return true;
}



private static IntentSender createIntentSender(Context context, int sessionId) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                context,
                sessionId,
                new Intent(ACTION_INSTALL_COMPLETE),
                0);
        return pendingIntent.getIntentSender();
    }

Deinstallieren:

String appPackage = "com.your.app.package";
Intent intent = new Intent(getActivity(), getActivity().getClass());
PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0);
PackageInstaller mPackageInstaller = getActivity().getPackageManager().getPackageInstaller();
mPackageInstaller.uninstall(appPackage, sender.getIntentSender());

Git-Repo hier.

  • vielen dank.. aber ich kann apk nicht installieren.. der ganze code läuft ohne fehler aber es ist kein apk installiert. Ist es mein Verständnis falsch. Silent install apk benötigt gerootetes Gerät..?

    – Sandeep R

    18. Januar 2017 um 5:23 Uhr

  • Für die unbeaufsichtigte Installation muss das Gerät nicht gerootet sein. Auf Ihrem Telefon sollte Android M und höher ausgeführt werden. Und Sie sollten dem Gerätebesitzer die Erlaubnis für Ihre App erteilen. @sandeep folge diesem .. codelabs.developers.google.com/codelabs/cosu/#0

    – amalBit

    18. Januar 2017 um 7:27 Uhr


  • @Maragues Das stille Update funktioniert erst ab 6. (Für eigene und andere Apps)

    – amalBit

    25. Mai 2017 um 15:26 Uhr

  • Wie machen Sie Ihre App zum Gerätebesitzer? ? Ist es über die Benutzeroberfläche des Betriebssystems möglich? Ohne Root oder angeschlossenen PC ?

    – Android-Entwickler

    21. Juli 2017 um 23:27 Uhr

  • Beachten Sie, dass ACTION_INSTALL_COMPLETE eine Variable ist, die Sie selbst deklarieren müssen. Im Repo: github.com/googlesamples/android-testdpc/blob/…es ist definiert als public static final String ACTION_INSTALL_COMPLETE = "com.afwsamples.testdpc.INSTALL_COMPLETE";.

    – Dick Lucas

    20. September 2017 um 18:07 Uhr

Sie können eine Anwendung eines Drittanbieters nicht unbemerkt im neu erstellten Benutzer mit installieren PackageInstaller.Session.commit() ohne besondere “Rechte”.
Du brauchst entweder:

  • der INSTALL_PACKAGES Erlaubnis. Diese Berechtigung ist jedoch nicht für Anwendungen von Drittanbietern verfügbar. Auch mit Ihrer Profilbesitzer-App haben Sie diese spezielle Berechtigung nicht.
  • Führen Sie den Prozess aus als ROOT_UID. Das bedeutet, dass Sie das Gerät rooten müssen.

Von den Android-Quellcode:

if ((mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) == PackageManager.PERMISSION_GRANTED) 
   || (installerUid == Process.ROOT_UID)) {
    mPermissionsAccepted = true;
} else {
    mPermissionsAccepted = false;
}

Wenn Sie weder Root-Zugriff haben noch die INSTALL_PACKAGES Berechtigung, dann wird eine Nachricht an den Benutzer gesendet, in der er gefragt wird, ob er die Berechtigungen bestätigt. Diese Bestätigung wird dann während des Commit verwendet process des PackageInstaller's Sitzung. Offensichtlich ist dies in diesem Fall nicht transparent, da der Benutzer die Installation Ihrer Apps manuell bestätigen muss.

  • Könnten Sie bitte mehr Details zur Endphase geben? Basierend auf Ihrer Antwort sehe ich, dass ich diese Klasse immer noch auf L verwenden kann, aber mit einigen Aktionen des Benutzers. Ich habe diese Logik implementiert, aber leider wird beim Commit keine Absicht ausgeführt oder ein ydialog angezeigt

    – Gleichmut

    2. Dezember 2016 um 9:47 Uhr

  • Ist es überhaupt möglich, den Prozess als ROOT_UID auszuführen?

    – dkchris

    3. März 2017 um 11:25 Uhr

  • Es scheint der Fall zu sein. Aber dazu müssen Sie das Gerät rooten. (=alle Anwendungen werden als root ausgeführt… mehr Infos auf Wikipedia).

    – Florent Dupont

    3. März 2017 um 15:32 Uhr


  • Sehr nützlicher Link, der war: developer.android.com/reference/android/… danke @FlorentDupont

    – Benchuk

    26. November 2017 um 15:43 Uhr

  • @FlorentDupont wie kann ich den Prozess der Installation/Deinstallation von Paketen als ROOT_UID ausführen, wenn ich Root-Berechtigung für meine App habe?

    – aki92

    22. März 2018 um 6:20 Uhr

Wie installiereaktualisiereentferne ich APK mit der Klasse „PackageInstaller in Android
Entwickler

Die bereitgestellte Installationsmethode @amalBit hat bei mir nicht funktioniert. Es ist seltsam, da es so in der implementiert ist Google-Beispiel.

Diese Antwort hat mir geholfen, eine Lösung zu finden. Ich musste einige Teile des Codes ändern. Hier meine Implementierung:

public static void installPackage(Context context, InputStream inputStream)
        throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    int sessionId = packageInstaller.createSession(new PackageInstaller
            .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);

    long sizeBytes = 0;

    OutputStream out = null;
    out = session.openWrite("my_app_session", 0, sizeBytes);

    int total = 0;
    byte[] buffer = new byte[65536];
    int c;
    while ((c = inputStream.read(buffer)) != -1) {
        total += c;
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    inputStream.close();
    out.close();

    // fake intent
    IntentSender statusReceiver = null;
    Intent intent = new Intent(context, SomeActivity.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
            1337111117, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    session.commit(pendingIntent.getIntentSender());
    session.close();
}

Diese Methode kann wie folgt aufgerufen werden:

        InputStream inputStream = getActivity().getAssets().open("my_awesome_app.apk");
        InstallationHelper.installPackage(getActivity(), inputStream);

Sie löschen einfach Ihre Beschränkungen

public static DevicePolicyManager getDpm(Context context) {
    return (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
}

public static ComponentName getAdmin(Context context) {
    return new ComponentName(context, MyDevicePolicyReceiver.class);
}

public static void addMyRestrictions(Context context) {
    getDpm(context).addUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_APPS);
    getDpm(context).addUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
}

public static void clearMyRestrictions(Context context) {
    getDpm(context).clearUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_APPS);
    getDpm(context).clearUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
}

public static void installPackage(Context context, InputStream inputStream)
        throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    int sessionId = packageInstaller.createSession(new PackageInstaller
            .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));

    //openSession checks for user restrictions
    clearMyRestrictions(context);
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);

    long sizeBytes = 0;

    OutputStream out = null;
    out = session.openWrite("my_app_session", 0, sizeBytes);

    int total = 0;
    byte[] buffer = new byte[65536];
    int c;
    while ((c = inputStream.read(buffer)) != -1) {
        total += c;
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    inputStream.close();
    out.close();

    // fake intent
    IntentSender statusReceiver = null;
    Intent intent = new Intent(context, SomeActivity.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
            1337111117, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    session.commit(pendingIntent.getIntentSender());
    session.close();
}

Dies funktioniert auch bei mir, obwohl mein Gerätebesitzer die Installation von Apps und unbekannten Quellen durch den Benutzer einschränkt. Selbst wenn ich dieses Beispiel als Geräteadministrator ausführe, habe ich die java.lang.SecurityException: User restriction prevents installing.

openSession prüft auf Berechtigungen. Mit dieser einfachen Modifikation ist es möglich, die Benutzereinschränkungen nur während eines kurzen Methodenaufrufs zurückzusetzen.

public static DevicePolicyManager getDpm(Context context) {
    return (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
}

public static ComponentName getAdmin(Context context) {
    return new ComponentName(context, MyDevicePolicyReceiver.class);
}

public static void addMyRestrictions(Context context) {
   getDpm(context).addUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_APPS);
   getDpm(context).addUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
}

public static void clearMyRestrictions(Context context) {    
   getDpm(context).clearUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_APPS);
   getDpm(context).clearUserRestriction(getAdmin(context), UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
}

public static void installPackage(Context context, InputStream inputStream)
    throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    int sessionId = packageInstaller.createSession(new PackageInstaller
        .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));

    //openSession checks for user restrictions
    clearMyRestrictions(context);
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);
    addMyRestrictions(context);

    long sizeBytes = 0;

    OutputStream out = null;
    out = session.openWrite("my_app_session", 0, sizeBytes);

    int total = 0;
    byte[] buffer = new byte[65536];
    int c;
    while ((c = inputStream.read(buffer)) != -1) {
        total += c;
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    inputStream.close();
    out.close();

    // fake intent
    IntentSender statusReceiver = null;
    Intent intent = new Intent(context, SomeActivity.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
        1337111117, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    session.commit(pendingIntent.getIntentSender());
    session.close();
}

Bitte kümmern Sie sich um die Ausnahmebehandlung.

  • Ist das für Android L oder M?

    – Benutzer1880957

    13. November 2018 um 9:40 Uhr

  • Gibt es eine Möglichkeit zu erkennen, ob ein solches Problem auftritt?

    – Android-Entwickler

    26. Februar 2021 um 7:39 Uhr

1647846190 586 Wie installiereaktualisiereentferne ich APK mit der Klasse „PackageInstaller in Android
KOTIOS

In Android Api-21 ist unten ein Code-Snippet, über das wir apk im Hintergrund installieren können.

private void runInstallWrite() throws IOException, RemoteException {
        long sizeBytes = -1;

        String opt;
        while ((opt = nextOption()) != null) {
            if (opt.equals("-S")) {
                sizeBytes = Long.parseLong(nextOptionData());
            } else {
                throw new IllegalArgumentException("Unknown option: " + opt);
            }
        }

        final int sessionId = Integer.parseInt(nextArg());
        final String splitName = nextArg();

        String path = nextArg();
        if ("-".equals(path)) {
            path = null;
        } else if (path != null) {
            final File file = new File(path);
            if (file.isFile()) {
                sizeBytes = file.length();
            }
        }

        final SessionInfo info = mInstaller.getSessionInfo(sessionId);

        PackageInstaller.Session session = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));

            if (path != null) {
                in = new FileInputStream(path);
            } else {
                in = new SizedInputStream(System.in, sizeBytes);
            }
            out = session.openWrite(splitName, 0, sizeBytes);

            int total = 0;
            byte[] buffer = new byte[65536];
            int c;
            while ((c = in.read(buffer)) != -1) {
                total += c;
                out.write(buffer, 0, c);

                if (info.sizeBytes > 0) {
                    final float fraction = ((float) c / (float) info.sizeBytes);
                    session.addProgress(fraction);
                }
            }
            session.fsync(out);

            System.out.println("Success: streamed " + total + " bytes");
        } finally {
            IoUtils.closeQuietly(out);
            IoUtils.closeQuietly(in);
            IoUtils.closeQuietly(session);
        }
    }

Der obige Code stammt aus Framework Hier

Kann ich diesen Code mit device_owner oder einem normalen Benutzer in LoLiipop verwenden?

Antwort – Nein, da es APIs gibt, die in Android-Frameworks ein @hide-Tag sind, obwohl PackageManager.Session in API 21 eingeführt wird, aber wir können das neue PAckageManager.Session() nicht verwenden, da es in API 21 @hide ist.

Wenn Sie diesen Code dennoch über framework.jar verwenden möchten, müssen Sie den Lolippop-Quellcode erstellen und jar aus out/…./framework.jar extrahieren und obige APIs aufrufen.

  • Ist das für Android L oder M?

    – Benutzer1880957

    13. November 2018 um 9:40 Uhr

  • Gibt es eine Möglichkeit zu erkennen, ob ein solches Problem auftritt?

    – Android-Entwickler

    26. Februar 2021 um 7:39 Uhr

1647846191 93 Wie installiereaktualisiereentferne ich APK mit der Klasse „PackageInstaller in Android
Vibor Chopra

INSTALLIEREN:

Intent promptInstall = new Intent(Intent.ACTION_VIEW);
        promptInstall.setDataAndType(Uri.fromFile(new File(Environment
                .getExternalStorageDirectory() + "/download/" + APK_NAME)),
                "application/vnd.android.package-archive");
        promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(promptInstall);

DEINSTALLIEREN:

Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);

  • Bitte lesen Sie meine Frage sorgfältig durch. Ich frage nach der Verwendung der PackageInstaller-Klasse (eingeführt in Android Lollipop) zum Installieren von apk.

    – Sud

    12. November 2014 um 10:54 Uhr

1005200cookie-checkWie installiere/aktualisiere/entferne ich APK mit der Klasse „PackageInstaller“ in Android L?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy