Mon application installe d'autres applications et doit garder une trace des applications qu'elle a installées. Bien sûr, cela pourrait être réalisé en conservant simplement une liste des applications installées. Mais cela ne devrait pas être nécessaire! Il devrait être de la responsabilité du PackageManager de maintenir la relation InstallBy (a, b). En fait, selon l'API c'est:
public abstract String getInstallerPackageName (String packageName) - Récupère le nom du package de l'application qui a installé un package. Cela identifie de quel marché provient le colis.
L'approche actuelle
Installer l'APK en utilisant l'intention
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Désinstallez l'APK avec Intent:
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
Ce n'est évidemment pas la façon dont, par exemple, Android Market installe / désinstalle les packages. Ils utilisent une version plus riche de PackageManager. Cela peut être vu en téléchargeant le code source Android à partir du référentiel Android Git. Vous trouverez ci-dessous les deux méthodes cachées qui correspondent à l'approche Intent. Malheureusement, ils ne sont pas disponibles pour les développeurs externes. Mais peut-être le seront-ils dans le futur?
La meilleure approche
Installer l'APK à l'aide de 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);
Désinstaller l'APK à l'aide de 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);
Différences
Lors de l'utilisation d'intents, le gestionnaire de packages local n'est pas informé de l'application d'origine de l'installation. Plus précisément, getInstallerPackageName (...) renvoie null.
La méthode masquée installPackage (...) prend le nom du package du programme d'installation comme paramètre et est probablement capable de définir cette valeur.
Question
Est-il possible de spécifier le nom du programme d'installation du package à l'aide d'intents? (Peut-être que le nom du package d'installation peut être ajouté en supplément à l'intention d'installation?)
Conseil: Si vous souhaitez télécharger le code source Android, vous pouvez suivre les étapes décrites ici: Téléchargement de l'arborescence source. Pour extraire les fichiers * .java et les placer dans des dossiers selon la hiérarchie des packages, vous pouvez consulter ce script soigné: Afficher le code source Android dans Eclipse .
Réponses:
Ce n'est actuellement pas disponible pour les applications tierces. Notez que même l'utilisation de la réflexion ou d'autres astuces pour accéder à installPackage () n'aidera pas, car seules les applications système peuvent l'utiliser. (C'est parce qu'il s'agit du mécanisme d'installation de bas niveau, une fois que les autorisations ont été approuvées par l'utilisateur, il n'est donc pas sûr pour les applications normales d'y accéder.)
De plus, les arguments de la fonction installPackage () ont souvent changé entre les versions de la plate-forme, donc tout ce que vous essayez d'y accéder échouera sur diverses autres versions de la plate-forme.
ÉDITER:
Il convient également de noter que ce programme d'installation n'a été ajouté que récemment à la plate-forme (2.2?) Et n'était à l'origine pas utilisé pour suivre qui a installé l'application - il est utilisé par la plate-forme pour déterminer qui lancer lors du signalement de bogues avec l'application, pour mettre en œuvre Android Feedback. (Ce fut également l'une des fois où les arguments de la méthode API ont changé.) Pendant au moins un long moment après son introduction, Market ne l'a toujours pas utilisé pour suivre les applications qu'il a installées (et il se peut très bien qu'il ne l'utilise toujours pas. ), mais l'a simplement utilisé pour définir l'application Android Feedback (qui était distincte de Market) en tant que "propriétaire" pour prendre en charge les commentaires.
la source
Android P + nécessite cette autorisation dans AndroidManifest.xml
Ensuite:
pour désinstaller. Cela semble plus facile ...
la source
onDestroy()
méthode?Le niveau 14 de l'API a introduit deux nouvelles actions: ACTION_INSTALL_PACKAGE et ACTION_UNINSTALL_PACKAGE . Ces actions vous permettent de passer EXTRA_RETURN_RESULT booléen supplémentaire pour obtenir une notification de (dés) installation de résultat.
Exemple de code pour appeler la boîte de dialogue de désinstallation:
Et recevez la notification dans votre méthode Activity # onActivityResult :
la source
ACTION_INSTALL_PACKAGE
nécessitera l'REQUEST_INSTALL_PACKAGES
autorisation au niveau de la signature . De même, à partir de l'API 28 (Android P), l'appelACTION_UNINSTALL_PACKAGE
nécessitera l'REQUEST_DELETE_PACKAGES
autorisation non dangereuse . Au moins selon la documentation.Si vous disposez de l'autorisation de propriétaire de l'appareil (ou du propriétaire du profil, je n'ai pas essayé), vous pouvez installer / désinstaller silencieusement des packages à l'aide de l'API du propriétaire de l'appareil.
pour la désinstallation:
et pour installer le package:
la source
La seule façon d'accéder à ces méthodes est la réflexion. Vous pouvez obtenir une poignée sur un
PackageManager
objet en appelantgetApplicationContext().getPackageManager()
et en utilisant la réflexion pour accéder à ces méthodes. Consultez ce tutoriel.la source
Selon le code source de Froyo, la clé supplémentaire Intent.EXTRA_INSTALLER_PACKAGE_NAME est interrogée pour le nom du package d'installation dans PackageInstallerActivity.
la source
Sur un appareil enraciné, vous pouvez utiliser:
Util.sudo()
est défini ici.la source
Si vous passez le nom du package en tant que paramètre à l'une de vos fonctions définies par l'utilisateur, utilisez le code ci-dessous:
la source
Si vous utilisez Kotlin, API 14+, et que vous souhaitez simplement afficher la boîte de dialogue de désinstallation de votre application:
Vous pouvez
packageName
utiliser n'importe quel autre nom de package si vous souhaitez inviter l'utilisateur à désinstaller une autre application sur l'appareilla source
Prérequis:
Votre APK doit être signé par le système comme indiqué précédemment. Une façon d'y parvenir consiste à créer vous-même l'image AOSP et à ajouter le code source dans la construction.
Code:
Une fois installé en tant qu'application système, vous pouvez utiliser les méthodes du gestionnaire de packages pour installer et désinstaller un APK comme suit:
Installer:
Désinstaller:
Pour avoir un rappel une fois que votre APK est installé / désinstallé, vous pouvez utiliser ceci:
la source