android 7.0 8.0 安装apk适配 FileUriExposedException

public static void installApk(Context context, File file) {  
    Intent intent = new Intent(Intent.ACTION_VIEW);  
    Uri data = Uri.fromFile(file);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(data, "application/vnd.android.package-archive");  
    context.startActivity(intent);  
} 

Android 7.0
7.0以上会报FileUriExposedException. 使用FileProvider解决
FileProvider官方文档
https://developer.android.google.cn/reference/android/support/v4/content/FileProvider.html

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

这里最好不直接用android.support.v4.content.FileProvider,新建一个MyProvider 继承android.support.v4.content.FileProvider,以防与其他lib定义的冲突。

res/xml 目录下新建file_paths.xml文件,xml文件夹不存在就创建.

<paths>  
    <external-cache-path name="my_download" path="download/" />  
</paths> 

external-cache-path 对应Context.getExternalCacheDir(),也就是我的apk文件是放在
Context.getExternalCacheDir()/download文件夹下面的.
其他还(复制过来,直接看文档比较好)

The <paths> element must contain one or more of the following child elements:

<files-path name="name" path="path" />
Represents files in the files/ subdirectory of your app's internal storage area. This subdirectory is the same as the value returned by Context.getFilesDir().
<cache-path name="name" path="path" />
Represents files in the cache subdirectory of your app's internal storage area. The root path of this subdirectory is the same as the value returned by getCacheDir().
<external-path name="name" path="path" />
Represents files in the root of the external storage area. The root path of this subdirectory is the same as the value returned by Environment.getExternalStorageDirectory().
<external-files-path name="name" path="path" />
Represents files in the root of your app's external storage area. The root path of this subdirectory is the same as the value returned by Context#getExternalFilesDir(String) Context.getExternalFilesDir(null).
<external-cache-path name="name" path="path" />
Represents files in the root of your app's external cache area. The root path of this subdirectory is the same as the value returned by Context.getExternalCacheDir().
<external-media-path name="name" path="path" />
Represents files in the root of your app's external media area. The root path of this subdirectory is the same as the value returned by the first result of Context.getExternalMediaDirs().
Note: this directory is only available on API 21+ devices.

然后代码中判断版本

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
        // "com.csdn.fileprovider"即manifest中的authorities  
        data = FileProvider.getUriForFile(context, "com.csdn.fileprovider", file);  
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  //授权
    } else {  
        data = Uri.fromFile(file);  
    }  

Android 8.0
8.0开始安装未知来源的apk,需要用户设置授权.
声明权限

加上一些判断

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !context.getPackageManager().canRequestPackageInstalls()){
            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
            activity.startActivityForResult(intent);
        }else{
        //install
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值