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

3

我一直在使用 Action_View 应用以下代码来通过 安装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);

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

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

当安装失败时,我如何捕获事件?我能从 ACTION_INSTALL_PACKAGE 中获取结果吗?

我已经阅读了 系统广播消息,但所有这些都用于添加或替换软件包。

有什么线索吗?


你尝试过使用startActivityForResult启动进程,然后在onActivityResult中分析回调以处理失败的情况吗? - nano
@nano 在打开安装提示窗口后立即触发 OnActivityResult,而不等待用户响应。 - Rajeev Kumar
请再试一次,删除 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - nano
可能是ACTION_INSTALL_PACKAGE的重复问题。 - Yazan
3个回答

6

引用"ACTION_INSTALL_PACKAGE"的文档:

输出:如果使用EXTRA_RETURN_RESULT,则返回安装是否成功。

引用“EXTRA_RETURN_RESULT”的文档:

作为布尔类型的额外字段,与ACTION_INSTALL_PACKAGE或ACTION_UNINSTALL_PACKAGE一起使用。指定安装程序UI应将安装/卸载的结果代码返回给应用程序。返回的结果代码将在成功时为RESULT_OK,失败时为RESULT_FIRST_USER。

因此,请将“EXTRA_RETURN_RESULT”添加到您的“Intent”中,并赋予值“true”,然后使用“startActivityForResult()”。


4

使用 startActivityForResult 启动意图:

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 ...
    }
}

0

我只想添加自己的考虑和经验。我曾遇到过同样的问题。 如果你想得到最好的结果,最好按照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
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接