如何在应用程序中获取应用程序安装失败事件

How to get Application Installation failed event in app

我一直在使用 Action_Viewinstall apk 使用以下代码

Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
    intent.setDataAndType(Uri.fromFile(new File(location + "myAPK.apk")),
            "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

它会在设备中打开安装提示 window。现在用户可以安装或取消安装过程。

我只对用户单击安装包但由于某些原因安装失败可能是损坏的 apk 或不匹配的签名 apk 等感兴趣。

安装失败时如何捕获事件..我可以从ACTION_INSTALL_PACKAGE

中获取结果吗

我已经阅读了 System Broadcast Messages 但所有内容都用于添加或替换 Pacakge。

有什么线索吗?

引用 the documentation for ACTION_INSTALL_PACKAGE:

Output: If EXTRA_RETURN_RESULT, returns whether the install succeeded.

引用 the documentation for EXTRA_RETURN_RESULT:

Used as a boolean extra field with ACTION_INSTALL_PACKAGE or ACTION_UNINSTALL_PACKAGE. Specifies that the installer UI should return to the application the result code of the install/uninstall. The returned result code will be RESULT_OK on success or RESULT_FIRST_USER on failure.

因此,将 EXTRA_RETURN_RESULT 添加到您的 Intent,值为 true,然后使用 startActivityForResult()

使用 startActivityForResult 启动 Intent:

Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setDataAndType(Uri.fromFile(new File(location + "myAPK.apk")),
        "application/vnd.android.package-archive");
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
startActivityForResult(intent, MY_CONSTANT);

然后分析结果

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case ...
    }
}

我只想补充一下自己的心得和体会。我遇到了同样的问题。 如果你想获得结果,最好的方法是 Nano 和 CommonsWare 建议的方法。

我想强调的是,如果您的 apk 位于内部,您可能会遇到“解析包错误”的问题。我想记住你需要清单中的正确权限 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

但我注意到还需要添加 Intent.FLAG_GRANT_READ_URI_PERMISSION。 所以完整的示例代码可能像我的这样:

Uri fileUri = FileProvider.getUriForFile(getApplicationContext(),  BuildConfig.APPLICATION_ID + ".provider", currentFile);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setDataAndType(fileUri,"application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
startActivityForResult(intent, APK_INSTALL_CODE);

那我也会记住你,这个机制都是异步的,所以如果你需要知道结果才能继续,你需要等待它。 我不知道这是否是最好的方法,但它有效:

Uri fileUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", currentFile);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setDataAndType(fileUri,"application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
startActivityForResult(intent, APK_INSTALL_CODE);
while (WAIT_APK_INSTALL) {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == APK_INSTALL_CODE) {
        if (resultCode == 1) {
            WAIT_APK_INSTALL = false;
            //SUCCESS
        }
        else {
            //FAILED 
            //maybe it's needed crash the app like me. In my case the installation was necessary
            Intent intent = new Intent(getBaseContext(), ErrorActivity.class);
            intent.putExtra(GlobalStrings.INTENT_EXTRA_MESSAGE, getString(R.string.apk_installation_failed));
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application
            startActivity(intent);
            System.exit(1); // kill off the crashed app
        }
    }
}