系统权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- 相机-->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 存储权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 添加这个权限-->
<application
android:requestLegacyExternalStorage="true"
>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="项目包名.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!--设置共享路径的资源文件为上一步创建的文件-->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
xml文件下创建provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_path"
path="." />
<external-files-path
name="external_files_path"
path="." />
<files-path
name="internal_files_path"
path="." />
<cache-path
name="internal_cache_path"
path="." />
</paths>
Activity内使用
private String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
ActivityResultLauncher<Uri> takePictureResultLauncher;
ActivityResultLauncher<String> pickContactResultLauncher;
Uri contentUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
takePictureResultLauncher = registerForActivityResult(new ActivityResultContracts.TakePicture(), new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
if (result) {
ToastUtils.LogPrintf("保存成功");
Bitmap bitmap = getBitmap(contentUri);
iv_show.setImageBitmap(bitmap);
} else {
ToastUtils.LogPrintf("保存失败");
}
}
});
pickContactResultLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
ToastUtils.LogPrintf("相册回调");
Bitmap bitmap = getBitmap(result);
iv_show.setImageBitmap(bitmap);
}
});
}
//权限获取
@SuppressLint("CheckResult")
public void checkPermissions() {
new RxPermissions(MenuActivity.this).request(permissions).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Throwable {
boolean isAllGranted = false;
for (String s : permissions) {
if (ContextCompat.checkSelfPermission(MenuActivity.this, s) == PackageManager.PERMISSION_GRANTED) {
isAllGranted = true;
} else {
isAllGranted = false;
break;
}
}
if (aBoolean && isAllGranted) {
showPictureDialog();
} else {
ToastUtils.showShortToast("还有权限为被获取!");
permissionDialog();
}
}
});
}
private Bitmap getBitmap(Uri uri) {
if (uri == null) return null;
Bitmap bitmap = null;
try {
ContentResolver cr = this.getContentResolver();
bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}
private AlertDialog alertDialog;
private void permissionDialog() {
if (alertDialog == null) {
alertDialog = new AlertDialog.Builder(this).setTitle("提示信息").setMessage("当前应用缺少必要权限,该拍摄功能暂时无法使用。如若需要,请单击【设置】按钮前往设置中心进行权限授权。").setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelPermissionDialog();
Uri packageURI = Uri.parse("package:" + getPackageName());
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
startActivity(intent);
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelPermissionDialog();
}
}).create();
}
alertDialog.show();
}
private void cancelPermissionDialog() {
alertDialog.cancel();
}
/**
* 选择方式
*/
private void showPictureDialog() {
if (dialogUtils == null) {
dialogUtils = new DialogUtils(MenuActivity.this, new DialogUtils.PictureSelectListener() {
@SuppressLint("ObsoleteSdkInt")
@Override
public void selectCamera() {
String fileName = "image" + new Date().getTime() + ".jpg";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
contentUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
File imagePath = new File(getExternalFilesDir(null), fileName);
try {
//创建一个文件,等待输入流
boolean newFile = imagePath.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//android:authorities="项目包名.fileprovider" 与这个相同
contentUri = FileProvider.getUriForFile(MenuActivity.this, "项目包名.fileprovider", imagePath);
}
} else {
contentUri = Uri.fromFile(new File(getExternalCacheDir().getAbsolutePath(), fileName));
}
takePictureResultLauncher.launch(contentUri);
}
@Override
public void selectGallery() {
pickContactResultLauncher.launch("image/*");
}
});
}
dialogUtils.showSwitchPictureDialog();
}
DialogUtils类
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
public class DialogUtils {
private PictureSelectListener pictureSelectListener;
private Context context;
public DialogUtils(Context context, PictureSelectListener pictureSelectListener) {
this.pictureSelectListener = pictureSelectListener;
this.context = context;
}
public void showSwitchPictureDialog() {
AlertDialog dialog = new AlertDialog.Builder(context).setTitle("请选择").setItems(new String[]{"相机", "相册"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0://相机
pictureSelectListener.selectCamera();
dialog.dismiss();
break;
case 1://相册
pictureSelectListener.selectGallery();
dialog.dismiss();
break;
}
}
}).create();
dialog.show();
}
public interface PictureSelectListener {
void selectCamera();
void selectGallery();
}
}
//这个方法可以直接返回Bitmap但是图片很模糊 如果需要清晰的图片采用上面的方法
registerForActivityResult(new ActivityResultContracts.TakePicturePreview(), new ActivityResultCallback<Bitmap>() {
@Override
public void onActivityResult(Bitmap result) {
}
});