我的视频课程:《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(){@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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();}@Overridepublic void onCutPhotoResult(Bitmap bitmap) {//图片(相机和相册)裁剪后返回的bitmap}@Overridepublic 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)@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (pickPhotoDialog != null){pickPhotoDialog.onRequestPermissionsResult(requestCode, permissions, grantResults);}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if(pickPhotoDialog != null){pickPhotoDialog.onActivityResult(requestCode, resultCode, data);}}

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

GitHub下载

CSDN下载

Android选择图片相关推荐

  1. Android 选择图片、上传图片之ImagePicker

    效果图: 后来又出了两篇,也可以看一下 Android 选择图片.上传图片之PictureSelector Android 选择图片.上传图片之Matisse 添加依赖: 选择图片:compile ' ...

  2. android选择图片或拍照开源项目,Android 开源照相和图片选择框架PictureSelector

    拍照或者相册选择图片并渲染到UI上,发现了一个更简单的三方框架来实现 -- PictureSelector.Github地址:https://github.com/LuckSiege/PictureS ...

  3. android 选择图片sdk,GitHub - XieZed/CameraSDK: Android多图选取,滤镜,贴纸,裁剪等类似美图秀秀的功能...

    非常实用的类似新浪微博的多图片选择工具 一.软件功能: 1.可以加载手机里面所有的图片 2.也可以根据相册文件夹选择图片 3.裁剪正方形图片 4.给图片加滤镜特效 5.给图片加贴纸功能 6.可以删除已 ...

  4. Android 调用相机APP获取拍照图片和从相册选择图片

    源码部分分析 Camera.java → 点我定位,注意研究1134行与2023行的两个方法. 通过源码可以发现,输出的图片有2个分支 如果你没有指定Intent里面的Extra参数,它就返回一个序列 ...

  5. Android 如何从系统图库中选择图片

     这几天我都在做Android的App,同时学习它的API,我将分享一些我学到的东西,比如: 如何从系统图库中选择图片. 首先,让我们来看看如何将手机系统图库集成到你的App中,然后再从图库中选择 ...

  6. php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择

    概述 在Android开发中获取图片主要包括如下两种方式: 打开相机拍照 从图库中选择图片 一.打开相机拍照 打开相机拍照主要包括如下几个部分: 权限申请 打开摄像头 拍照后传回数据处理 1. 权限申 ...

  7. Android 拍照、从相册选择图片

    在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照.从相册选择. 一.拍照 调用相机拍照有两种方法: 直接返回图片. 在调用相机的时候,传入uri,拍照后通过该uri来获取图片. ...

  8. android选择本地图片并裁剪

    本文使用Android原生的选择和裁剪功能.下面是代码: public class PickAndCropActivity extends AppCompatActivity implements V ...

  9. Android手机图片上传 选择不了本地照片 解决方案

    问题描述:在实现Android端向服务器上传图片过程中,本人采用的是Android4.4版本,最初选择图片的代码是这样写的: //        Intent intent = new Intent( ...

最新文章

  1. 利用ConcurrentHashMap来实现一个ConcurrentHashSet
  2. 跨工厂物料状态/特定工厂的物料状态
  3. Google又发大招:高效实时实现视频目标检测
  4. zabbix安装php7.0,Centos 7.0安装Zabbix server详细步骤(示例代码)
  5. MySQL安装教程图解
  6. java起源英文_Abbreviation 英文词组缩写(来源:南阳理工大学ACM)java
  7. php异步轮询如何实现,深入剖析JavaScript异步之事件轮询
  8. 【opencv学习】透视变换矩阵
  9. Unity面试题精选(6)
  10. Packt发布了2018年技能提升报告
  11. vue 共用新增和修改验证分离
  12. 基于Web应用的性能分析及优化案例
  13. django的admin
  14. HDU 12O3 I NEED A OFFER!
  15. SQL增删改查基本语法整理
  16. 医院防统方软件解决方案
  17. 已知ip地址和其子网掩码如何求网络号子网号主机号
  18. 给在读研究生的一封信
  19. 计算机如何正确开关机,初学台式机电脑开关机的正确操作 电脑定时关机的基础知识...
  20. Google学术映像

热门文章

  1. 调试并修理垂起固定翼(VTOL)
  2. 电影-魔幻之吻-后感
  3. 详解java中的日期与时间;新旧API对比;各种日期格式转换
  4. git submodule sync --recursive
  5. 有人知道报软件测试培训班需要多少钱吗?
  6. JS实现Html转义和反转义(html编码和解码)的方法总结
  7. 电脑开机黑屏提示 ERROR 0199 System Security-Security password retry
  8. 埃及分数怎么计算java_埃及分数之斐波那契法
  9. Elasticsearch搜索与排序经验小记
  10. 高中毕业,可以选择的技能