У моєму додатку встановлено інші програми, і йому потрібно відслідковувати, які програми встановлені. Звичайно, цього можна досягти, просто утримуючи список встановлених додатків. Але це не повинно бути необхідним! Відповідальність PackageManager повинна підтримувати відносини встановленогоBy (a, b). Насправді згідно API це:
публічний конспект String getInstallerPackageName (String packageName) - Отримайте назву пакета програми, яка встановила пакет. Це визначає, з якого ринку прийшов пакет.
Сучасний підхід
Встановіть APK за допомогою Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Видаліть APK за допомогою наміру:
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
Очевидно, це не спосіб, наприклад, Android Market встановлює / видаляє пакети. Вони використовують більш багату версію PackageManager. Це можна побачити, завантаживши вихідний код Android із сховища Android Git. Нижче наведені два прихованих методу, що відповідають підходу Інтенції. На жаль, вони недоступні для зовнішніх розробників. Але, можливо, вони будуть у майбутньому?
Кращий підхід
Встановлення APK за допомогою 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);
Видалення APK за допомогою 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);
Відмінності
При використанні намірів локальному менеджеру пакунків не відомо про те, з якого додатка походить інсталяція. Зокрема, getInstallerPackageName (...) повертає null.
Прихований метод installPackage (...) приймає назву пакета інсталятора як параметр і, швидше за все, здатний встановити це значення.
Питання
Чи можна вказати ім'я інсталятора пакета за допомогою намірів? (Можливо, ім'я пакета інсталятора можна додати як додатковий намір встановлення?)
Порада: Якщо ви хочете завантажити вихідний код Android, ви можете виконати описані тут дії: Завантаження джерельного дерева. Щоб витягти * .java файли та помістити їх у папки відповідно до ієрархії пакунків, ви можете перевірити цей акуратний сценарій: Переглянути вихідний код Android у програмі Eclipse .