目录
一、调用摄像头拍照
二、打开相册选择照片
学完本篇文章可以收获如何调用手机的摄像头和打开手机相册选择图片功能。
先新建一个CameraAlbumTest项目。
修改activity_main.xml,代码如下:
按钮打开摄像头,ImageView将拍到的图片显示出来。
下面编写调用摄像头的具体逻辑,修改MainActivity代码,如下:
按钮点击事件里首先创建一个File对象,用于存放摄像头拍下的照片,并命名为output_image.jpg,并将它存放在手机SD卡的应用关联缓存目录下(SD卡中专门存放当前应用缓存数据的位置),调用getExternalCacheDir()方法可以得到这个目录,目录具体路径是:/sdcard/Android/data/包名/cache。
放入缓存目录下的目的是可以不需要处理运行时权限。
接着进行一个判断,如果Android版本低于7.0,调用Uri的fromFile()方法将File对象转换成Uri对象。否则,将File对象转换为Uri对象,Uri对象标识着output_image.jpg这张图片的本地真实路径。这里使用FileProvider的getUriForFile()方法转换为Uri对象,此方法有3个参数,第一个是Context对象,第二个是任意唯一的字符串,第三个是刚刚创建的File对象。
之所以进行转换,是因为直接使用本地真实路径Uri被认为是不安全的,会抛出异常,而FileProvider是一种特殊的内容提供器,它使用了和内容提供其类似的机制来对数据进行保护,可以选择性将封装过的Uri共享给外部,提高了安全性。
接下来构建Intent对象,调用putExtra()方法指定图片的输出地址,这里填入的是刚刚得到的Uri对象,最后调用startActivityForResult()来启动活动,拍下的照片输出到output_image.jpg中。
由于使用的是startActivityForResult()来启动活动,因此拍完照后结果会返回到onActivityResult()方法中,就可以调用BitmapFactory的decodeStream()方法将照片解析成Bitmap对象,然后设置到ImageView中显示出来。
然后在res目录下新建一个名字为xml的目录(如果有则忽略这步),右键xml目录 -> New -> File,创建一个file_paths.xml文件,修改内容,代码如下:
external-path用来指定Uri共享,name属性值随意填,path属性的值表示共享的具体路径,这里设置空值表示将整个SD卡共享,也可以仅共享我们存放output_image.jpg这张图片的途径。
最后修改AndroidManifest.xml文件代码,如下:
由于刚才使用了内容提供器,所以需要进行注册。
需要声明访问SD卡的权限。
android:name值是固定的,android:authorities的值必须要和刚才的FileProvider.getUriForFile()方法中的第二个参数的值一致,<meta-data>指定Uri的共享路径。
效果如下:
在以上项目的基础上进行修改。
修改activity_main.xml文件,在布局中添加一个按钮用于从相册中选择照片,如下:
修改MainActivity代码,如下:
代码稍微有点长,因为对Android4.4以上和以下版本分别做了处理,如果你的应用不希望版本低的使用,那么可以不用处理4.4以下版本。
最后提醒一下,因为有些照片尺寸很大,直接加载到内存中会导致程序崩溃,需要根据需求对照片进行压缩,再加载到内存中。