Мое приложение устанавливает другие приложения, и ему необходимо отслеживать, какие приложения он установил. Конечно, этого можно добиться, просто сохранив список установленных приложений. Но это не обязательно! Администратор PackageManager должен поддерживать поддерживаемые отношения b (a, b). Фактически, согласно API, это:
public abstract String getInstallerPackageName (String packageName) - Получить имя пакета приложения, которое установило пакет. Это определяет, на каком рынке появился пакет.
Текущий подход
Установить APK с использованием намерения
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Удалите APK с помощью Intent:
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. Ниже приведены два скрытых метода, которые соответствуют подходу Intent. К сожалению, они недоступны для внешних разработчиков. Но, возможно, они будут в будущем?
Лучший подход
Установка 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 manifest is already installed, or if there 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 и поместить их в папки в соответствии с иерархией пакетов, вы можете проверить этот чистый script: Просмотр исходного кода Android в Eclipse.я >