android调用摄像头拍照的功能实现
该功能使用到的场景比较多,下面能过一个实例介绍其使用,布局比较简单只有两个控件,上面Button下面ImageView,Button用于打开摄像头进行拍照,而ImageView用于将拍到的图片显示出来。
public class CameraTestActivity extends AppCompatActivity { public static final int TAKE_PHOTO = 1; private ImageView picture; private Uri imageUri; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera_test); Button takePhoto = (Button)findViewById(R.id.take_photo); picture = (ImageView)findViewById(R.id.picture); takePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { File outputImage = new File(getExternalCacheDir(), "output_image.jpg"); try{ if (outputImage.exists()){ outputImage.delete(); } outputImage.createNewFile(); }catch (IOException e){ e.printStackTrace(); } if (Build.VERSION.SDK_INT >= 24){ //android7.0及以上 imageUri = FileProvider.getUriForFile(CameraTestActivity.this, "com.example.cameratest.fileprovider", outputImage); }else { imageUri = Uri.fromFile(outputImage); } //启动相机程序 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, TAKE_PHOTO); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode){ case TAKE_PHOTO: if (resultCode == RESULT_OK){ try { Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)); picture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } break; default: break; } } }
首先创建一个File对象,用于存放摄像头拍下的图片,这里将图片命名为output_image.jpg,并将它存放在手机SD卡的应用关联缓存目录下。什么叫做应用关联缓存目录呢?就是指SD卡中专门用于存放当前应用缓存数据的位置,调用getExternalCacheDir()方法可以得到这个目录,具体的路径是/sdcard/Android/data/(package name)/cache。那么为什么要使用应用关联缓存目录来存放图片呢?因为从Android6.0系统开始,读写SD卡被列为危险权限,如里将图片存放在SD卡的任何其它目录,都要进行运行时权限处理才行,而使用应用关联目录则可以跳过这一步。
接着进行一个判断,如果运行设备的系统版本低于Android7.0,就调用Uri的fromFile()方法将File对象转换成Uri对象,这个Uri对象标识着output_image.jpg这张图片的本地真实路径。否则,就调用FileProvider的getUriForFile()方法将File对象转换成一个封装过的Uri对象。之所以要进行这样一层转换,是因为从Android7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,会抛出一个FileUriExposedException异常。而FileProvider是一种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性。
因为使用到了内容提供器FileProvider,自然需要在AndroidManifest.xml中进行注册。
......
其中,android:name属性的值是固定的,android:authorities属性的值必须要和刚才FileProvider.getUriForFile()方法中的第二个参数一致。另外,这里还在
其中,external-path就是用来指定Uri共享的,name属性的值可以随便填,path属性的值表示共享的具体路径。这里设置空值就表示将整个SD卡进行共享,当然也可仅共享我们存放output_image.jpg这张图片的路径。
另外还有一点要注意,在Android4.4系统之前,访问SD卡的应用关联目录也是要声明权限的,从4.4系统开始不再需要权限声明。那么我们为了兼容老版本系统的手机,还需要在清单文件中声明一下访问SD卡的权限:
推荐阅读
-
Android编程使用加速度传感器实现摇一摇功能及优化的方法详解
-
Android编程实现点击EditText之外的控件隐藏软键盘功能
-
Android悬浮球及全局返回功能的实现示例
-
python+opencv打开摄像头,保存视频、拍照功能的实现方法
-
Android Recyclerview实现多选,单选,全选,反选,批量删除的功能
-
Android开发实现的IntentUtil跳转多功能工具类【包含视频、音频、图片、摄像头等操作功能】
-
Android开发之ListView功能扩展,实现高性能的瀑布流布局讲解
-
Android开发实现的图片浏览功能示例【放大图片】
-
Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能详解
-
Android开发使用Activity嵌套多个Fragment实现横竖屏切换功能的方法