Android使用系统相机进行拍照的步骤

前言

我们在日常的开发中有时候会遇到需要用到相机的需求,而相机也是很常用的东西,例如扫二维码啊拍照上传啊等等。这里我不讲像qq那样自定义很强的拍照功能(事实上我也不会),讲个最简单的调用系统相机拍照并储存

调用系统相机步骤

这里我通过一个简单的例子来讲这个内容。
我自己写了一个demo,布局很简单:

<Button
 android:id="@+id/button"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="4dp"
 android:text="take phone"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintHorizontal_bias="0.281"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />

 <ImageView
 android:id="@+id/imageView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="29dp"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toBottomOf="@+id/button"
 app:srcCompat="@mipmap/ic_launcher_round" />

就是一个按钮点击弹起相机,然后一个imageView显示拍到的照片。

接下来我想一下调用的整个过程我们需要做什么:
首先弹起相机肯定要跳到相机这个应用,那么就必须通过隐性启动相机的活动。
然后当我们返回应用的时候,还要将照片显示,所以这里就要用到startActivityForResult这个方法。
其次,我们拍照之后肯定要进行储存的,那么就涉及到文件的操作。
涉及到内存的操作就肯定要和权限打交道,所有还有权限相关的内容。
最后还有一个问题就是,相机拍完照是要储存照片的,所以我们要给他一个地址uri,但是可不可以直接把地址当成参数发过去呢?这里就要用到特殊的内容提供器FileProvider。
上面就是调用相机要用到的内容,虽然用的都很浅,但是都会涉及到。接下来看看具体怎么实现。看看Activity中的onCreate的代码:

 private Uri imageUri;
 private ImageView imageView;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 imageView = findViewById(R.id.imageView);

 Button button = findViewById(R.id.button);
 button.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {

  //创建一个File对象。getExternalCacheDir()获取应用的缓存目录,outputImage.jpg是照片名称
  File outputImage = new File(getExternalCacheDir(),"outputImage.jpg");
  try{
  //创建一个空文件
   outputImage.createNewFile();
  }catch (IOException e){
   e.printStackTrace();
  }

  //不同的安卓版本对用不同的获取Uri的方法
  if (Build.VERSION.SDK_INT>=24){
   imageUri =FileProvider.getUriForFile(MainActivity.this,"huan",outputImage);
  }else{
   imageUri = Uri.fromFile(outputImage);
  }

  //启动相机的对应Activity
  Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
  intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
  startActivityForResult(intent,1);
  }
 });

我们来看看这里的代码:前面的代码很简单就是控件的初始化。
我们知道照片是要放文件夹得,所以这里要创建一个File对象,指定文件的路径以及名字。这里路径为什么要用getExternalCacheDir()呢?因为每个应用都有对应得缓存目录,访问这些目录得时候不用访问内存权限,这样得话就可以省去需求权限得步骤啦。这个目录在/scare/Android/data//cache。

然后我们再创建一个空的文件夹。这里如果已经有照片了的话例如我们第二次拍照的时候,那么就不会创建新的空文件夹了。直到储存的时候才会被替换掉。

然后我们刚才讲到,拍到的图片要在我们的应用中展示,那么就必须用到内容提供器。这里用到FileProvider来获取uri,关于provider我在下文有讲到可以
如果是低于4.4版本的安卓就用Uri.fromFile(outputImage);方法可以获取到uri

再通过隐式启动相机activity可以打开相机了。这里系统相机的action是android.media.action.IMAGE_CAPTURE,相机储存路径的参数名字是MediaStore.EXTRA_OUTPUT,并把uri传输进去。

好了这样就完成了拍照并把照片储存的步骤了。接下来还差什么?对了,把照片显示出来。现在在内存中已经有这个照片了,而且uri也知道,所以就很容易了,看代码:

 @Override
 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
 if (requestCode == 1) {
  if (resultCode == RESULT_OK)
  try {
   Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
   imageView.setImageBitmap(bitmap);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
 }
 }

我们刚才使用startActivityForResult来启动活动的,所以就要重写这个方法来显示图片了。这里首先判断是哪个启动命令,然后再判断是否成功启动,再BitmapFactory.decodeStream这个方法来获取bitmap,再把bitmap显示出来就行了。BitmapFactory.decodeStream这个方法需要一个流,可以通过getContentResolver().openInputStream这个方法来开启一个流。

到此整个流程就解决了。

FileProvider

FileProvider是一个特殊的内容提供器,可以把一个file开头的uri改成content开头的,例如:file://uri -> content://uri。那为什么要这么做呢?这里简单讲一下:
这个是因为在Android 7.0之后,官方禁止直接把一个真实路径的uri传输到别的应用,而我们要把地址送给相机,所以就会出现问题了。详细可以查阅这篇博客:Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

既然是内容提供器那么肯定是要进行注册的:

<provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="huan"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/file_paths" />
 </provider>

这里的authorities参数必须和前面的getUriForFile方法的第二个参数保持一致,同个内容提供器的authorities肯定要一样啦。grantUriPermissions参数一定要是true,这个的大概意思就是给他的所有元素授权可以被访问,在FileProvider中这个参数必须是true(这也是为什么在4.4一下版本的安卓无法使用的原因之一,有兴趣可以去了解一下)export这个参数表示可不可以给其他的应用共享,这里要设置为false。<meta-data这个是配置我们可以访问的文件路径,@xml/file_paths这个就是表示什么文件可以被访问,当然要建一个这个文件。看代码:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
 <external-path
 name="my_image"
 path="/"/>
</paths>

<external-path这个就是表示可以被访问的路径,name是后面映射用到的,可以自己随便起,我这里用一横杆表示整个目录可以被访问。

小结

调用系统相机的功能虽然不难,代码也不多,但是其中的零碎知识很多,零零散散,还是要注意的。特别是关于低高配的安卓版本问题还是要特别注意一下。

以上就是Android使用系统相机进行拍照的步骤的详细内容,更多关于Android 适用系统相机的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android 拍照选择图片并上传功能的实现思路(包含权限动态获取)

    作为一个Android新手,想实现手机拍照并上传的功能,经过查找资料,已实现此功能.在此记录备忘.老鸟请忽略. 一.实现思路: 1.Android手机客户端,拍照(或选择图片),然后上传到服务器. 2.服务器端接收手机端上传上来的图片. 二.实现步骤: 1.按惯例,先放效果图: 项目结构: 2.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a

  • Android实现静默拍照功能

    本文实例为大家分享了Android实现静默拍照功能的具体代码,供大家参考,具体内容如下 1.申请权限(6.0以后要动态申请) <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission and

  • android 7自定义相机预览及拍照功能

    本文实例为大家分享了Android实现摄像头切换,拍照及保存到相册,预览等功能,解决android7拍照之后不能连续预览的问题.参数设置相关问题以及前后摄像头语言颠倒等问题. import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; imp

  • android实现简单拍照功能

    拍照可以调用系统的相机进行拍照,拍完保存到相应的SD卡目录.最近要用到拍照这个功能,首先试了下调用相机拍照,保存到相应目录,然后用imageview显示的时候感觉,很模糊.可能是图片被压缩的太狠了.所以自己使用Camera写了一个拍照的功能,拍出来的还挺清晰的,不过文件有点大一张图片差不多1.7M.如果想拍高清图可以使用下面的代码. 代码很简单,我就不做过多解释了. package com.example.testsimple; import java.io.File; import java.

  • Android如何调用系统相机拍照

    本文实例为大家分享了Android调用系统相机拍照的具体代码,供大家参考,具体内容如下 /** * 调用系统相机 */ private void takePhoto() { Uri uri = null; if (which_image == FRONT_IMAGE) { frontFile = new File(getSDPath() +"/test/front_" + getDate() + ".jpg"); uri = Uri.fromFile(frontFi

  • Android快速实现无预览拍照功能

    本文实例为大家分享了Android实现无预览拍照功能的具体代码,供大家参考,具体内容如下 实现思路: 把预览的SurfaceView的宽高设置为肉眼看不出的值,例如0.1dp,其他的就是自定义相机的标准步骤了! 当然,网上自定义相机的文章多的去了,我是不可能再做老生常谈的事的,在这里我推荐一个很好用的第三方库,也许很多人已经了解过并且用过,没用过的同学可以试试,亲测好用. 废话不多说,先上源码地址 这里简单介绍一下用法: 1.在gradle里添加库的依赖:compile 'com.wonderk

  • Android打开系统相机并拍照的2种显示方法

    本文实例为大家分享了Android打开系统相机并拍照的具体实现代码,供大家参考,具体内容如下 目标效果: 第二张为点击第一个按钮拍照后显示的,比较模糊,第三章为点击第二个按钮拍照后显示的,比较清楚. 1.activity_main.xml页面设置布局. activity_main.xml页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="h

  • 适配AndroidQ拍照和读取相册图片的实现方法

    Google发行Android Q版本也有很长一段时间了,华为应用市场已经要求要适配Android Q版本了,所以,我们也要去对Android Q进行适配. 先讲一下咱们这节用到的新特性 Android Q文件存储机制修改成了沙盒模式,类似于iOS 应用只能访问自己沙盒下的文件和公共媒体文件 如果有想具体了解Android Q新版特效的可以去 官方文档 我们在这个地方记录一下Android Q版本进行拍照保存到相册的功能. 权限问题 Android Q不再需要申请文件读写权限,默认可以读写自己沙

  • 微信小程序实现点击拍照长按录像功能的实现代码

    代码里面注释写的都很详细,直接上代码.官方的组件属性中有触摸开始和触摸结束属性.本功能依靠这些属性实现. .wxml代码: <!-- 相机 pages/camera/camera.wxml--> <!-- 相机 --> <camera wx:if="{{!videoSrc}}" device-position="back" flash="off" binderror="error" style=&

  • Android 系统相机拍照后相片无法在相册中显示解决办法

    Android 系统相机拍照后相片无法在相册中显示解决办法 目前自己使用发送广播实现了效果 public void photo() { Intent openCameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(openCameraIntent, TAKE_PICTURE); } 解决方法: protected void onActivityResul

随机推荐