Android选择图片
我的视频课程:《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选择图片相关推荐
- Android 选择图片、上传图片之ImagePicker
效果图: 后来又出了两篇,也可以看一下 Android 选择图片.上传图片之PictureSelector Android 选择图片.上传图片之Matisse 添加依赖: 选择图片:compile ' ...
- android选择图片或拍照开源项目,Android 开源照相和图片选择框架PictureSelector
拍照或者相册选择图片并渲染到UI上,发现了一个更简单的三方框架来实现 -- PictureSelector.Github地址:https://github.com/LuckSiege/PictureS ...
- android 选择图片sdk,GitHub - XieZed/CameraSDK: Android多图选取,滤镜,贴纸,裁剪等类似美图秀秀的功能...
非常实用的类似新浪微博的多图片选择工具 一.软件功能: 1.可以加载手机里面所有的图片 2.也可以根据相册文件夹选择图片 3.裁剪正方形图片 4.给图片加滤镜特效 5.给图片加贴纸功能 6.可以删除已 ...
- Android 调用相机APP获取拍照图片和从相册选择图片
源码部分分析 Camera.java → 点我定位,注意研究1134行与2023行的两个方法. 通过源码可以发现,输出的图片有2个分支 如果你没有指定Intent里面的Extra参数,它就返回一个序列 ...
- Android 如何从系统图库中选择图片
这几天我都在做Android的App,同时学习它的API,我将分享一些我学到的东西,比如: 如何从系统图库中选择图片. 首先,让我们来看看如何将手机系统图库集成到你的App中,然后再从图库中选择 ...
- php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择
概述 在Android开发中获取图片主要包括如下两种方式: 打开相机拍照 从图库中选择图片 一.打开相机拍照 打开相机拍照主要包括如下几个部分: 权限申请 打开摄像头 拍照后传回数据处理 1. 权限申 ...
- Android 拍照、从相册选择图片
在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照.从相册选择. 一.拍照 调用相机拍照有两种方法: 直接返回图片. 在调用相机的时候,传入uri,拍照后通过该uri来获取图片. ...
- android选择本地图片并裁剪
本文使用Android原生的选择和裁剪功能.下面是代码: public class PickAndCropActivity extends AppCompatActivity implements V ...
- Android手机图片上传 选择不了本地照片 解决方案
问题描述:在实现Android端向服务器上传图片过程中,本人采用的是Android4.4版本,最初选择图片的代码是这样写的: // Intent intent = new Intent( ...
最新文章
- 利用ConcurrentHashMap来实现一个ConcurrentHashSet
- 跨工厂物料状态/特定工厂的物料状态
- Google又发大招:高效实时实现视频目标检测
- zabbix安装php7.0,Centos 7.0安装Zabbix server详细步骤(示例代码)
- MySQL安装教程图解
- java起源英文_Abbreviation 英文词组缩写(来源:南阳理工大学ACM)java
- php异步轮询如何实现,深入剖析JavaScript异步之事件轮询
- 【opencv学习】透视变换矩阵
- Unity面试题精选(6)
- Packt发布了2018年技能提升报告
- vue 共用新增和修改验证分离
- 基于Web应用的性能分析及优化案例
- django的admin
- HDU 12O3 I NEED A OFFER!
- SQL增删改查基本语法整理
- 医院防统方软件解决方案
- 已知ip地址和其子网掩码如何求网络号子网号主机号
- 给在读研究生的一封信
- 计算机如何正确开关机,初学台式机电脑开关机的正确操作 电脑定时关机的基础知识...
- Google学术映像