看到《第一行代码》中调用摄像头拍照代码的如下:
@Override
public void onClick(View view) {
if (btn_take_photo == view){
File imgFile = new File(getExternalCacheDir(), "abc.png");
//imgFile = "/storage/emulated/0/Android/data/com.lyl.avatar/cache/abc.png"
if (imgFile.exists()){
imgFile.delete();
}
try {
imgFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//File对象 --> Uri对象
if (Build.VERSION.SDK_INT >= 24){
/*
Android7.0以后不再使用真实路径的Uri,FileProvider是特殊的内容提供者,可以选择性的将封装过的Uri共享给外部
FileProvider是ContentProvider的子类,清单文件中要添加provider
imgUri的值打印出来为:"content://com.lyl.avatar.takephoto/my_imgs/Android/data/com.lyl.avatar/cache/abc.png"
*/
imgUri = FileProvider.getUriForFile(MainActivity.this, "com.lyl.avatar.takephoto", imgFile);
} else {
// imgUri的值打印出来为:"file:///storage/emulated/0/Android/data/com.lyl.avatar/cache/abc.png"
imgUri = Uri.fromFile(imgFile);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
startActivityForResult(intent, TAKE_PHOTO_REQ);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((TAKE_PHOTO_REQ == requestCode) && (RESULT_OK == resultCode)){
setImg(imgUri);
}
}
public void setImg(Uri imgUri){
//getContentResolver,内容解析器,和getContentResolver对应
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(imgUri);
//BitmapFactory --> Bitmap
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);//bitmap : 位图对象
iv_photo.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
发现可以用getExternal的方式来获取uri,经尝试会报错,就搜索了下相关问题。
1).当指定uri时,即intent.putExtra(MediaStore.EXTRA_OUTPUT,imgUri); ,mSaveUri不为null,系统在保存完图片,直接setResult(RESULT_OK)了,并没有创建intent返回,故在onActivityResult中的data为null;
2).若不指定uri,mSaveUri为null会把图片转换为bitmap,创建Intent,把bitmap存放在data中,即在onActivityResult中通过 data.getExtras().get("data");就能拿到图片的Bitmap。但data返回的是缩略图,没有原始图片清晰。
故,在保存自己图片的uri时,不要使用解析返回的data的方法。若要使用返回的Intent类型的data,代码如下:
@Override
public void onClick(View view) {
if (btn_take_photo == view){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);//使mSaveUri为空
startActivityForResult(intent, TAKE_PHOTO_REQ);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((TAKE_PHOTO_REQ == requestCode) && (RESULT_OK == resultCode)){
try {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
iv_photo.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
参考链接:
解释 Android 调用系统相机,在onActivityResult中接收的data为null的原因
getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()的作用