android 版本更新7.0,8.0 兼容

本文介绍了在Android 7.0.0到8.0.0之间,更新和下载应用时遇到的问题及解决方案。对于7.0.0以上版本,需在清单文件和res-xml-file-paths.xml中配置provider,同时在安装代码中检查权限。对于8.0.0及以上版本,由于权限问题,需在主配置文件添加权限,并在fragment中正确请求权限。文章还提供了解决小米手机更新失败的参考链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.情况:在android版本>=7.0.0 && android 版本<8.0.0 更新下载app失败:

解决:配置provider

1.清单文件:

       <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.xx.xxx.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

2.res-xml-file-paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path path="" name="download" />
    </paths>
</resources>

 3.安装代码:

  /**
     * 通过隐式意图调用系统安装程序安装APK
     */
    public static void install2(Context context) {
        File file = new File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "xxx.apk");
        Intent intent = new Intent(Intent.ACTION_VIEW);
        // 由于没有在Activity环境下启动Activity,设置下面的标签
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if(Build.VERSION.SDK_INT>=24) { //判读版本是否在7.0以上

            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure();

            //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
            Uri apkUri = FileProvider.getUriForFile(context, "com.xx.xxx.fileprovider", file);
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        }else{
            intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

2.情况:android 版本>8.0.0 更新下载app失败:

报错:

 java.lang.SecurityException: Need to declare android.permission.REQUEST_INSTALL_PACKAGES to call this api

 

解决:  缺失权限,在主配置文件添加,然后代码里面添加,没有的话去跳转用户手动允许。

之前是fragment的权限请求写错了,写成了activity的请求方式:

1.fragment中请求:

UpdateAppDialogFragment.this.requestPermissions( new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 10010);

2.activity中请求:

ActivityCompat.requestPermissions( new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 10010);

主要代码:

1.判断是否是8.0以上的android手机,如果是的话,判断权限

public void checkIsAndroidO() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    //>=26
            boolean b = getActivity().getPackageManager().canRequestPackageInstalls();
            if (b) {
                download(); //安装apk
                Toast.makeText(getActivity(),"安装apk"+b+b,Toast.LENGTH_LONG).show();
            } else {
                //请求安装未知应用来源的权限
                Toast.makeText(getActivity(),"请求安装未知应用来源的权限:"+b,Toast.LENGTH_LONG).show();
                UpdateAppDialogFragment.this.requestPermissions( new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 10010);
            }
        } else {
            Toast.makeText(getActivity(),"安装apk",Toast.LENGTH_LONG).show();
            download(); //安装apk
        }
    }

2.权限请求回调:

   @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        LogUitl.e("===requestCode==:"+requestCode);
        Toast.makeText(getActivity(),"requestCode:"+requestCode,Toast.LENGTH_LONG).show();
        switch (requestCode) {
            case 10010:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    download(); //安装apk
                } else {
                    Uri packageURI = Uri.parse("package:"+getActivity().getPackageName());//设置包名,可直接跳转当前软件的设置页面
                    Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
                    startActivityForResult(intent, 10012);
                }
                break;

            case 4:
                LogUitl.e("======onRequestPermissionsResult======更新权限回调========");
                LogUitl.e("======length======更新权限回调========" + grantResults.length);
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    download();
                } else {
                    DialogUtil.showPermissionDialogFragment(getFragmentManager(), "存储");
                }
        }
    }

3.用户授权之后,继续判断是否可以安装:

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 10012:
                checkIsAndroidO();
                break;

        }
    }

4.清单配置的权限:

    <!--8.0 android安装-->
    <uses-permission android:name="android.REQUEST_INSTALL_PACKAGES.GET_TASKS" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

参考:

https://blog.youkuaiyun.com/u012483116/article/details/73798383

二:使用外链更新:

 Intent intent = new Intent();
                intent.setData(Uri.parse(downloadDir));//Url 就是你要打开的网址
                intent.setAction(Intent.ACTION_VIEW);
                this.startActivity(intent); //启动浏览器

1.测试的手机:

2.小米 Mi 4LTE更新不成功,报错,不知道怎么解决。

10-25 19:49:51.448 5272-5272/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: com.android.packageinstaller, PID: 5272
                                                 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.packageinstaller/com.android.packageinstaller.PackageInstallerActivity}: java.lang.NullPointerException: Attempt to read from field 'int android.content.pm.ApplicationInfo.privateFlags' on a null object reference
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2517)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2577)
                                                     at android.app.ActivityThread.access$1100(ActivityThread.java:156)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                     at android.os.Looper.loop(Looper.java:157)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5696)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:746)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
                                                  Caused by: java.lang.NullPointerException: Attempt to read from field 'int android.content.pm.ApplicationInfo.privateFlags' on a null object reference
                                                     at com.android.packageinstaller.PackageInstallerActivity.getOriginatingUid(PackageInstallerActivity.java:625)
                                                     at com.android.packageinstaller.PackageInstallerActivity.onCreate(PackageInstallerActivity.java:553)
                                                     at android.app.Activity.performCreate(Activity.java:6362)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2470)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2577) 
                                                     at android.app.ActivityThread.access$1100(ActivityThread.java:156) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                     at android.os.Looper.loop(Looper.java:157) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:5696) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:746) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值