Android调用系统照相机拍照与摄像的方法

前言

  在很多场景中,都需要用到摄像头去拍摄照片或视频,在照片或视频的基础之上进行处理。但是Android系统源码是开源的,很多设备厂商均可使用,并且定制比较混乱。一般而言,在需要用到摄像头拍照或摄像的时候,均会直接调用系统现有的相机应用,去进行拍照或摄像,我们只取它拍摄的结果进行处理,这样避免了不同设备的摄像头的一些细节问题。本篇博客将介绍在Android应用中,如何调用系统现有的相机应用去拍摄照片与短片,并对其进行处理,最后均会以一个简单的Demo来演示效果。

1、系统现有相机应用的调用

  对于如何调用系统现有应用,之前就有讲解,这里简单再说一下。在开发的应用中调用系统现有应用,需要使用Intent指定开启的应用的Action和Category,然后通过startActivity(Intent)或者startActivityForResult(Intent,int)开启指定的Activity,如果使用startActivityForResult()方法开启并需要返回值,再重写onActivityResult(int,int,Intent)即可。

  先来看看系统现有相机应用的AndroidManifest.xml清单文件定义的Activity:

<activity
  android:name="com.android.camera.Camera"
  android:clearTaskOnLaunch="true"
  android:configChanges="orientation|keyboardHidden"
  android:screenOrientation="landscape"
  android:taskAffinity="android.task.camera"
  android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <categroy android:name="android.intent.category.DEFAULT" />
  <categroy android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  <intent-filter>
  <action android:name="android.media.action.IMAGE_CAPTURE" />
  <categroy android:name="android.intent.category.DEFAULT" />
  </intent-filter>
  <intent-filter>
  <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
  <categroy android:name="android.intent.category.DEFAULT" />
  </intent-filter>
 </activity>
 <activity
  android:name="com.android.camera.VideoCamera"
  android:clearTaskOnLaunch="true"
  android:configChanges="origientation|keyboardHidden"
  android:label="@string/video_camera_label"
  android:screenOrientation="landscape"
  android:taskAffinity="android.task.camcorder"
  android:theme="@android:style/theme.Black.NoTitleBar.Fullscreen" >
  <intent-filter>
  <action android:name="android.media.action.VIDEO_CAMERA" />
  <categroy android:name="android.intent.category.DEFAULT" />
  </intent-filter>
  <intent-filter>
  <action android:name="android.media.action.VIDEO_CAPTURE" />
  <categroy android:name="android.intent.category.DEFAULT" />
  </intent-filter>
 </activity>

  它定义了两个Activity,com.android.camera.Camera表示照相机,com.android.camera.VideoCamera表示摄像机。从字面意思可以看出,为了捕获系统相机返回的数据,一般需要使用一下两个Action即可开启照相机与摄像机:

  • android.media.action.IMAGE_CAPTURE:Intent的Action类型,从现有的相机应用中请求一张图片。
  • android.media.action.VIDEO_CAPTURE:Intent的Action类型,从现有的相机应用中请求一段视频。

  上面两个参数,均在MediaStore类中以静态常量的形式定义好了,分别是:MediaStore.ACTION_IMAGE_CAPTURE(相机)和MediaStore.ACTION_VIDEO_CAPTURE(摄像机)。

2、系统现有相机拍摄照片

  上面介绍到,开启系统现有相机应用拍摄照片,需要用的MediaStore.ACTION_IMAGE_CAPTURE作为Intent的action开启Activity即可。但是在使用系统现有相机用用的时候,默认会把图片保存到系统图库的目录下,如果需要指定图片文件的保存路径,需要额外在Intent中设置。

  设置系统现有相机应用的拍摄照片的保存路径,需要用Intent.putExtra()方法通过MediaStore.EXTRA_OUTPUT去设置Intent的额外数据,这里传递的是一个Uri参数,可以是一个文件路径的Uri。

Intent intent=new Intent();
  // 指定开启系统相机的Action
  intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.addCategory(Intent.CATEGORY_DEFAULT);
  // 根据文件地址创建文件
  File file=new File(FILE_PATH);
  // 把文件地址转换成Uri格式
  Uri uri=Uri.fromFile(file);
  // 设置系统相机拍摄照片完成后图片文件的存放地址
  intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

3、获取系统现有相机拍摄的图片

  在新开启的Activity中,如果需要获取它的返回值,则需要使用startActivityForResult(Intent,int)方法开启Activity,并重写onActivityResult(int,int,Intent)获取系统相机的返回数据,那么我们只需要在onActivityResult()中获取到返回值即可。

  系统相机拍摄的照片,如果不指定路径,会保存在系统默认文件夹下,可以使用Intent.getExtra()方法得到,得到的是一个Uri地址,表示了一个内容提供者的地址。如果通过MediaStore.EXTRA_OUTPUT指定了保存路径,那么通过Intent.getExtra()得到的将是一个空地址,但是既然是我们指定的地址,那么也不愁找不到它了。

4、系统现有相机拍摄图片Demo

  上面讲解了如何在开发的应用中使用系统相机拍摄照片并获得它所涉及到的内容,下面通过一个简单的Demo演示一下。在Demo中,有两个Button分别以指定路径的方式和不指定路径的方式启动系统相机,并获取返回值显示到ImageView中,Demo中注释比较详细,这里不再累述了。

布局代码:activity_syscamera.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <Button
 android:id="@+id/btn_StartCamera"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="系统相机拍照--指定路径到SD卡" />
 <Button
 android:id="@+id/btn_StartCameraInGallery"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="系统相机拍照--默认图库" />
 <ImageView
 android:id="@+id/iv_CameraImg"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

</LinearLayout>

实现代码:SysCameraActivity.java

package cn.bgxt.callsystemcamera;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class SysCameraActivity extends Activity {
 private Button btn_StartCamera, btn_StartCameraInGallery;
 private ImageView iv_CameraImg;

 private static final String TAG = "main";
 private static final String FILE_PATH = "/sdcard/syscamera.jpg";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_syscamera);

 btn_StartCamera = (Button) findViewById(R.id.btn_StartCamera);
 btn_StartCameraInGallery = (Button) findViewById(R.id.btn_StartCameraInGallery);
 iv_CameraImg = (ImageView) findViewById(R.id.iv_CameraImg);

 btn_StartCamera.setOnClickListener(click);
 btn_StartCameraInGallery.setOnClickListener(click);
 }

 private View.OnClickListener click = new View.OnClickListener() {

 @Override
 public void onClick(View v) {

  Intent intent = null;
  switch (v.getId()) {
  // 指定相机拍摄照片保存地址
  case R.id.btn_StartCamera:
  intent = new Intent();
  // 指定开启系统相机的Action
  intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.addCategory(Intent.CATEGORY_DEFAULT);
  // 根据文件地址创建文件
  File file = new File(FILE_PATH);
  if (file.exists()) {
   file.delete();
  }
  // 把文件地址转换成Uri格式
  Uri uri = Uri.fromFile(file);
  // 设置系统相机拍摄照片完成后图片文件的存放地址
  intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
  startActivityForResult(intent, 0);
  break;
  // 不指定相机拍摄照片保存地址
  case R.id.btn_StartCameraInGallery:
  intent = new Intent();
  // 指定开启系统相机的Action
  intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.addCategory(Intent.CATEGORY_DEFAULT);
  startActivityForResult(intent, 1);
  break;
  default:
  break;
  }

 }
 };

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 Log.i(TAG, "系统相机拍照完成,resultCode="+resultCode);

 if (requestCode == 0) {
  File file = new File(FILE_PATH);
  Uri uri = Uri.fromFile(file);
  iv_CameraImg.setImageURI(uri);
 } else if (requestCode == 1) {
  Log.i(TAG, "默认content地址:"+data.getData());
  iv_CameraImg.setImageURI(data.getData());
 }
 }
}

效果展示:

 这里只是简单的演示了如何调用系统现有的相机应用获取拍摄的图片,没有做图片资源的回收,所以可能会有内存溢出的错误,重新启动应用即可。

5、系统现有相机拍摄视频

  从系统现有的相机应用中获取拍摄的视频,与获取拍摄的图片过程大致相同,但是它除了可以通过putExtra()设置MediaStore.EXTRA_OUTPUT输出路径外,还可以设置其它值,这里简单介绍一下:

  • MediaStore.EXTRA_OUTPUT:设置媒体文件的保存路径。
  • MediaStore.EXTRA_VIDEO_QUALITY:设置视频录制的质量,0为低质量,1为高质量。
  • MediaStore.EXTRA_DURATION_LIMIT:设置视频最大允许录制的时长,单位为毫秒。
  • MediaStore.EXTRA_SIZE_LIMIT:指定视频最大允许的尺寸,单位为byte。

6、系统现有相机拍摄视频Demo

  既然和拍摄照片的流程一样,这里就不再累述了,直接上Demo。在Demo中通过一个Button启动一个系统现有相机拍摄视频,最后保存在SD卡上。

实现代码:

package cn.bgxt.callsystemcamera;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SysVideoCameraActivity extends Activity {
 private Button btn_StartVideoCamera;
 private static final String FILE_PATH = "/sdcard/sysvideocamera.3gp";
 private static final String TAG="main";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_sysvideocamera);

 btn_StartVideoCamera = (Button) findViewById(R.id.btn_StartVideoCamera);
 btn_StartVideoCamera.setOnClickListener(click);
 }

 private View.OnClickListener click = new View.OnClickListener() {

 @Override
 public void onClick(View v) {
  Intent intent = new Intent();
  intent.setAction("android.media.action.VIDEO_CAPTURE");
  intent.addCategory("android.intent.category.DEFAULT");
  File file = new File(FILE_PATH);
  if(file.exists()){
  file.delete();
  }
  Uri uri = Uri.fromFile(file);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
  startActivityForResult(intent, 0);
 }
 };

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 Log.i(TAG, "拍摄完成,resultCode="+requestCode);
 }

}

效果展示:

源码下载:Android调用系统照相机拍照与摄像

总结

到此就把如何使用系统现有相机应用拍摄照片与视频都讲解清楚了,在非相机相关的项目中,如果需要拍照的话,一般都是调用系统现有的相机应用,而不会直接调用Camera硬件去获取图像。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android使用系统自带的相机实现一键拍照功能

    今天分享的是用系统自带的相机实现一键拍照功能. public class MainActivity extends AppCompatActivity { private static final int TAKE_PHOTO = 100; private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setConte

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

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

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

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

  • Android 实现调用系统照相机拍照和录像的功能

    本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_heig

  • Android自定义组件获取本地图片和相机拍照图片

    iOS中有封装好的选择图片后长按出现动画删除效果,效果如下 而Android找了很久都没有找到有这样效果的第三方组件,最后懒得找了还是自己实现这效果吧 选择图片后还可对图片进行剪裁 当然,代码中还有很多不完善的地方,我接下来会继续完善这个组件的 已经上传到开源社区,欢迎大家来Star啊~ Demo源码:传送门 设计中的碰到的一些问题和解决思路 1.如何让加号图片显示在GridView最后面 首先在调用GridAdapter构造方法时就加载加号图片 /** * 图片适配器 * @param con

  • Android自定义相机实现定时拍照功能

    这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能. 首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: activity_main.xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="m

  • 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 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启动相机拍照并返回图片

    具体实现过程请看下面代码: 简单的调用了一下系统的拍照功能 代码如下所示: //拍照的方法 private void openTakePhoto(){ /** * 在启动拍照之前最好先判断一下sdcard是否可用 */ String state = Environment.getExternalStorageState(); //拿到sdcard是否可用的状态码 if (state.equals(Environment.MEDIA_MOUNTED)){ //如果可用 Intent intent

  • Android实现从本地图库/相机拍照后裁剪图片并设置头像

    玩qq或者是微信的盆友都知道,这些聊天工具里都要设置头像,一般情况下大家的解决办法是从本地图库选择图片或是从相机拍照,然后根据自己的喜爱截取图片.上述过程已经实现好了,最后一步我加上了把截取好的图片在保存到本地的操作,来保存头像.为了大家需要,下面我们小编把完整的代码贴出来供大家参考. 先给大家展示效果图: 代码部分: 布局代码(其实就是两个按钮和一个ImageView来显示头像) <LinearLayout xmlns:android="http://schemas.android.co

  • Android自定义照相机倒计时拍照

    自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: 两个TextView是用来显示提示信息和倒计时的秒数的 相关教程:Android开发从相机或相册获取图片裁剪 Android启动相机拍照并返回图片 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&qu

  • Android 调用系统照相机拍照和录像

    本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_heig

  • Android编程实现调用相册、相机及拍照后直接裁剪的方法

    本文实例讲述了Android编程实现调用相册.相机及拍照后直接裁剪的方法.分享给大家供大家参考,具体如下: package com.cvte.health.phone; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.content.ContentResolver; import android.co

随机推荐