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


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

模拟器动态图如下:


手机静态图:

1、


2、


3、


4、


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

(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 dirPaths = new HashSet();                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 imgBeens = new ArrayList();            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 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);        }    }



这样总的核心功能也就完成了,详细的实例可以到我的CSDN或者GitHub去下载:

GitHub下载

CSDN下载






更多相关文章

  1. android相机如何只显示处理后的图像以及这里onPreviewFrame不被
  2. Android中合多图片和文字合成PDF文件---路很长
  3. ANDROID XML图像资源文件详细讲解(一)
  4. Android中的缓存策略—拉取网络图片,缓存本地
  5. android 新闻图片加载,缓存处理
  6. Android(安卓)使用ColorMatrix改变图片颜色
  7. Android(安卓)图片获取及上传
  8. 使用Glide替换Picasso经验小结
  9. Android中新建的文件在R没有显示对应的文件解决办法总结

随机推荐

  1. Android抓屏源码
  2. 【Android】数据库 sqLite
  3. Android(安卓)实现监听开机启动开启后台
  4. android 使用vcard示例
  5. Android(安卓)Handler线程间通信机制分析
  6. Android:电话拨号器
  7. Android(安卓)自定义广播
  8. 详解Android中自定义View的invalidate,Ha
  9. Arduino相关
  10. android中通过"反射"的到android隐藏的AP