Android--使用手机拍照获取图片路径,小米手机选择照片问题处理
2016-12-13 10:25
946 查看
Android开发选取照片问题
本文主要记录使用手机自带相机拍照获取返回照片路径,以及从本地相册选取已有照片时返回Intent data;数据处理 操作。(小米手机获取照片路径与其他手机不一致问题!)
一:使用相机时添加权限:
<!-- 调用相机权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!-- SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
二 调取相机拍照:
1. 拍照获取图片,返回Bitmap对象,图片不会自动保存至本地:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 1);
使用此方法拍照时,返回结果Intent data ;data.getData()==null;
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //... Uri uri = data.getData();//此时uri为null Bundle bundle = data.getExtras();// if (bundle != null) { //图片被保存在 bundle中返回,使用budle.get("data")获取bitmap对象 Bitmap photo = (Bitmap) bundle.get("data"); //todo:得到bitmap对象可以直接使用imgaeview展示,此时是缩略图 } else { Toast.makeText(getApplicationContext(), "无法找到该图片!", Toast.LENGTH_LONG).show(); return; } //... }
ps:如果像保存图片到本地需要单独设置保存得路径
/** * 将bitmap保存为特定格式的图片 * * @param bmp 需要保存的bmp * @param desFilename 目的文件路径 * @param format 保存的图片格式, 如果为空则默认保存为jpg格式 * @param quality 是否进行质量压缩 * @param recycleBitmapSavedFile 是否在保存图片后回收bitmap * @return 保存成功, 则返回true; 否则返回false */ public static boolean saveBitmap(Bitmap bmp, String desFilename, Bitmap.CompressFormat format, boolean recycleBitmapSavedFile, int quality) { try { if (bmp == null || bmp.isRecycled() || TextUtils.isEmpty(desFilename)) { return false; } File file = new File(desFilename); if (!file.getParentFile().exists()) file.getParentFile().mkdirs(); if (file.exists()) file.delete(); file.createNewFile(); FileOutputStream outStream = new FileOutputStream(file); if (format == null) { format = Bitmap.CompressFormat.JPEG; } boolean result = bmp.compress(format, quality, outStream); outStream.flush(); outStream.close(); if (recycleBitmapSavedFile) { bmp.recycle(); bmp = null; } // 操作成功, 直接返回 return result; } catch (IOException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); } catch (OutOfMemoryError e) { e.printStackTrace(); } return false; }
2 自定义照片存储路径,需要注意自定义路径时返回Intent data 都为null :
![这里写图片描述](https://img-blog.csdn.net/20161213130517218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2l0aHViXzMwNjYyNTcx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
/** * 两种拍照获取图片得方法 */ private Uri photoUri; @Override public void onTakePhotoItemclick() { //方法一:保存拍摄图片至手机默认相册中 SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmss"); filename = timeStampFormat.format(new Date()); ContentValues values = new ContentValues(); //使用本地相册保存拍摄照片 values.put(MediaStore.Images.Media.TITLE, filename); photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); // 设置 intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); photoUri = 保存图片得uri Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(intent, FLAG_TAKE_PHOTO); /* // 方法二 自定义文件夹保存 if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { //创建文件夹 在本地文件Pictures 目录下创建 自己得文件夹 File dir = new File(Environment.getExternalStorageDirectory()+ "/Pictures/image"); if (!dir.exists()) { dir.mkdirs(); } //照片名称 File file = new File(dir, new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".jpg"); photoUri = Uri.parse(file.getPath()); startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE) .putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)), FLAG_TAKE_PHOTO); } else { showToast("请检查SDCard!"); }*/ }
如何获取imagePath:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == FLAG_CHOOSE_IMG && resultCode == RESULT_OK) { //处理选择照片返回 //todo: } else if (requestCode == FLAG_TAKE_PHOTO && resultCode == RESULT_OK) { //处理拍照返回 //使用第一种方法拍照时处理图片路径 Uri uri = null; String path = ""; Cursor cursor = null; uri = photoUri; if (uri != null) { String[] proj = {MediaStore.Images.Media.DATA}; cursor = managedQuery(uri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); path = cursor.getString(column_index); //在android 4.0及其以上的版本中,Cursor会自动关闭,不需要自己关闭。 if (cursor != null && !cursor.isClosed() && Build.VERSION.SDK_INT < 14) { cursor.close(); } } // 第二种方法时:获取图片路径 if (photoUri != null) {//todo path = photoUri.toString(); } //todo: 得到 path 之后可以转换成bitmap 使用。 } }
在上述方法二中因为是自定义路径所以图片地址是已知得因此直接将 photoUri 转化成String 就可以直接使用了。
三 直接选择本地现有图片
@Override public void onChoosePhotoItemclick() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, FLAG_CHOOSE_IMG); }
处理返回数据Intent data
**PS:个别小米手机返回数据和其他手机不同(暂时无法确定是否时全部小米手机)以下是debug
下三星手机和小米手机在选择本地图片时数据对比。**
三星手机:
小米手机:
可以看到小米手机返回得直接是file:///文件绝对路径;因此在获取图片path
时使用以下判断:
/** * Intent data 小米手机选择相册照片时返回数据 { dat=file:///storage/emulated/0/DCIM/Camera/IMG_20161129_195938.jpg typ=image/jpeg } //other 拍照返回 Intent data { dat=content://media/external/images/media/222494 } * @param data */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Uri uri = null; String path = ""; Cursor cursor = null; if (requestCode == FLAG_CHOOSE_IMG && resultCode == RESULT_OK) { //处理选择照片返回 if (data != null && data.getData() != null) { uri = data.getData(); if (!TextUtils.isEmpty(uri.getAuthority())) { //使用 getAuthority 做判断条件 String[] proj = {MediaStore.Images.Media.DATA}; cursor = managedQuery(uri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); path = cursor.getString(column_index); }else{ path = uri.getPath(); //小米选择照片返回 data="file:///..." uri.getAuthority()=="" } //todo: } } else if (requestCode == FLAG_TAKE_PHOTO && resultCode == RESULT_OK) { //处理拍照返回 }
学习记录,如有错误和不足,欢迎大家指出
最后贴出一个不错的库:一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库
。https://github.com/crazycodeboy/TakePhoto
相关文章推荐
- Android:Camera的使用,并处理手机拍照后上传图片被旋转的问题
- Android-->拍照/相册选择照片(从Uri中获取图片路径)
- android拍照后图片路径的获取(解决不同手机存在拍照后旋转的问题)
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- android 解决小米手机上选择照片路径为null的问题
- android解决小米手机上选择照片路径为null问题
- Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- android 解决小米手机上选择照片路径为null情况,导致图片显示不出来
- Android 4.4以上拍照或者从图库选择图片,获取图片路径
- Android 从手机相册获取图片 uri 路径 从相机获取照片
- android 手机拍照后获取图片导致OOM问题
- TakePhoto是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本3.0.0。
- Android 获取手机系统图片、拍照图片时回调后通过URI解析路径的方法,比较全面!!!!
- Android开发——相册拍照_03.解决相机拍照之后部分手机无法将图片保存到路径或部分手机点击相机确定无法返回问题
- Android部分手机拍照后获取的图片被旋转问题的解决方法
- Android 拍照(获取原图),选择照片并且剪切图片
- Android部分手机拍照上传返回为空处理,和拍照后图片压缩后保存到指定路径下
- android 适配8.0。6.0调起手机拍照获取照片路径
- Android 相册选择照片或拍照获取图片系统6.0及7.0实现