一,静态权限申请
AndroidManifest.xml 内操作
<!--读写内存块权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--调用相机权限-->
<uses-permission android:name="android.permission.CAMERA" />
......
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.hxd.pictest.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
在 项目 res 下面创建 xml 文件夹,xml文件夹下创建 file_paths.xml 文件,文件内写如下
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
二、拍照和调取相册
从相册中获取:
public void gallery(View view) {
// 激活系统图库,选择一张图片
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
this.startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
}
从相机中获取:
public void camera() {
//所有存储在getExternalFilesDir()提供的目录中的文件会在用户卸载你的app后被删除
cameraSavePath = new File(getExternalFilesDir(null).getPath() + "/" + System.currentTimeMillis() + ".jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//第二个参数为 包名.fileprovider
uri = FileProvider.getUriForFile(MainActivity.this, "com.example.hxd.pictest.fileprovider", cameraSavePath);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(cameraSavePath);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, PHOTO_REQUEST_CAMERA);
}
动态权限申请:
private void startCamera(View view)
{
if (hasPermission(this, new String(Manifest.permission.CAMERA))){
// 执行拍照的逻辑
camera();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
}
}
//检查权限是否已获取
public static boolean hasPermission(@NonNull Context context, @NonNull String permission) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
|| PermissionChecker.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
//通过requestCode来识别是否同一个请求
if (requestCode == PERMISSION_REQUEST_CODE){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//用户同意,执行操作
// initScan();
camera();
}else{
//如果没有授权的话,可以给用户一个友好提示
Toast.makeText(this, "用户拒绝了拍照权限", Toast.LENGTH_SHORT).show();
}
}
}
三、照片剪辑处理
private void crop(Uri uri) {
// 裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
// intent.putExtra("aspectX", 1);
// intent.putExtra("aspectY", 1);
if(android.os.Build.MODEL.contains("HUAWEI"))
{//华为特殊处理 不然会显示圆
intent.putExtra("aspectX", 9998);
intent.putExtra("aspectY", 9999);
}
else
{
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
}
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
// 图片格式
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);// true:不返回uri,false:返回uri
//在7.0系统上还需要添加intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);这样的一句话,
// 表示对目标应用临时授权该Uri所代表的文件,否则会报无法加载此图片的错误。
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, PHOTO_REQUEST_CUT);
}
四、图片显示处理
Android的相机应用会把拍好的照片编码为缩小的Bitmap,使用extra value的方式添加到返回的Intent当中,并传送给onActivityResult(),对应的Key为"data":
Note: 这张从"data"
中取出的缩略图适用于作为图标,但其他作用会比较有限。而处理一张全尺寸图片需要做更多的工作。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
配合剪辑处理使用:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PHOTO_REQUEST_GALLERY) {
if (data != null) {
// 得到图片的全路径
Uri uri = data.getData();
crop(uri);
}
} else if (requestCode == PHOTO_REQUEST_CAMERA) {
if (hasSdcard()) {
tempFile = new File(getExternalFilesDir(null), PHOTO_FILE_NAME);
crop(uri);
}else {
Toast.makeText(MainActivity.this, "未找到存储卡,无法存储照片!", Toast.LENGTH_LONG).show();
}
} else if (requestCode == PHOTO_REQUEST_CUT) {
try {
Bitmap bitmap = data.getParcelableExtra("data");
mImageView.setImageBitmap(bitmap);
tempFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
--------------详细项目地址--------------
主要相机获得需要动态权限见文章Android 动态获取权限
相机的获取参考Android调用相册、相机(兼容6.0、7.0、8.0
文件夹的创建参考Android — 创建文件及文件夹