在很多app中都有调用摄像头的功能,接下来就是实现这个功能。
1.新建一个活动,修改activity_main.xml,代码如下:
其中做一个take_photo的按钮,还有一个叫picture的ImageView用来将所拍的照片展示出来。
2.修改MainActivity的代码:
大体思路:新建一个outputSream的File类用来保存所拍的图片,其中getExternCacheDir()方法表示获得手机SD卡的应用关联缓存目录,Android 6.0之后读写SD卡变为危险权限,需要程序运行时权限申请,而应用关联缓存目录不需要。图片存储在outpuStream之后,通过if判断Android系统的版本。若是7.0版本及以上,就调用FileProvider类的getUriForFile()方法将outputSream转化成封装过Uri类赋值给imageUri,其中getUriForFile()方法接收3个参数,第一个参数为,Context类直接传入MainActivit。this即可,第二个参数为任意并且唯一的字符串,第三个参数为File类,传入outputStream。否则,就直接直接将File类即outputStream转化成Uri对象。这是因为在Android7.0之后,使用本地真实的Uri路径被认为不安全,会抛出FileUriExposedException异常。使用FileProvider这种特殊的内容提供器,可以对数据进行保护,对真实的Uri路径进行封装再共享给外部。接着新建Intent类,并将action指定为android.media.action.IMAGE_CAPTURE,并通关putExtra指定图片的输出地址,将imagUri传入,最后通过startActivityForResult方法启动活动。由于我们使用startActivityForResult方法启动活动,那需要重写onActivityResult()方法,当拍照成功就通过BitmapFactory类的decodeStream()将output_picture.jpg解码成Bitmap类,最终通过设置ImageView显示出来。
3.在res目录下新建一个存放.xml文件的目录,新建path.xml,修改代码:
其中external-path用来指定Uri共享的,name可以随便填,path表示共享的具体路径,空值表示共享整个SD卡。
4.修改AnroidManifest.xml代码,注册内容提供器,并对访问SD卡应用关联目录进行权限申请:
android:name 属性为固定值,android:authorities属性的值需要与MainActivity.java中的FileProvider类的getUriForFile()方法的第二个参数一样,meta-data标签指定共享路径。在Android 4.4之前,访问SD卡应用关联目录需要进行权限的申请,4.4之后就不需要了,但为了兼容老版本,我们还是需要对权限进行申请。
5.运行效果