接到一个新需求,用户可以自己跟换自己的头像
1.可以使用相机或是选择照片
2.剪切头像
3.保存头像到本地
实现步骤:
1.我们首先提供用户选择是相机还是相册:
使用alterDialog让用户选择,相机的没有实现:
private fun choiceHeadImage() {
val builder = AlertDialog.Builder(mContext)
builder.setSingleChoiceItems(arrayOf("选择图片", "恢复默认头像"), -1, object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, which: Int) {
Log.e(TAG, "-----------which >>>>${which}")
when (which) {
0 -> {
//选择图片
if (android.os.Build.VERSION.SDK_INT >= 23) {
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
} else {
choseHeadImageFromGallery()
}
}
1 -> {
//删除照片
deleteHeadFile("$SAVE_PIC_PATH$HeadImageName")
}
}
dialog.dismiss()
}
})
builder.show()
}
2.如何跳转至相册:
/* 请求识别码 */
private val CODE_GALLERY_REQUEST = 0xa0;
private val CODE_CAMERA_REQUEST = 0xa1;
// 从本地相册选取图片作为头像
private fun choseHeadImageFromGallery() {
// 设置文件类型
val intent = Intent()
intent.setAction(Intent.ACTION_PICK)
intent.setType("image/*")
startActivityForResult(intent, CODE_GALLERY_REQUEST)
}
3.如何跳转至相机:
//跳转至相机,未实现
4.接收选择回来的照片
在Activity中接收返回的照片信息;
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
//开启指纹登录成功,返回修改指纹登录状态,本地保存状态
when (requestCode) {
CODE_GALLERY_REQUEST -> {
if (Activity.RESULT_OK == resultCode) {
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver,resultData?.data)
sign_head_iv.setImageBitmap(bitmap)
}
}
CODE_CAMERA_REQUEST -> {
}
}
}
此处遇到一个问题,就是如果将在相册中取回的Bitmap直接显示ImageView里面,这是照片会出现逆时针旋转了45度的情况,所以,一般在取回Bitmap之后,我们需要在使用系统的裁剪,这样裁剪后的照片就正常了;
5.进行裁剪
public static Intent cropImageUri(Uri orgUri, Uri desUri, int aspectX, int aspectY, int width, int height) {
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(orgUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("outputX", width);
intent.putExtra("outputY", height);
intent.putExtra("scale", true);
//将剪切的图片保存到目标Uri中
intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri);
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
return intent;
}
在Activity的onActivityResult的方法中:
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
//开启指纹登录成功,返回修改指纹登录状态,本地保存状态
when (requestCode) {
CODE_GALLERY_REQUEST -> {
if (Activity.RESULT_OK == resultCode) {
val newUri = Uri.parse(PhotoUtil.getPath(resultData?.getData()));
onCrop(newUri)
}
}
}
}
fun onCrop(imageUri: Uri) {
val cropImageUri = Uri.fromFile(fileCropUri);
val intent = PhotoUtil.cropImageUri(imageUri, cropImageUri, 1, 1, outputX, outputY)
startActivityForResult(intent, CODE_CORP_REQUEST)
}
6.保存裁剪后的照片
关于保存照片,我尝试了很多次,一直都是保存失败,在代码中执行是catch到一个异常IOException,是因为权限的问题,所以在保存之前一定要记得检查权限是否允许,获取权限;
public static void saveHeaderImage(Bitmap bitmap, String filePath) {
File file = new File(filePath);
try {
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
BufferedOutputStream bo;
bo = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bo);
bo.flush();
bo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
7.获取保存后的照片,显示照片
if (getLoacalBitmap("$SAVE_PIC_PATH$HeadImageName") != null) {
sign_head_iv.setImageBitmap(getLoacalBitmap("$SAVE_PIC_PATH$HeadImageName"))
}
获取本地照片:
fun getLoacalBitmap(url: String): Bitmap? {
if (url != null) {
var fis: FileInputStream? = null
try {
fis = FileInputStream(url)
return BitmapFactory.decodeStream(fis) // /把流转化为Bitmap图片
} catch (e: FileNotFoundException) {
e.printStackTrace()
return null
} finally {
if (fis != null) {
try {
fis.close()
} catch (e: IOException) {
e.printStackTrace()
}
fis = null
}
}
} else {
return null
}
}
网友评论