программная установка / удаление APK (PackageManager vs Intents)

Мое приложение устанавливает другие приложения, и ему необходимо отслеживать, какие приложения оно установило. Конечно, этого можно добиться, просто ведя список установленных приложений. Но в этом не должно быть необходимости! PackageManager должен нести ответственность за поддержание отношения installedBy (a, b). Фактически, согласно API это:

общедоступная абстрактная строка getInstallerPackageName (String packageName) - Получить имя пакета приложения, установившего пакет. Это определяет, с какого рынка поступил пакет.

Текущий подход

Установить APK с помощью намерения

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 (...) возвращает значение null.

  • Скрытый метод installPackage (...) принимает имя пакета установщика в качестве параметра и, скорее всего, способен установить это значение.

Вопрос

Является ли Можно ли указать имя установщика пакета с помощью намерений? (Может быть, имя пакета установщика можно добавить в качестве дополнения к намерениям установки?)

Совет: если вы хотите загрузить исходный код Android, вы можете следовать шаги, описанные здесь: Загрузка исходного дерева. Чтобы извлечь файлы * .java и поместить их в папки в соответствии с иерархией пакетов, вы можете проверить этот аккуратный сценарий: Просмотреть исходный код Android в Eclipse .

136
задан Håvard Geithus 27 July 2011 в 07:10
поделиться