ダウンロードした APK をファイル システムからインストールすることを仕事とする InstallationHelper というアクティビティがあります。以下で installApk() が呼び出されると、作成した Environment.getExternalStorageDirectory() ディレクトリに存在する APK へのファイルパスが渡されます。
private void installApk(String filepath)
{
Intent installAPK = new Intent(Intent.ACTION_VIEW);
installAPK.setDataAndType(Uri.fromFile(
new File(filepath)), "application/vnd.android.package-archive");
startActivityForResult(installAPK, ACTION_INSTALL_APK);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d(LOG_TAG, "Installation activity completed, " +
"request code: " + requestCode +
", result code: " + resultCode +
", intent: " + data);
deleteFile();
finish();
}
private void deleteFile()
{
Log.d(LOG_TAG, "Attempting to delete file: " + file.getCanonicalPath());
...
}
これは、Google が PackageVerificationService ( https://support.google.com/accounts/answer/2812853?hl=en )を導入した最近まで、非常にうまく機能していました。startActivityForResult() が呼び出されると、インテントを処理するダイアログがユーザーに表示されます (つまり、「パッケージ インストーラー」、「検証とインストール」(Google)、および Lookout などのその他のフィルター)。コードは、デフォルトのパッケージ インストーラーで動作します。と Lookout を使用しますが、[確認してインストール] を選択すると、インストールが開始される前に onActivityResult() がすぐに呼び出されます。ログは次のとおりです。
「パッケージインストーラー」を使用:
07-26 10:44:01.167: D/InstallationHelper(24528): Attempting to install file: /storage/sdcard0/SC/599173
07-26 10:44:01.167: D/InstallationHelper(24528): startActivityGotResult()
...
07-26 10:44:17.993: I/System.out(23660): siso added package name is package:com.opensignal.weathersignal
07-26 10:44:18.043: I/MediaHubAPP(3068): MHDisable Receiver action = android.intent.action.PACKAGE_ADDED
07-26 10:44:18.043: I/MediaHubAPP(3068): MHDisable Receiver PackageName = com.opensignal.weathersignal
...
07-26 10:44:20.276: I/InstallAppProgress(14735): Finished installing com.opensignal.weathersignal
07-26 10:44:20.336: D/InstallationHelper(24528): Installation activity completed, request code: 1, result code: 0, intent: null
07-26 10:44:20.396: D/InstallationHelper(24528): Attempting to delete file: /storage/sdcard0/SC/599173
「確認してインストール」を使用する:
07-26 10:58:42.366: D/InstallationHelper(24528): Starting InstallationHelper...
07-26 10:58:42.366: D/InstallationHelper(24528): Attempting to install file: /storage/sdcard0/SC/599173
07-26 10:58:42.366: D/InstallationHelper(24528): startActivityGotResult()
07-26 10:58:49.894: D/InstallationHelper(24528): Installation activity completed, request code: 1, result code: 0, intent: null
07-26 10:58:49.934: D/InstallationHelper(24528): Attempting to delete file: /storage/sdcard0/SC/599173
07-26 10:58:49.954: D/Finsky(14410): [47670] PackageVerificationService.getPackageInfo: Error while calculating sha256 for file=file:///storage/sdcard0/SC/599173, error=java.io.FileNotFoundException: /storage/sdcard0/SC/599173: open failed: ENOENT (No such file or directory)
07-26 10:58:50.155: D/InstallationHelper(24528): Installation activity being destroyed.
PackageVerificationService がファイルを解析する前にファイルが削除されるため、「パッケージの解析に問題があります」というエラー ダイアログが表示され、APK がインストールされません。
onActivityResult() に渡されるパラメーターは、Package Installer または Verify App が選択されているかどうかに関係なく同じであるため、2 つを区別することはできません。
これは、APK のインストールを開始したアクティビティがファイナライズされて PackageVerificationService に渡されたため、onActivityResult() が時期尚早に呼び出されたために発生していますか? これを防ぐ方法はありますか?