我的应用程序将安装其他应用程序,并且需要跟踪已安装的应用程序。当然,这可以通过简单地保留已安装的应用程序列表来实现。但这不是必须的!PackageManager应该负责维护installedBy(a,b)关系。实际上,根据API,它是:
公共抽象字符串getInstallerPackageName(字符串packageName)- 检索安装软件包的应用程序的软件包名称。这可以确定包装来自哪个市场。
目前的做法
使用Intent安装APK
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
使用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 Git存储库下载Android源代码可以看出这一点。以下是与Intent方法相对应的两个隐藏方法。不幸的是,它们对外部开发人员不可用。但是也许它们会在未来吗?
更好的方法
使用PackageManager安装APK
/**
* @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);
使用PackageManager卸载APK
/**
* 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);
差异性
使用Intent时,本地软件包管理器不会知道安装来自哪个应用程序。具体来说,getInstallerPackageName(...)返回null。
隐藏的方法installPackage(...)将安装程序包名称作为参数,并且很可能能够设置此值。
题
是否可以使用意图指定软件包安装程序名称? (也许可以将安装程序包的名称作为附加内容添加到安装意图中?)
提示:如果要下载Android源代码,可以按照此处描述的步骤进行操作:下载源代码树。要提取* .java文件并将其根据包层次结构放置在文件夹中,您可以检出以下简洁的脚本:在Eclipse中查看Android源代码。