私のアプリケーションは他のアプリケーションをインストールし、インストールしたアプリケーションを追跡する必要があります。もちろん、これは、インストールされているアプリケーションのリストを保持するだけで実現できます。しかし、これは必要ないはずです!installedManager(a、b)関係を維持するのはPackageManagerの責任です。実際、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 = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
これは明らかにAndroid Marketがパッケージをインストール/アンインストールする方法ではありません。それらは、PackageManagerのより豊富なバージョンを使用します。これは、AndroidソースコードをAndroid Gitリポジトリからダウンロードすることで確認できます。以下は、インテントアプローチに対応する2つの非表示メソッドです。残念ながら、外部の開発者はそれらを利用できません。しかし、おそらくそれらは将来的になるでしょうか?
より良いアプローチ
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);
違い
インテントを使用する場合、ローカルパッケージマネージャーは、インストール元のアプリケーションを認識しません。具体的には、getInstallerPackageName(...)はnullを返します。
非表示のメソッドinstallPackage(...)は、パラメーターとしてインストーラーパッケージ名を受け取り、ほとんどの場合、この値を設定できます。
質問
インテントを使用してパッケージインストーラー名を指定することは可能ですか? (おそらく、インストーラーパッケージの名前をインストールインテントの追加として追加できますか?)
ヒント:Androidソースコードをダウンロードしたい場合は、ここで説明されている手順に従ってください:ソースツリーのダウンロード。* .javaファイルを抽出し、パッケージ階層に従ってフォルダーに配置するには、次のきちんとしたスクリプトを確認できます。EclipseでAndroidソースコードを表示する。