我的视频课程:《FFmpeg打造Android万能音频播放器》


       距离上次更新博客都感觉是好久远的事了,不过不管过多久,有更新总是不错的。今天给大家带来一个自己写的获取Android手机相册图片或相机拍照图片的例子,可以相册可以单选或多选,在单选或相机模式下可以设置是否裁剪,裁剪是调用的系统的裁剪方法,对于6.0以上的系统,会先去申请相机和读写SDcard权限。先简单看几张效果图:

模拟器动态图如下:

android 选择多图 android 相册选择图片_裁剪

手机静态图:

1、

android 选择多图 android 相册选择图片_单张图片选择_02

2、

android 选择多图 android 相册选择图片_android 选择多图_03

3、

android 选择多图 android 相册选择图片_裁剪_04

4、

android 选择多图 android 相册选择图片_android 选择多图_05

一、老规矩,先说说实现的思路:

(1)首先是相册选择:由于Android的多样性,通过系统来选择图片也是可行的,但是兼容性不好,对不同版本返回的uri解析也不同,而且还不能实现多张同时选择。因此为了达到好的用户体验,就抛弃了系统选择图片的这种方式。因为图片都是存储在手机Sdcard上的,因此我们可以通过扫描Sdcard来获取所以图片的路径,然后再根据路径来获取图片,这样就不会有什么问题了。为了扫描Sdcard,我们使用ContentResolver来查询媒体类型为:jpg或png的图片,然后分文件夹来存储相应的图片路径就可以了。

对于对图片按文件夹分类时,我们只需要存储文件夹的路径和里面第一张图片就行了,就可以把图片列表展示给用户选择,然后选择相应文件夹时,再查询相应文件夹下所有图片类型的文件,获取其实际路径就OK了。

(2)相机拍照:我们可以用默认的方式调用相机拍照,然后在返回的data里面获取图片,但是这个图片是缩略图,不是很清晰。所以我们改变策略,Android系统调用相机拍照时可以设置所拍的照片的存储路径,这样我们就可以自己定义文件路径,然后拍照成功后,到相应路径下面去获取图片就可以了,而且还是高清五码的哦 吼吼。不过我们自己定义图片路径并且保存成功后,还需要做一步就是通知系统刷新图库,这样我们才能及时在图片文件夹列表里面找到我们刚拍摄的图片。

综上:我们对图片的处理都是通过图片的实际路径来获取图片,这样就不会存在兼容性问题了。

二、代码比较多,并且大多都是处理交互UI的,这里就没必要贴出来了,只贴出重要代码即可:

(1)扫描系统图库,并存储所以图片路径和分文件夹存储图片和相应的图片数量:

public void scanImgs()
    {
        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
        {
            Toast.makeText(context, "当前存储卡不可用", Toast.LENGTH_SHORT).show();
            return;
        }
        new Thread()
        {
            @Override
            public void run() {
                Uri muri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                ContentResolver cr = activity.getContentResolver();

                Cursor cursor = cr.query(muri, null, MediaStore.Images.Media.MIME_TYPE + " = ? or " + MediaStore.Images.Media.MIME_TYPE + " = ? ", new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED);

                Set<String> dirPaths = new HashSet<String>();
                int count = cursor.getCount();
                for(int i = count - 1; i >= 0; i--) {
                    cursor.moveToPosition(i);
                    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));

                    if(i == count - 1)
                    {
                        ImgFloderBean imgflder = new ImgFloderBean();
                        imgflder.setFirstImgPath(path);
                        imgflder.setDirName("所以图片");
                        imgflder.setType(0);
                        imgflder.setSelected(true);
                        imgFloderBeens.add(imgflder);
                    }

                    ImgBean imgBean = new ImgBean();
                    imgBean.setPath(path);
                    imgBean.setSelected(false);
//                    checkSelectedImgBeans(imgBean);
                    imgs.add(imgBean);
                    tempImgs.add(imgBean);
                    File parentFile = new File(path).getParentFile();

                    if (parentFile == null)
                        continue;
                    String dirPath = parentFile.getAbsolutePath();
                    ImgFloderBean imgFloderBean = null;

                    if (dirPaths.contains(dirPath)) {
                        continue;
                    } else {
                        dirPaths.add(dirPath);
                        imgFloderBean = new ImgFloderBean();
                        imgFloderBean.setDir(dirPath);
                        imgFloderBean.setFirstImgPath(path);
                        imgFloderBean.setDirName(parentFile.getName());
                        imgFloderBean.setType(1);
                        imgFloderBean.setSelected(false);
                        imgFloderBeens.add(imgFloderBean);
                    }

                    if (parentFile.list() == null)
                        continue;

                    int picSize = parentFile.list(new FilenameFilter() {
                        @Override
                        public boolean accept(File file, String s) {
                            if (s.endsWith(".jpg") || s.endsWith(".jpeg") || s.endsWith(".png"))
                                return true;
                            return false;
                        }
                    }).length;

                    if (imgFloderBean != null) {
                        imgFloderBean.setSize(picSize);
                    }

                }
                cursor.close();
                Message message = Message.obtain();
                message.what = 0x001;
                handler.sendMessage(message);
            }
        }.start();

    }

(2)扫描文件夹下面的图片:

public void scanChildDirPaths(String dirPath)
    {
        this.dirPath = dirPath;
        File file = new File(dirPath);
        String[]childFilePaths = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File file, String s) {
                if(s.endsWith(".jpg") || s.endsWith(".jpeg") || s.endsWith(".png"))
                    return true;
                return false;
            }
        });

        if(childFilePaths != null)
        {
            imgGridViewAdapter.setIsaddpath(true);
            imgGridViewAdapter.setPpath(dirPath);
            imgs.clear();
            int length = childFilePaths.length;
            for(int i = 0; i < length; i++)
            {
                ImgBean imgBean = new ImgBean();
                imgBean.setPath(childFilePaths[i]);
                imgs.add(imgBean);
            }
            Collections.reverse(imgs);
            imgGridViewAdapter.notifyDataSetInvalidated();
        }

    }


(3)相机拍照后,更新系统相册

try {
                MediaStore.Images.Media.insertImage(context.getContentResolver(),
                        imageUri.getPath(), imgname, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            // 最后通知图库更新
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath())));

(4)打开相机,设置自定义图片保存路径:

file = new File(getImgPath());
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    imgname = getHeadImgName();
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    imageUri = Uri.fromFile(new File(file, imgname));
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//设置图片保存路径
                    activity.startActivityForResult(intent, REQUEST_CAMERA_RESULT_CODE);



三、6.0权限申请:

这里以申请相机权限为例:

(1)首先判断是否允许调用相机权限

if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)//相机权限
                {
                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);//去申请相机权限
                }
else
{

}


(2)在onRequestPermissionsResult中处理权限申请结果,如果用户拒绝,则给出相应的提示:

if (requestCode == REQUEST_CAMERA_CODE)
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                Toast.makeText(context, "camera--1", Toast.LENGTH_SHORT).show();
            } else
            {
                Toast.makeText(context, "请允许打开摄像头权限", Toast.LENGTH_SHORT).show();
            }
            return;
        }

四、调用方法(这里是在Activity中)

private PickPhotoDialog pickPhotoDialog;

    //点击事件里面添加
    pickPhotoDialog = new PickPhotoDialog(MainActivity.this, MainActivity.this);
    Window window = pickPhotoDialog.getWindow();
    window.setGravity(Gravity.BOTTOM);
    window.setWindowAnimations(R.style.DialogEnter);
    pickPhotoDialog.setCutImg(true, 5);//第一个参数为true:表示图片会被裁剪,此时第二个参数默认为1,只能选择一种图片;为false时,表示不裁剪,然后第二个参数表示选择图片的数量。
    pickPhotoDialog.setOnPhotoResultListener(new PickPhotoDialog.OnPhotoResultListener() {
        @Override
        public void onCameraResult(String path) {//相机拍照图片路径
            List<ImgBean> imgBeens = new ArrayList<ImgBean>();
            ImgBean imgBean = new ImgBean();
            imgBean.setPath(path);
            imgBeens.add(imgBean);
            adViewpagerUtil = new AdViewpagerUtil(MainActivity.this, viewpager, lydots, 8, 4, imgBeens);
            adViewpagerUtil.initVps();
        }

        @Override
        public void onCutPhotoResult(Bitmap bitmap) {
            //图片(相机和相册)裁剪后返回的bitmap
        }

        @Override
        public void onPhotoResult(List<ImgBean> selectedImgs) {//相册多图选择返回图片路径结果集
            if(selectedImgs != null && selectedImgs.size() > 0) {
                adViewpagerUtil = new AdViewpagerUtil(MainActivity.this, viewpager, lydots, 8, 4, selectedImgs);
                adViewpagerUtil.initVps();
            }
            else
            {
                if(adViewpagerUtil != null) {
                    adViewpagerUtil.startLoopViewPager();
                }
            }
        }
    });

    //权限申请
    @TargetApi(23)
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (pickPhotoDialog != null)
        {
            pickPhotoDialog.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);

        if(pickPhotoDialog != null)
        {
            pickPhotoDialog.onActivityResult(requestCode, resultCode, data);
        }
    }