Мое приложение устанавливает другие приложения, и оно должно отслеживать, какие приложения оно установило. Конечно, этого можно достичь, просто ведя список установленных приложений. Но это не должно быть необходимым! PackageManager должен нести ответственность за поддержание отношения установленныхBy (a, b). На самом деле, согласно API это:
публичная абстрактная строка getInstallerPackageName (строка имя_пакета) -
Получить имя пакета приложения, которое установило пакет. Это определяет, с какого рынка пришла посылка.
Текущий подход
Установить 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. Ниже приведены два скрытых метода, которые соответствуют подходу 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'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 (...) возвращает ноль.
Скрытый метод installPackage (...) принимает имя пакета установщика в качестве параметра и, скорее всего, может установить это значение.
Вопрос
Можно ли указать имя установщика пакета с помощью намерений?
(Может быть, имя установочного пакета можно добавить как дополнение к намерению установки?)
Подсказка. Если вы хотите загрузить исходный код Android, вы можете выполнить действия, описанные здесь: Загрузка исходного кода. Чтобы извлечь файлы * .java и поместить их в папки в соответствии с иерархией пакетов, вы можете проверить этот аккуратный скрипт: Просмотр исходного кода Android в Eclipse .