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 .