一、配置拍照和读写权限
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
二、手动申请权限
implementation 'com.permissionx.guolindev:permissionx:1.4.0'
1、手动申请读写,拍照权限
PermissionX.init(this)
.permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA)
.request((allGranted, grantedList, deniedList) -> {
if(allGranted){
}
});
2、手动申请文件管理权限
if (Build.VERSION.SDK_INT >= 30 && !Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
三、Manifest中配置queries(解决resolveActivity为null)
<application
...>
...
</application>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE"/>
</intent>
<intent>
<action android:name="android.media.action.VIDEO_CAPTURE"/>
</intent>
</queries>
四、Manifest中配置provider
<application
...>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="你的package包名.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
tools:replace="android:resource"
android:resource="@xml/file_paths" />
</provider>
</application>
五、配置file_paths文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!--目录为:Environment.getExternalStorageDirectory()-->
<external-path
name="download"
path="Download" />
<external-path name="external_files" path="." />
</paths>
六、调用相机(FileUtil类)
public class FileUtil {
public static String takePhoto(Activity activity) { //照相
//调用相机
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//用来打开相机的Intent
if(takePhotoIntent.resolveActivity(activity.getPackageManager())!=null){
//Constant.PIC_DIR = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download"
File file=new File(Constant.PIC_DIR);
if(!file.exists())file.mkdir();
// 保存路径
file = getFile(Constant.PIC_DIR, System.currentTimeMillis()+ ".jpg");
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//设置7.0以上共享文件,分享路径定义在xml/file_paths.xml
uri = FileProvider.getUriForFile(activity, "你的package包名.fileprovider", file);
} else {
// 7.0以下,共享文件
uri = Uri.fromFile(file); // 将路径转换为Uri对象
}
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 表示录制完后保存的录制,如果不写,则会保存到默认的路径,在onActivityResult()的回调,通过intent.getData中返回保存的路径
//Constant.REQ_CODE为任意整数,用于回调
activity.startActivityForResult(takePhotoIntent, Constant.REQ_CODE); // 跳转
return file.getAbsolutePath();
}
return null;
}
public static File getFile(String filePath, String fileName){
File dir = new File(filePath);
if (!dir.exists()){//如果不存在,进行创建
dir.mkdirs();
}
File soundFile = new File(dir,fileName);
if (!soundFile.exists()){
try {
soundFile.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
}
return soundFile;
}
//通过URI获取file
public static File getFileFromContentUri(Uri contentUri, Context context) {
if (contentUri == null) {
return null;
}
File file = null;
String filePath;
String[] projection = { MediaStore.Files.FileColumns.DATA };
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(contentUri, projection, null,
null, null);
if (cursor != null && cursor.moveToFirst()) {
filePath = cursor.getString(0);
cursor.close();
if (!filePath.isEmpty()) {
file = new File(filePath);
}
}
return file;
}
}
七、处理拍照 / 本地图片回调(Activity类)
private String curSelectPhoto = "";
//启动相机
private void takePhoto(){
curSelectPhoto = FileUtil.takePhoto(this);
}
//从本地获取图片
private void getPhotoFromLocal(){
Intent i = new Intent();
i.setAction(Intent.ACTION_PICK);
i.setType("image/*");
//Constant.PHOTO_LOCAL为任意整数,用于获取本地图片回调
startActivityForResult(i, Constant.PHOTO_LOCAL);
}
@Override
public void onActivityResult(final int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if(resultCode==RESULT_OK){
ThreadManager.getThreadPool().exeute(() -> {
File file=null;
if(requestCode==Constant.REQ_CODE){ //拍照
file = new File(curSelectPhoto);
}else{ //从本地上传
Uri uri = data.getData(); //图片的保存路径
file = FileUtil.getFileFromContentUri(uri,getApplicationContext());
}
});
}
}