Android解决小米手机相机和相册的问题(适配小米手机相机和相册)

这两天做一个功能,需要拍照和相册选择图片并上传,功能本来不难,但是MIUI就不行了,拍照和相册取图用一般的方法都有问题,网上查了好多都是转载的,且解决办法有问题,当然也可能是我使用有问题,总之最后还是从网上东拼西凑做的,现在做个总结,也方便自己日后的使用。

测试机:小米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





  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值