美文网首页
关于APP内部进行升级下载好apk后无法正确地跳转到安装界面,抛

关于APP内部进行升级下载好apk后无法正确地跳转到安装界面,抛

作者: 濺m | 来源:发表于2019-08-05 17:39 被阅读0次

    在Android7.0上,使用下面的代码进行跳转到apk安装的页面

            final File file = new File(filePath);
            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri data = Uri.fromFile(file);
            intent.setDataAndType(data, "application/vnd.android.package-archive");
            context.startActivity(intent);
    

    会抛出下面的异常FileUriExposedException

    android.os.FileUriExposedException: “你的项目升级下载的apk的存放的地址”exposed beyond app through Intent.getData()
    

    是因为随着Android版本的升级,对用户的数据的保护越来越高。
    同时,Android提供了FileProvider来实现app间的数据共享。

    解决方法
    1、声明一个FileProvider

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="你的包名">
        <application
            ...>
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="你的包名+.fileprovider"
                android:grantUriPermissions="true"
                android:exported="false">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
            ...
        </application>
    </manifest>
    
    参数 说明 备注
    name FileProvider组件的完整类名 android.support.v4.content.FileProvider
    authorities 域名 为了保证唯一性,最好使用包名+fileprovider
    grantUriPermissions 是否允许你可以对文件授予临时权限 true
    exported 是否需要暴露它 false

    2、添加file_paths.xml文件
    在res/xml的路径下创建file_paths.xml的文件,文件内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <files-path name="name" path="path" />
        <cache-path name="name" path="path" />
        <external-path name="name" path="path" />
        <external-files-path name="name" path="path" />
        <external-cache-path name="name" path="path" />
    </paths>
    //name=随便的命名,没特殊要求。path=该路径的具体的文件内容,如果是全部的文件就填写path="."
    
    参数 说明
    files-path 对应的是Context.getFilesDir,返回的是/data/data/“你的项目名称”/files
    cache-path 对应的是getCacheDir,返回的是/data/data/“你的项目名称”/cache
    external-path 对应的是Environment.getExternalStorageDirectory,返回的是/storage/emulated/0
    external-files-path 对应的是Context.getExternalFilesDir(null)返回的是/storage/emulated/0/Android/data/“你的项目名称”/files
    external-cache-path 对应的是Context.getExternalFilesDir(null)返回的是/storage/emulated/0/Android/data/“你的项目名称”/cache

    3、installapk的代码改成

            final File file = new File(filePath);
            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri data;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                data = FileProvider.getUriForFile(mApp,"声明fileprovider时的android:authorities",file);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }else {
                data = Uri.fromFile(file);
            }
            //不添加这个会抛出Caused by: android.util.AndroidRuntimeException: 
            //Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. 
            //Is this really what you want?
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
            intent.setDataAndType(data, "application/vnd.android.package-archive");
            context.startActivity(intent);
    

    4、添加请求安装app的权限

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

    5、最后有的机型可能需要再打开外部的来源的安装。

    相关文章

      网友评论

          本文标题:关于APP内部进行升级下载好apk后无法正确地跳转到安装界面,抛

          本文链接:https://www.haomeiwen.com/subject/sswmdctx.html