Android N 文件分享 - litonghui/TechBlog GitHub Wiki
对于软件分享功能,例如分享图片到微信好友或者朋友圈,Android提过几种方式,content://Uri 和 file://Uri通过Intent,最新的Android N 7.0 不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。关于文档中的描述。
解决方案,用FileProvider 的content:// Uri 代替
<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/provider_paths" />
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path path="." name="root" />
<files-path path="images/" name="my_images" />
<files-path path="audios/" name="my_audios" />
...
</paths>
paths中可以定义以下子节点
子节点 对应路径
files-path Context.getFilesDir()
cache-path Context.getCacheDir()
external-path Environment.getExternalStorageDirectory()
external-files-path Context.getExternalFilesDir(null)
external-cache-path Context.getExternalCacheDir()
生成 Content URI 方式如下:
File imagePath = new File(getContext().getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "com.mydomain.provider", newFile);
最后生成的 Content URI 为
content://com.domain.example.provider/images/default_image.jpg.
代码示例:
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
// 系统版本大于N的统一用FileProvider处理
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 将文件转换成content://Uri的形式
Uri photoURI = FileProvider.getUriForFile(activity,
activity.getPackageName()+ ".provider",
new File(photoPath));
// 申请临时访问权限
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
} else {
intent.addCategory(Intent.CATEGORY_DEFAULT);
Uri uri = Uri.parse("file://" + photoPath);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
activity.startActivityForResult(intent, requestCode);