Refrence:
Android 调用系统相机拍照适配主要经历了 6.0 7.0 10和11这几个大版本:
- 6.0主要是处理运行时权限
- 7.0为FileProvider 文件共享
- 10和11则是分区存储
基本步骤
一、 AndroidManifest.xml中配置provider
<application
......
<provider
android:name="androidx.core.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_paths" />
</provider>
</application>
其中:
- android:authorities 表示授权者,这里的格式一般是[appId].fileprovider
- android:exported 只能为false
- android:grantUriPermissions="true" 表示授权Uri权限 ,且必须为true
- meta-data 里设置指定的文件目录,为引用provider_paths文件
二、 新增file_paths.xml
标签 | 代码 | 路径 |
---|---|---|
<cache-path/> | context.getCacheDir() | /data/data/<包名>/cache |
<files-path/> | context.getFilesDir() | /data/data/<包名>/cache |
<external-path/> | Environment.getExternalStorageDirectory() | /storage/emulate/0 |
<external-cache-path> | context.getExternalCacheDir() | /storage/emulate/0/Android/data/<包名>/cache |
<external-files-path> | context.getExternalFilesDir() | /storage/emulate/0/Android/data/<包名>/files |
<external-media-path> | context.getExternalMediaDirs() | /storage/emulate/0/Android/data/<包名> |
常用到的为 external-path 和 external-files-path,name和path按照自己需求编写
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="externalPath"
path="./000" />
</paths>
上述示例意思是,external-path标签指向的路径后path中指向的文件/文件夹拥有被访问权限,即 /storage/emulate/0/000
这个路径拥有被访问的权限。
三、 通过intent调用系统相机
简单示例:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File outFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/000/" + System.currentTimeMillis() + ".jpg");
Uri uri = FileProvider.getUriForFile(this, getPackageName(getApplicationContext()) + ".fileProvider", outFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(intent);