Android7.0做了一些权限更改,为了提高私有文件的安全性,面向 Android 7.0 或更高版本的应用私有目录被限制访问。此设置可防止私有文件的原数据泄漏,同事Android7.0如果传递 file:// URI 会触发 FileUriExposedException 异常。适配Android7.0 FileProvider的步骤如下:
AndroidManifest.xml清单文件的修改
<manifest>
......
<application>
<!-- Android7.0适配 -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
</application>
</manifest>
${applicationId}.FileProvider 中 applicationId 为gradle项目写法,可修改为自己的包名。
file_provider_paths.xml文件
<paths>
<!-- 国内由于rom比较多,会产生各种路径,比如华为的/system/media/,以及外置sdcard -->
<root-path
name="root"
path="." />
<!-- 代表的根目录Context.getFilesDir() -->
<files-path
name="files"
path="." />
<!-- 代表的根目录getCacheDir() -->
<cache-path
name="cache"
path="." />
<!-- 代表的根目录Environment.getExternalStorageDirectory() -->
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<external-cache-path
name="external_cache"
path="." />
<external-path
name="external_storage_root"
path="." />
<external-path
name="external_storage_files"
path="." />
<external-path
name="external_storage_cache"
path="." />
</paths>
代码中调用
/**
* 安装APK
*
* @param context
* @return
*/
public static void installApk(Context context, String apkPath) {
if (context == null || TextUtils.isEmpty(apkPath)) return;
File file = new File(apkPath);
if (!file.exists() || !file.isFile() || file.length() <= 0) return;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//判读版本是否在7.0以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//provider authorities
Uri apkUri = FileProvider.getUriForFile(context, getPackageInfo(context).packageName + ".FileProvider", file);
//Granting Temporary Permissions to a 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);
}