android相机保存文件为空,android 调用系统相机拍照,返回的data为null

最近做项目,需要拍照功能,于是就想简单的调用系统相机来完成这一需求(当然,如果想要个性化一点的,也可以自定义camera去实现,这里暂时不做)。

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ){

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

File file = FileUtils.createTempImage(getContext());

mImageCapturePath = file.toString();

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));

startActivityForResult(intent, IMAGE_CAPTURE);

}else {

ToastUtil.showShortToast(context, "请确认插入SD卡");

}

然后问题就来了:

在onActivityResult(int requestCode, int resultCode, Intent data)代码中得到的data居然为null。。。

于是百度了一下,原来已经有很多人都发表过相关的博客了…这里就权当记录一下自己的学习经历吧。

原来我们在

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));

如果指定了存储的路径的uri,那么返回的data就为null;

如果不指定图片的uri,则可能会返回data(照相机有自己默认的存储路径,拍摄的照片将返回一个缩略图。可以通过data.getParcelableExtra("data")

获得图片)。

为什么说可能?因为有些机型即时不指定图片的uri也返回null,T_T。

所以需要在onActivityResult方法中判断一下:

@Override

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

switch (requestCode) {

case IMAGE_CAPTURE:

if (resultCode == RESULT_OK) {

if(data !=null){ //可能尚未指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

//返回有缩略图

if(data.hasExtra("data")){

Bitmap thumbnail = data.getParcelableExtra("data");

//得到bitmap后的操作,如压缩处理...

}

}else{

//由于指定了目标uri,存储在目标uri,intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

// 通过目标uri,找到图片

// 对图片的缩放处理

// 操作

}

}

}

}

当然,最稳妥的办法还是指定uri吧,免得有些机型不指定uri返回null。

参考下源码:

if (mSaveUri != null) {//存在mSaveUri,即指定了目标uri

OutputStream outputStream = null;

try {

outputStream = mContentResolver.openOutputStream(mSaveUri);

outputStream.write(data);

outputStream.close();

setResult(RESULT_OK); //直接返回RESULT_OK,并没有指定intent

finish();

} catch (IOException ex) {

// ignore exception

} finally {

Util.closeSilently(outputStream);

}

} else {

Bitmap bitmap = createCaptureBitmap(data);

// 返回RESULT_OK,并包含一个Intent对象,其中Extra中科key为data,value为一个bitmap

setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap));

finish();

}

最后还有一些注意事项

onActivityResult 方法中的data 返回为空(数据表明,93%的机型的data

将会是Null,所以如果我们指定了路径,就不要使用data 来获取照片,起码在使用前要做空判断)

照片无法存储。如果自定义存储路径是/mnt/sdcard/lowry/,而手机SD 卡下在拍照前没有名为lowry的文件夹,那么部分手机拍照后图片不会保存,导致我们无法获得照片,大多数手机的相机遇到文件夹不存在的情况都会自己创建出不存在的文件夹,而个别手机却不会创建,其代表机型为:三星I8258、华为H30-T00、红米等。解决的方法就是在指定存储路径前先判断路径中的文件夹是否都存在,不存在先创建再调用相机。

照片可以存储,但是名字不对 file:///mnt/sdcard/123 1.jpg,由于Uri 的fromFile方法会将路径中的空格用“%20”取代。其实对于大多数的手机这都不算事,手机在解析存储路径的时候都会将“%20”替换为空格,这样实际上最终的照片名字还是我们当初指定的名字:123 1.jpg,遗憾的是个别手机(如酷派7260)系统自带的相机没有将“%20”读成空格,拍照后的照片的名字是123%201.jpg,我们用路径“file:///mnt/sdcard/123 1.jpg”能找到照片才怪!!

解决办法:

使用 onActivityResult 中的 intent(data)前要做空判断。

指定拍照路径时,先检查路径中的文件夹是否都存在,不存在时先创建文件夹再调用相机拍照。

指定拍照存储路径时,照片的命名中不要包含空格等特殊符号。