【问题标题】:How to use PackageManager canRequestPackageInstalls in Android Oreo?如何在 Android Oreo 中使用 PackageManager canRequestPackageInstalls?
【发布时间】:2017-12-18 16:04:50
【问题描述】:

在我的应用清单中我已经声明了使用权限:

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

并在我的代码中检查我的应用是否可以从未知来源安装:

    public void reinstallApp(Activity activity, String pathname, int request_code)
    {
        if (activity.getPackageManager().canRequestPackageInstalls())
        {
            try
            {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(new File(pathname)), "application/vnd.android.package-archive");
                activity.startActivityForResult(intent, request_code);
            }
            catch (Exception e)
            {
                LogUtilities.show(this, e);
            }
        }
        else
        {
            activity.startActivity(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", activity.getPackageName()))));
        }
    }

但“activity.getPackageManager().canRequestPackageInstalls()”总是返回“false”,即使我在选择活动中检查了允许从未知来源安装。

有什么问题?

【问题讨论】:

    标签: android


    【解决方案1】:

    您必须先请求许可。为此,您必须从未知来源调用安装许可。我通过重新排列您的代码得到了答案。

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (!getPackageManager().canRequestPackageInstalls()) {
                    startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", getPackageName()))), 1234);
                } else {
                    callInstallProcess();
                }
            } else {
                callInstallProcess();
            }
    

    以上代码将在您的 onCreate() 中。您可以验证结果。

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1234 && resultCode == Activity.RESULT_OK) {
            if (getPackageManager().canRequestPackageInstalls()) {
                callInstallProcess();
            }
        } else {
            //give the error
        }
    }
    

    您的安装在 callInstallProcess() 中发生的位置;

            try
            {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(new File(pathname)), "application/vnd.android.package-archive");
                activity.startActivityForResult(intent, request_code);
            }
            catch (Exception e)
            {
                LogUtilities.show(this, e);
            }
    

    别忘了在 AndroidManifest.xml 中授予权限

        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    

    【讨论】:

    • 当我使用你的 callInstallProcess() 方法时,我得到了异常:exposed beyond app through Intent.getData()。我认为这是因为 .apk 文件包含在我的应用程序中,并且其他活动无法访问我的文件。
    • 注意:如果在片段中将 startActivityForResult(...) 替换为 getActivity()。 startActivityForResult(...) 获取 onActivityResult 中的好 requestCode
    • @ZdravkoDonev FileProvider 是你需要的。
    • 当我打电话给getPackageManager().canRequestPackageInstalls() 我得到Java.Lang.SecurityException: 'Need to declare android.permission.REQUEST_INSTALL_PACKAGES to call this api'
    【解决方案2】:

    here 所述,要使getPackageManager().canRequestPackageInstalls() 正常工作,您必须声明此权限

        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    

    在你的 AndroidManifest.xml 中,就像你已经做的那样,并且 - 很可能是你的问题的原因 - 在你的 build.gradle 或 AndroidManifest.xml 中声明 targetSdkVersion 为 26 或更高 (换句话说,您的应用必须针对 Android Oreo 或更高版本)。

    否则此方法将始终返回false,即使用户授予了权限。

    【讨论】:

    • 我正在处理一个旧项目,targetSdkVersion 成功了!
    • 相同。 targetSdkVersion 救了我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2023-02-18
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-26
    相关资源
    最近更新 更多