最近在做一个相册功能的app,想来都是一些很简单的功能,做起来应该很快,没想到果断被几个问题卡住了大半天,现在记录一下问题并供大家参考。
调用系统相机有很多方法,但大致可分为俩种,指定了照片保存路径的调用和没有指定路径的调用:
指定了照片保存路径:
String imagePath = "/sdcard/DCIM/Camera/photo.jpg";
// 保存照片到指定的路径
File dir = new File("/sdcard/DCIM/Camera/");
if (!dir.exists()) {//如果没有此文件夹 需要创建
dir.mkdirs();
}
File file = new File(imagePath);
Uri uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 12);
没有指定路径的调用方法:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 12);
这里有几点需要注意:
1.你的保存路径文件夹如果没有,有些手机会创建文件夹让你保存进去,而有些手机是不会的,你会在拍照后保存失败或点击完成无反应,解决的方法就是在指定存储路径前先判断路径中的文件夹是否都存在,不存在先创建再调用相机,详细方法可以看上面的“指定了照片保存路径”。
2.你指定了照片的路径后,那么你在onActivityResult方法里得到的Intent是null的,如果你不指定这个uri,那么你就有可能得到这个Intent的值,你可以通过data.getParcelableExtra(“data”)得到这个照片的缩略图(Bitmap对象),为什么说是有可能呢,因为有些机型即时不指定图片的uri也返回null,是不是很坑。所以在onActivityResult得到返回的图片对象的话,记得进行非空判断,很重要。
3.照片可以存储,但是名字不对 file:///mnt/sdcard/123 1.jpg,由于Uri 的fromFile方法会将路径中的空格用“%20”取代。其实对于大多数的手机这都不算事,手机在解析存储路径的时候都会将“%20”替换为空格,这样实际上最终的照片名字还是我们当初指定的名字:123 1.jpg,遗憾的是个别手机(如酷派7260)系统自带的相机没有将“%20”读成空格,拍照后的照片的名字是123%201.jpg,我们用路径“file:///mnt/sdcard/123 1.jpg”能找到照片才怪!!(这一条是博主看别人资料找到的,没有证实)
调用相机的问题解决了,对于那些只是调用相机得到一张图片的同学,问题已经解决了,但做我需要的功能,又出现了新问题,照完后,在手机的媒体库里得不到这张图片。
查找本地图片分为俩种方法,查询手机的媒体数据库和遍历整个手机存储,由于我不止需要图片,还需要图片的别的信息,如宽高大小时间,所以我选择的是第一种方法,通过ContentResolver得到图片和它的信息。现在我照相后从数据库也得不到这个图片信息,在查找了资料后找到了解决方法,方法可以分为俩种,拍完后自己去数据库插入这个图片的信息和通知数据库刷新在去获取图片信息:
自己插入数据:
public boolean saveImgToGallery(String fileName) {
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
if (!sdCardExist)
return false;
try {
ContentValues values = new ContentValues();
values.put(Media.DATE_TAKEN, date);
values.put(Media.MIME_TYPE, "image/png");
values.put(Media.DATA, imagePath);
values.put(Media.TITLE, title);
// values.put("_size", Integer.valueOf(0));
Application app = MyApplication.getThis();
ContentResolver cr = app.getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
通知数据库刷新(有俩种方法):
1.
Uri localUri = Uri.fromFile(new File(imagePath));//imagePath为你的图片的路径,如/sdcard/Camera/tupian.jpg
Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
sendBroadcast(localIntent);
2.
MediaScannerConnection.scanFile(this,
new String[] { imagePath }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
//这里就可以再去获取数据库的图片信息了
}
});
由于功能需要,我选择的是刷新数据库的第二种方法,至此,问题解决!