Android解决小米手机相机和相册的问题(适配小米手机相机和相册)
2016-09-09 20:41
417 查看
这两天做一个功能,需要拍照和相册选择图片并上传,功能本来不难,但是MIUI就不行了,拍照和相册取图用一般的方法都有问题,网上查了好多都是转载的,且解决办法有问题,当然也可能是我使用有问题,总之最后还是从网上东拼西凑做的,现在做个总结,也方便自己日后的使用。
测试机:小米5
相机:以storage为存储路径以当前时间作为File的文件名,拍照后根据路径获取图片的File就可以为所欲为了。
然后在onActivityResult()中对图片进行处理,这里就单纯的放到imageview里了,内存小的手机发生OOM表找我。
从相册选择:
调用相册的方法都一样,不多说了
以及针对MIUI系统的相册选择:
这样就大功告成了,不过我在写博客的时候出现了FileNotFoundException,提示我:EACCES (Permission denied);可是我明明已经在manifest里申请了读写权限,后来经各种Google发现在api 23+的时候不仅需要在manifest中申请权限,在代码中也要添加。
其实这只是适配小米而且,安卓机型那么多,谁知道还会出现什么问题,所以最好还是自己写个相册,我也在写希望能坚持写完吧。
Demo的地址:
http://download.csdn.net/detail/lizhiying61f/9634016
测试机:小米5
相机:以storage为存储路径以当前时间作为File的文件名,拍照后根据路径获取图片的File就可以为所欲为了。
// 存储路径 private static final String PATH = Environment .getExternalStorageDirectory() + "/DCIM"; // 图片名 public String name;
public void takephoto(View v){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 调用系统相机 new DateFormat(); name = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";//以当前时间作为文件名 Uri imageUri = Uri.fromFile(new File(PATH, name)); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, RESULT_FROM_CAMERA); }
然后在onActivityResult()中对图片进行处理,这里就单纯的放到imageview里了,内存小的手机发生OOM表找我。
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_FROM_CAMERA && resultCode == RESULT_OK){ String filePath = PATH + "/" + name; Bitmap bitmap = BitmapFactory.decodeFile(filePath); imageview.setImageBitmap(bitmap); } }这样就结束了,拍照还是蛮简单的。
从相册选择:
调用相册的方法都一样,不多说了
<span style="white-space:pre"> </span>Intent i = new Intent(Intent.ACTION_PICK, null); i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(i, RESULT_FROM_ALBUM);关键是在onActivityResult中,需要单独对小米机型做处理
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_FROM_ALBUM && resultCode == RESULT_OK){ if (SystemUtils.isMIUI()){ setPhotoForMiuiSystem(data); }else { setPhotoForNormalSystem(data); } } }这里需要判断当前的手机系统是不是MIUI系统:这里我直接贴上工具类
public class SystemUtils { private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"; private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name"; private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"; public static boolean isMIUI() { try { final BuildProperties prop = BuildProperties.newInstance(); return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null; } catch (final IOException e) { return false; } } public static class BuildProperties { private final Properties properties; private BuildProperties() throws IOException { properties = new Properties(); properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); } public boolean containsKey(final Object key) { return properties.containsKey(key); } public boolean containsValue(final Object value) { return properties.containsValue(value); } public Set<Map.Entry<Object, Object>> entrySet() { return properties.entrySet(); } public String getProperty(final String name) { return properties.getProperty(name); } public String getProperty(final String name, final String defaultValue) { return properties.getProperty(name, defaultValue); } public boolean isEmpty() { return properties.isEmpty(); } public Enumeration<Object> keys() { return properties.keys(); } public Set<Object> keySet() { return properties.keySet(); } public int size() { return properties.size(); } public Collection<Object> values() { return properties.values(); } public static BuildProperties newInstance() throws IOException { return new BuildProperties(); } } }
以及针对MIUI系统的相册选择:
/** * MIUI系统的相册选择 * @param data */ private void setPhotoForMiuiSystem(Intent data) { Uri localUri = data.getData(); String scheme = localUri.getScheme(); String imagePath = ""; if("content".equals(scheme)){ String[] filePathColumns = {MediaStore.Images.Media.DATA}; Cursor c = getContentResolver().query(localUri, filePathColumns, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePathColumns[0]); imagePath = c.getString(columnIndex); c.close(); }else if("file".equals(scheme)){//小米4选择云相册中的图片是根据此方法获得路径 imagePath = localUri.getPath(); } Bitmap bitmap = BitmapFactory.decodeFile(imagePath); imageview.setImageBitmap(bitmap); }针对其他非小米手机的图片选择:
/** * 其他系统的相册选择 * @param data */ private void setPhotoForNormalSystem(Intent data) { String filePath = getRealPathFromURI(data.getData()); <pre name="code" class="java" style="font-size: 13.3333px;"><span style="white-space:pre"> </span>Bitmap bitmap = BitmapFactory.decodeFile(<span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">filePath</span><span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;">);</span>imageview.setImageBitmap(bitmap); }
/** * 解析Intent.getdata()得到的uri为String型的filePath * @param contentUri * @return */ public String getRealPathFromURI(Uri contentUri){ String[] proj = { MediaStore.Audio.Media.DATA }; Cursor cursor = managedQuery(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }
这样就大功告成了,不过我在写博客的时候出现了FileNotFoundException,提示我:EACCES (Permission denied);可是我明明已经在manifest里申请了读写权限,后来经各种Google发现在api 23+的时候不仅需要在manifest中申请权限,在代码中也要添加。
public class PermissionsUtils { // Storage Permissions private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; /** * Checks if the app has permission to write to device storage * * If the app does not has permission then the user will be prompted to grant permissions * * @param activity */ public static void verifyStoragePermissions(Activity activity) { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission .WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user ActivityCompat.requestPermissions( activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } }使用起来就很方便了:
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){ PermissionsUtils.verifyStoragePermissions(this); }
其实这只是适配小米而且,安卓机型那么多,谁知道还会出现什么问题,所以最好还是自己写个相册,我也在写希望能坚持写完吧。
Demo的地址:
http://download.csdn.net/detail/lizhiying61f/9634016
相关文章推荐
- Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题
- android 调用系统相机或者系统相册功能时,onActivityResult方法不执行问题的解决过程
- android 相机和相册获取相片剪裁报错问题解决,机型也解决
- 解决Android调用系统相机拍照后相片无法在相册中显示问题
- Android 调用系统相机拍照并且显示在相册中,以及中间可能会遇到的一些问题的解决
- android调用系统相机和相册进行拍照裁剪处理,解决不同安卓版本存在无法加载相册的问题,处理了是否有sd卡的存在的情况
- Android开发——相册拍照_03.解决相机拍照之后部分手机无法将图片保存到路径或部分手机点击相机确定无法返回问题
- Android 7.0+相机、相册、裁剪适配问题
- 解决Android 6.0以上的相机权限适配问题
- Android拍照和从相册获取图片(解决android7.0打开相机崩溃的问题),同时也解决了拍完照后图片方向不正的问题
- Android拍照和从相册获取图片(解决android7.0打开相机崩溃的问题),同时也解决了拍完照后图片方向不正的问题
- Android屏幕大小适配问题解决
- Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题
- cocos2d-x iOS和Android同步开发 手机设备适配问题解决
- 解决Android录制适配 setVideoSize 后start failed问题
- 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题
- Android笔记:多分辨率适配及碎片化问题解决方案总结 推荐
- Android实战技术: 用Dimension解决多屏幕适配的问题
- 解决Android相机竖屏预览的问题
- 解决Android拍照保存在系统相册不显示的问题