700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 适配android7.0 miui Android调用相机 相册 裁剪(适配7.0和MIUI系统)

适配android7.0 miui Android调用相机 相册 裁剪(适配7.0和MIUI系统)

时间:2018-10-22 18:40:09

相关推荐

适配android7.0 miui Android调用相机 相册 裁剪(适配7.0和MIUI系统)

实现设置头像功能的具体步骤

创建实现功能的视图界面

设置权限(android 6.0以上需要动态申请)

选择拍照或者相册选择图片

选择图片后的进行裁剪(看需求)

裁剪完后对结果进行处理(设置到界面、上传到服务器等)

最后会贴上整个测试类的代码

1、创建实现功能的视图界面

类似如下所示,具体内容根据项目需求去实现

设置头像.png

设置方式.png

2、设置权限(6.0以上需要动态申请)

首先在AndroidManifest.xml中添加以下权限

6.0以上系统需要动态权限适配

//检查有无相机使用权限,没有的话动态申请

if (ActivityCompat.checkSelfPermission(TestActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

new RxPermissions(TestActivity.this).requestEach(Manifest.permission.CAMERA).subscribe(new Consumer() {

@Override

public void accept(Permission permission) throws Exception {

if (permission.granted) {

// 用户已经同意该权限

LogUtil.e(TAG, permission.name + " is granted.");

takePhoto();

} else if (permission.shouldShowRequestPermissionRationale) {

// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框

LogUtil.e(TAG, permission.name + " is denied. More info should be provided.");

Toast.makeText(TestActivity.this, "未能授予权限,部分功能可能不能正常使用", Toast.LENGTH_SHORT).show();

} else {

// 用户拒绝了该权限,并且选中『不再询问』

LogUtil.e(TAG, permission.name + " is denied.");

Toast.makeText(TestActivity.this, "请打开相机权限", Toast.LENGTH_SHORT).show();

//引导用户至设置页手动授权

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);

intent.setData(uri);

startActivity(intent);

}

}

});

} else {

takePhoto();

}

3、选择拍照或者相册选择图片

这里需要注意Android 7.0 以后对于共享文件路径的处理

/**

* 拍照

*/

private void takePhoto() {

//创建保存拍照的文件

outFile = new File(getExternalFilesDir(""), "head.jpg");

if (outFile.exists()) {

outFile.delete();

}

try {

//创建文件

outFile.createNewFile();

} catch (IOException e) {

e.printStackTrace();

Log.e("createXMLFileException", e.getMessage());

}

// 启动系统相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

// 判断7.0 android系统

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

//临时添加一个拍照权限

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

//通过FileProvider获取uri

outUri = FileProvider.getUriForFile(TestActivity.this,

"com.lin.fileProvider", outFile);

//将拍取的照片保存到指定URI

intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);

} else {

outUri = Uri.fromFile(outFile);

intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);

}

startActivityForResult(intent, PHOTO_PZ);

}

/**

* 从相册选择

*/

private void selectPhoto() {

//调用系统图库,选择图片

Intent intent = new Intent(Intent.ACTION_PICK, null);

intent.setDataAndType(

MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");

//返回结果和标识

startActivityForResult(intent, PHOTO_TK);

}

4、选择图片后的进行裁剪(看需求)

一般用作头像的图片不宜太大,最好作适当的裁剪

这里也涉及到FileProvider(应用间共享文件),还有对MIUI系统的适配,具体看注释

/**

* 裁剪照片

*

* @param uri

*/

private void cutPhoto(Uri uri) {

//裁剪完成后保存的文件

cutOutFile = new File(getExternalFilesDir(""), "cutHead.jpg");

if (cutOutFile.exists()) {

cutOutFile.delete();

}

try {

//创建文件

cutOutFile.createNewFile();

} catch (IOException e) {

e.printStackTrace();

Log.e("createXMLFileException", e.getMessage());

}

Log.e("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);

// 裁剪后输出图片的尺寸大小

intent.putExtra("outputX", 320);

intent.putExtra("outputY", 320);

//设置裁剪完保存的URI

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

//开启临时权限

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

//重点:针对7.0以上的操作

cutOutUri = FileProvider.getUriForFile(TestActivity.this,

"com.lin.fileProvider", cutOutFile);

intent.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, cutOutUri));

} else {

cutOutUri = Uri.parse("file://" + "/" + cutOutFile.getPath());

}

intent.putExtra(MediaStore.EXTRA_OUTPUT, cutOutUri);

intent.putExtra("return-data", false);

/**

* return-data

* 这个属性决定我们在 onActivityResult 中接收到的是什么数据,

* 如果设置为true 那么data将会返回一个bitmap

* 如果设置为false,则会将图片保存到本地并将对应的uri返回,当然这个uri得有我们自己设定。

* 系统裁剪完成后将会将裁剪完成的图片保存在我们所这设定这个uri地址上。我们只需要在裁剪完成后直接调用该uri来设置图片,就可以了。

*/

//intent.putExtra("return-data", true); // 重点:小米的系统使用这个会使返回数据为null,所以设置为false用uri来获取数据

//图片输出格式

intent.putExtra("outputFormat", pressFormat.JPEG.toString());

//头像识别 会启动系统的拍照时人脸识别

intent.putExtra("noFaceDetection", true);

startActivityForResult(intent, PHOTO_CLIP);

}

5、裁剪完后对结果进行处理(设置到界面、上传到服务器等)

在onActivityResult方法中根据请求码对拍照、相册选择、裁剪完后的结果进行处理,大致流程如下图

image.png

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK) {

switch (requestCode) {

case PHOTO_PZ:

cutPhoto(outUri);

break;

case PHOTO_TK:

//获取图库结果,执行裁剪

cutPhoto(data.getData());

break;

case PHOTO_CLIP:

//1.裁剪时,这样设置 cropIntent.putExtra("return-data", true); 处理方案如下

// if (data != null) {

// Bundle bundle = data.getExtras();

// if (bundle != null) {

// Bitmap bitmap = bundle.getParcelable("data");

// ivHead.setImageBitmap(bitmap);

// // 把裁剪后的图片保存至本地

// FileUtils.writeImageToFile("cutHead.jpg", bitmap);

// }

// }

//2.cropIntent.putExtra("return-data", false);处理方案如下

//裁剪完成后的操作,上传至服务器或者本地设置

//将Uri图片转换为Bitmap

try {

Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(cutOutUri));

ivHead.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

LogUtil.e(e.toString());

}

break;

default:

break;

}

}

}

这里贴上整个测试类的代码

/**

* @author Lin

* @date /5/10

* @description 选择头像功能

*/

public class TestActivity extends BaseActivity {

private ImageView iconBack;

private RelativeLayout rlHead;

private CircleImageView ivHead;

private SelectPictureDialog dialog;

private Uri outUri;

private Uri cutOutUri;

//拍照保存的文件

private File outFile;

//裁剪完保存的图片

private File cutOutFile;

//图库

private static final int PHOTO_TK = 0;

//拍照

private static final int PHOTO_PZ = 1;

//裁剪

private static final int PHOTO_CLIP = 2;

@Override

protected int getLayoutId() {

return R.layout.activity_test;

}

@Override

protected void initView() {

iconBack = findViewById(R.id.icon_back);

rlHead = findViewById(R.id.rl_head);

ivHead = findViewById(R.id.iv_head);

}

@Override

protected void initData(Bundle savedInstanceState) {

}

@Override

protected void setEvent() {

rlHead.setOnClickListener(this);

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.rl_head:

dialog = new SelectPictureDialog(this, R.style.MyAppDialog);

dialog.show();

dialog.setListener(new SelectPictureDialog.OnSelectListener() {

@Override

public void onClickTakePhoto() {

dialog.dismiss();

if (ActivityCompat.checkSelfPermission(TestActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

new RxPermissions(TestActivity.this).requestEach(Manifest.permission.CAMERA).subscribe(new Consumer() {

@Override

public void accept(Permission permission) throws Exception {

if (permission.granted) {

// 用户已经同意该权限

LogUtil.e(TAG, permission.name + " is granted.");

takePhoto();

} else if (permission.shouldShowRequestPermissionRationale) {

// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框

LogUtil.e(TAG, permission.name + " is denied. More info should be provided.");

Toast.makeText(TestActivity.this, "未能授予权限,部分功能可能不能正常使用", Toast.LENGTH_SHORT).show();

} else {

// 用户拒绝了该权限,并且选中『不再询问』

LogUtil.e(TAG, permission.name + " is denied.");

Toast.makeText(TestActivity.this, "请打开相机权限", Toast.LENGTH_SHORT).show();

//引导用户至设置页手动授权

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);

intent.setData(uri);

startActivity(intent);

}

}

});

} else {

takePhoto();

}

}

@Override

public void onClickAlbum() {

dialog.dismiss();

selectPhoto();

}

@Override

public void onClickCancel() {

//不用操作

}

});

break;

default:

break;

}

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK) {

switch (requestCode) {

case PHOTO_PZ:

cutPhoto(outUri);

break;

case PHOTO_TK:

//获取图库结果,执行裁剪

cutPhoto(data.getData());

break;

case PHOTO_CLIP:

//1.裁剪时,这样设置 cropIntent.putExtra("return-data", true); 处理方案如下

// if (data != null) {

// Bundle bundle = data.getExtras();

// if (bundle != null) {

// Bitmap bitmap = bundle.getParcelable("data");

// ivHead.setImageBitmap(bitmap);

// // 把裁剪后的图片保存至本地

// FileUtils.writeImageToFile("cutHead.jpg", bitmap);

// }

// }

//2.cropIntent.putExtra("return-data", false);处理方案如下

//裁剪完成后的操作,上传至服务器或者本地设置

//将Uri图片转换为Bitmap

try {

Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(cutOutUri));

ivHead.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

LogUtil.e(e.toString());

}

break;

default:

break;

}

}

}

/**

* 从相册选择

*/

private void selectPhoto() {

//调用系统图库,选择图片

Intent intent = new Intent(Intent.ACTION_PICK, null);

intent.setDataAndType(

MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");

//返回结果和标识

startActivityForResult(intent, PHOTO_TK);

}

/**

* 拍照

*/

private void takePhoto() {

//创建保存拍照的文件

outFile = new File(getExternalFilesDir(""), "head.jpg");

if (outFile.exists()) {

outFile.delete();

}

try {

//创建文件

outFile.createNewFile();

} catch (IOException e) {

e.printStackTrace();

Log.e("createXMLFileException", e.getMessage());

}

// 启动系统相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

// 判断7.0 android系统

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

//临时添加一个拍照权限

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

//通过FileProvider获取uri

outUri = FileProvider.getUriForFile(TestActivity.this,

"com.lin.fileProvider", outFile);

//将拍取的照片保存到指定URI

intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);

} else {

outUri = Uri.fromFile(outFile);

intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);

}

startActivityForResult(intent, PHOTO_PZ);

}

/**

* 裁剪照片

*

* @param uri

*/

private void cutPhoto(Uri uri) {

//裁剪完成后保存的文件

cutOutFile = new File(getExternalFilesDir(""), "cutHead.jpg");

if (cutOutFile.exists()) {

cutOutFile.delete();

}

try {

//创建文件

cutOutFile.createNewFile();

} catch (IOException e) {

e.printStackTrace();

Log.e("createXMLFileException", e.getMessage());

}

Log.e("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);

// 裁剪后输出图片的尺寸大小

intent.putExtra("outputX", 320);

intent.putExtra("outputY", 320);

//设置裁剪完保存的URI

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

//开启临时权限

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

//重点:针对7.0以上的操作

cutOutUri = FileProvider.getUriForFile(TestActivity.this,

"com.lin.fileProvider", cutOutFile);

intent.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, cutOutUri));

} else {

cutOutUri = Uri.parse("file://" + "/" + cutOutFile.getPath());

}

intent.putExtra(MediaStore.EXTRA_OUTPUT, cutOutUri);

intent.putExtra("return-data", false);

/**

* return-data

* 这个属性决定我们在 onActivityResult 中接收到的是什么数据,

* 如果设置为true 那么data将会返回一个bitmap

* 如果设置为false,则会将图片保存到本地并将对应的uri返回,当然这个uri得有我们自己设定。

* 系统裁剪完成后将会将裁剪完成的图片保存在我们所这设定这个uri地址上。我们只需要在裁剪完成后直接调用该uri来设置图片,就可以了。

*/

//intent.putExtra("return-data", true); // 重点:小米的系统使用这个会使返回数据为null,所以设置为false用uri来获取数据

//图片输出格式

intent.putExtra("outputFormat", pressFormat.JPEG.toString());

//头像识别 会启动系统的拍照时人脸识别

intent.putExtra("noFaceDetection", true);

startActivityForResult(intent, PHOTO_CLIP);

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。