132 votes

installer / désinstaller des APK par programme (PackageManager vs Intents)

Mon application s'installe d'autres applications, et il a besoin de garder une trace de ce que les applications qu'il a installé. Bien sûr, cela pourrait être réalisé en gardant simplement une liste des applications installées. Mais cela ne devrait pas être nécessaire! Il devrait être de la responsabilité de l'PackageManager pour maintenir la installedBy(a, b) de la relation. En fait, selon l'API, il est:

public abstract String getInstallerPackageName(String packageName) - Récupérer le nom du package de l'application qui a installé un paquet. Ce qui identifie le marché provient le paquet.

L'approche actuelle

Installer APK en utilisant l'Intention de

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);

Désinstaller APK en utilisant l'Intention de:

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 l'Android Market s'installe / désinstalle les paquets. Ils utilisent une version enrichie de la PackageManager. Cette montre en téléchargeant le code source Android à partir de l'Android dépôt Git. Ci-dessous sont les deux cachés méthodes qui correspond à l'Intention de l'approche. Malheureusement, ils ne sont pas disponibles à des développeurs externes. Mais peut-être qu'ils le seront dans le futur?

La meilleure approche

Installer APK en utilisant les 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ésinstallation APK en utilisant les 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);

Les différences

  • Lors de l'utilisation de modes locaux gestionnaire de paquets n'est pas informé de l'application de l'installation provient. Plus précisément, getInstallerPackageName(...) renvoie la valeur null.

  • Cachés méthode installationprogiciel(...) prend le package d'installation nom en tant que paramètre, et est le plus susceptible capable de régler cette valeur.

Question

Est-il possible de spécifier le package de l'installateur nom de l'aide intentions? (Peut-être le nom du package du programme d'installation peut être ajouté comme un supplément à l'installation de l'intention?)

Astuce: Si vous souhaitez télécharger le code source Android, vous pouvez suivre les étapes décrites ici: Téléchargement de l'Arbre Source. Pour extraire l' *.java fichiers et les mettre dans des dossiers en fonction de la hiérarchie des paquets, vous pouvez vérifier cet soigné script: Afficher le Code Source Android dans Eclipse.

66voto

hackbod Points 55292

Ce n'est actuellement pas disponible pour les applications tierces. Notez que, même en utilisant la réflexion ou autres astuces pour l'accès installationprogiciel() ne va pas aider, car seules les applications du système de pouvoir l'utiliser. (C'est parce que c'est le faible niveau de mécanisme d'installation, une fois que les autorisations ont été approuvés par l'utilisateur, de sorte qu'il n'est pas sûr pour les applications d'avoir accès à l'.)

Aussi la installationprogiciel() les arguments de la fonction ont souvent changé entre la plate-forme de communiqués, de sorte que tout ce que vous faites en essayant d'accès elle échoue sur divers autres versions de la plate-forme.

EDIT:

Il est également intéressant de souligner que cette installerPackage n'a été ajouté à assez récemment à la plate-forme (2.2?) et à l'origine, non utilisés pour le suivi de la personne ayant installé l'application -- il est utilisé par la plate-forme afin de déterminer qui à lancer lorsque les rapports de bogues avec l'application, de la mise en œuvre Android Commentaires. (C'était aussi l'un des moments la méthode de l'API arguments changé.) Pour au moins un long moment après qu'il a été introduit, le Marché n'a toujours pas l'utiliser pour suivre les apps qu'il a été installé (et il se peut très bien encore de ne pas l'utiliser), mais au lieu de simplement utilisé cette fonction pour définir le Android Commentaires de l'app (qui était distincte de Marché) que le "propriétaire" de prendre soin de commentaires.

65voto

JohnyTex Points 421

[Désinstaller]

Que diriez-vous:

 Intent intent = new Intent(Intent.ACTION_DELETE);
intent.setData(Uri.parse("package:com.android.calculator2"));
startActivity(intent);
 

pour la désinstallation. Cela semble plus facile ...

36voto

Pir Fahim Shah Points 1786

Utilisez ce code, il désinstallera votre application

 Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.setDataAndType(Uri.parse("package:" + app_pkg_name));
  startActivity(intent);
 

4voto

HandlerExploit Points 3881

Le seul moyen d'accéder à ces méthodes est la réflexion. Vous pouvez obtenir un descripteur sur un objet PackageManager en appelant getApplicationContext().getPackageManager() et en utilisant la méthode de réflexion pour accéder à ces méthodes. Commander ce tutoriel.

3voto

njzk2 Points 17085

Selon le code source Froyo, la clé supplémentaire Intent.EXTRA_INSTALLER_PACKAGE_NAME est demandée pour connaître le nom du package du programme d'installation dans PackageInstallerActivity.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: