La mia applicazione installa altre applicazioni e deve tenere traccia delle applicazioni installate. Naturalmente, questo potrebbe essere ottenuto semplicemente mantenendo un elenco di applicazioni installate. Ma questo non dovrebbe essere necessario! Dovrebbe essere responsabilità del PackageManager mantenere la relazione InstallBy (a, b). Infatti, secondo l'API è:
abstract pubblico String getInstallerPackageName (String nomepacchetto) - Recupera il nome del pacchetto dell'applicazione che ha installato un pacchetto. Ciò identifica da quale mercato proviene il pacchetto.
L'attuale approccio
Installa APK usando Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Disinstallare APK usando Intent:
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
Questo ovviamente non è il modo in cui Android Market installa / disinstalla i pacchetti. Usano una versione più ricca di PackageManager. Questo può essere visto scaricando il codice sorgente Android dal repository Android Git. Di seguito sono riportati i due metodi nascosti che corrispondono all'approccio Intento. Purtroppo non sono disponibili per sviluppatori esterni. Ma forse saranno in futuro?
L'approccio migliore
Installazione di APK tramite 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);
Disinstallazione di APK mediante 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);
differenze
Quando si utilizzano gli intenti, il gestore pacchetti locale non viene a conoscenza di quale applicazione abbia avuto origine l'installazione. In particolare, getInstallerPackageName (...) restituisce null.
Il metodo nascosto installPackage (...) accetta il nome del pacchetto di installazione come parametro ed è probabilmente in grado di impostare questo valore.
Domanda
È possibile specificare il nome del programma di installazione del pacchetto utilizzando gli intenti? (Forse il nome del pacchetto di installazione può essere aggiunto come extra all'intenzione di installazione?)
Suggerimento: se si desidera scaricare il codice sorgente Android, è possibile seguire i passaggi descritti qui: Download della struttura dei sorgenti. Per estrarre i file * .java e metterli in cartelle in base alla gerarchia dei pacchetti, puoi dare un'occhiata a questo script accurato: Visualizza il codice sorgente Android in Eclipse .