Meine Anwendung installiert andere Anwendungen und muss nachverfolgen, welche Anwendungen sie installiert hat. Dies könnte natürlich erreicht werden, indem einfach eine Liste der installierten Anwendungen geführt wird. Das sollte aber nicht nötig sein! Es sollte in der Verantwortung des PackageManager liegen, die installierte By (a, b) -Beziehung aufrechtzuerhalten. In der Tat ist es laut API:
public abstract String getInstallerPackageName (String packageName) - Ruft den Paketnamen der Anwendung ab, die ein Paket installiert hat. Dies identifiziert, von welchem Markt das Paket kam.
Der aktuelle Ansatz
Installieren Sie APK mit Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Deinstallieren Sie APK mit Intent:
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
Dies ist offensichtlich nicht der Weg, z. B. installiert / deinstalliert Android Market Pakete. Sie verwenden eine umfangreichere Version des PackageManager. Dies kann durch Herunterladen des Android-Quellcodes aus dem Android Git-Repository festgestellt werden. Nachfolgend sind die beiden versteckten Methoden aufgeführt, die dem Intent-Ansatz entsprechen. Leider stehen sie externen Entwicklern nicht zur Verfügung. Aber vielleicht werden sie es in Zukunft sein?
Der bessere Ansatz
Installieren von APK mit dem PackageManager
/**
* @hide
*
* Install a package. Since this may take a little while, the result will
* be posted back to the given observer. An installation will fail if the calling context
* lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
* package named in the package file's manifest is already installed, or if there's no space
* available on the device.
*
* @param packageURI The location of the package file to install. This can be a 'file:' or a
* 'content:' URI.
* @param observer An observer callback to get notified when the package installation is
* complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
* called when that happens. observer may be null to indicate that no callback is desired.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
* {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
*/
public abstract void installPackage(
Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName);
Deinstallation von APK mit dem PackageManager
/**
* Attempts to delete a package. Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the calling context
* lacks the {@link android.Manifest.permission#DELETE_PACKAGES} permission, if the
* named package cannot be found, or if the named package is a "system package".
* (TODO: include pointer to documentation on "system packages")
*
* @param packageName The name of the package to delete
* @param observer An observer callback to get notified when the package deletion is
* complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
* called when that happens. observer may be null to indicate that no callback is desired.
* @param flags - possible values: {@link #DONT_DELETE_DATA}
*
* @hide
*/
public abstract void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags);
Unterschiede
Bei Verwendung von Absichten wird dem lokalen Paketmanager nicht mitgeteilt, von welcher Anwendung die Installation stammt. Insbesondere gibt getInstallerPackageName (...) null zurück.
Die versteckte Methode installPackage (...) verwendet den Namen des Installationspakets als Parameter und kann diesen Wert höchstwahrscheinlich festlegen.
Frage
Ist es möglich, den Namen des Paketinstallationsprogramms mit Absichten anzugeben? (Vielleicht kann der Name des Installationspakets als Extra zur Installationsabsicht hinzugefügt werden?)
Tipp: Wenn Sie den Android-Quellcode herunterladen möchten, können Sie die hier beschriebenen Schritte ausführen: Herunterladen des Quellbaums. Um die * .java-Dateien zu extrahieren und sie gemäß der Pakethierarchie in Ordnern abzulegen, können Sie dieses übersichtliche Skript überprüfen: Anzeigen des Android-Quellcodes in Eclipse .
Antworten:
Dies ist derzeit nicht für Anwendungen von Drittanbietern verfügbar. Beachten Sie, dass selbst die Verwendung von Reflection oder anderen Tricks für den Zugriff auf installPackage () nicht hilfreich ist, da nur Systemanwendungen es verwenden können. (Dies liegt daran, dass es sich um den Installationsmechanismus auf niedriger Ebene handelt, nachdem die Berechtigungen vom Benutzer genehmigt wurden. Daher ist der Zugriff auf reguläre Anwendungen nicht sicher.)
Außerdem haben sich die Funktionsargumente von installPackage () zwischen den Plattformversionen häufig geändert, sodass alles, was Sie versuchen, darauf zuzugreifen, auf verschiedenen anderen Versionen der Plattform fehlschlägt.
BEARBEITEN:
Es ist auch erwähnenswert, dass dieses installerPackage erst vor relativ kurzer Zeit zur Plattform hinzugefügt wurde (2.2?) Und ursprünglich nicht zum Nachverfolgen verwendet wurde, wer die App installiert hat. Es wird von der Plattform verwendet, um zu bestimmen, wer gestartet werden soll, wenn Fehler gemeldet werden die App zur Implementierung von Android Feedback. (Dies war auch einer der Fälle, in denen sich die Argumente der API-Methode geändert haben.) Zumindest lange Zeit nach ihrer Einführung verwendete Market sie immer noch nicht, um die installierten Apps zu verfolgen (und sie wird sie möglicherweise immer noch nicht verwenden ), sondern nur die Android-Feedback-App (die vom Markt getrennt war) als "Eigentümer" festgelegt, um sich um das Feedback zu kümmern.
quelle
Android P + erfordert diese Berechtigung in AndroidManifest.xml
Dann:
zu deinstallieren. Scheint einfacher ...
quelle
onDestroy()
Methode?API-Level 14 führte zwei neue Aktionen ein: ACTION_INSTALL_PACKAGE und ACTION_UNINSTALL_PACKAGE . Mit diesen Aktionen können Sie das boolesche Extra EXTRA_RETURN_RESULT übergeben , um eine Benachrichtigung über das (Un-) Installationsergebnis zu erhalten.
Beispielcode zum Aufrufen des Deinstallationsdialogs:
Und erhalten Sie die Benachrichtigung in Ihrer Activity # onActivityResult- Methode:
quelle
ACTION_INSTALL_PACKAGE
erfordert der Aufruf dieREQUEST_INSTALL_PACKAGES
Berechtigung auf Signaturstufe . Ab API 28 (Android P) ist für AnrufeACTION_UNINSTALL_PACKAGE
ebenfalls die ungefährlicheREQUEST_DELETE_PACKAGES
Berechtigung erforderlich . Zumindest nach den Unterlagen.Wenn Sie über die Berechtigung Gerätebesitzer (oder Profilbesitzer, die ich nicht ausprobiert habe) verfügen, können Sie Pakete mithilfe der Gerätebesitzer-API unbeaufsichtigt installieren / deinstallieren.
zur Deinstallation:
und um das Paket zu installieren:
quelle
Der einzige Weg, auf diese Methoden zuzugreifen, ist die Reflexion. Sie können ein
PackageManager
Objekt in den Griff bekommen ,getApplicationContext().getPackageManager()
indem Sie diese Methoden aufrufen und Reflection Access verwenden. Kasse dieses Tutorial.quelle
Gemäß dem Froyo-Quellcode wird der zusätzliche Schlüssel Intent.EXTRA_INSTALLER_PACKAGE_NAME nach dem Namen des Installationspakets in der PackageInstallerActivity abgefragt.
quelle
Auf einem gerooteten Gerät können Sie Folgendes verwenden:
Util.sudo()
ist hier definiert.quelle
Wenn Sie den Paketnamen als Parameter an eine Ihrer benutzerdefinierten Funktionen übergeben, verwenden Sie den folgenden Code:
quelle
Wenn Sie Kotlin, API 14+ verwenden und nur den Deinstallationsdialog für Ihre App anzeigen möchten:
Sie können
packageName
zu einem anderen Paketnamen wechseln , wenn Sie den Benutzer auffordern möchten, eine andere App auf dem Gerät zu deinstallierenquelle
Voraussetzung:
Ihre APK muss vom System signiert werden, wie bereits erwähnt. Eine Möglichkeit, dies zu erreichen, besteht darin, das AOSP-Image selbst zu erstellen und den Quellcode zum Build hinzuzufügen.
Code:
Nach der Installation als System-App können Sie die APP mithilfe der Paketmanager-Methoden wie folgt installieren und deinstallieren:
Installieren:
Deinstallieren:
Um einen Rückruf zu erhalten, sobald Ihr APK installiert / deinstalliert ist, können Sie Folgendes verwenden:
quelle