Android开发教程之调用摄像头功能的方法详解

本文实例讲述了Android调用摄像头功能的方法。分享给大家供大家参考,具体如下:

我们要调用摄像头的拍照功能,显然

第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码

摄像头权限:

<uses-permission android:name="android.permission.CAMERA"/>

SD卡读写权限:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

第二步,要将摄像头捕获的图像实时地显示在手机上

我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码

<SurfaceView
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:id="@+id/surfaceview"
 />

第三步,设置窗口的显示方式

首先获得当前窗口

Window window = getWindow();//得到窗口

接着设置没有标题

requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题

接着设置全屏

代码如下:

window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏

当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码

代码如下:

window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮

至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)

setContentView(R.layout.main);

第四步,设置SurficeView显示控件的属性

找到surficeView

surfaceView = (SurfaceView) findViewById(R.id.surfaceview);

设置它的像素为800x600

surfaceView.getHolder().setFixedSize(800, 480);
//下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

第五步,就是为surficeView加入回调方法(callBack)

surfaceView.getHolder().addCallback(new SurfaceCallback());

上面的回调类是我们自己定义的,代码如下

private class SurfaceCallback implements SurfaceHolder.Callback{
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器
Display display = wm.getDefaultDisplay();//得到当前屏幕
Camera.Parameters parameters = camera.getParameters();//得到摄像头的参数
parameters.setPreviewSize(display.getWidth(), display.getHeight());//设置预览照片的大小
parameters.setPreviewFrameRate(3);//设置每秒3帧
parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的格式
parameters.setJpegQuality(85);//设置照片的质量
parameters.setPictureSize(display.getHeight(), display.getWidth());//设置照片的大小,默认是和   屏幕一样大
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面
camera.startPreview();//开始预览
isPreview = true;//设置是否预览参数为真
} catch (IOException e) {
Log.e(TAG, e.toString());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
if(isPreview){//如果正在预览
camera.stopPreview();
camera.release();
}
}
}
}

第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下

public boolean onKeyDown(int keyCode, KeyEvent event) {//处理按键事件
if(camera!=null&&event.getRepeatCount()==0)//代表只按了一下
{
switch(keyCode){
case KeyEvent.KEYCODE_BACK://如果是搜索键
   camera.autoFocus(null);//自动对焦
 break;
  case KeyEvent.KEYCODE_DPAD_CENTER://如果是中间键
   camera.takePicture(null, null, new TakePictureCallback());//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中
 break;
}
}
return true;//阻止事件往下传递,否则按搜索键会变成系统默认的
}
private final class TakePictureCallback implements PictureCallback{
public void onPictureTaken(byte[] data, Camera camera) {
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, outputStream);
outputStream.close();
camera.stopPreview();
camera.startPreview();//处理完数据之后可以预览
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}

注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。

至此,简单的拍照功能介绍完毕!

package cn.camera.rxm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
import org.apache.commons.logging.Log;
import android.text.format.DateFormat;
import android.util.*;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
//import android.widget.Toast;
public class MycamActivity extends Activity {
private Preview mPreview;
private Camera mCamera;
Bitmap CameraBitmap;
SurfaceHolder mHolder;
private static final int OPTION_SNAPSHOT = 0;
private static final int OPTION_STOPCAMERA = 1;
private View viewStart;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LayoutInflater flater = this.getLayoutInflater();
    viewStart = flater.inflate(R.layout.main, null);
    setContentView(viewStart);
    Button btn1 = (Button)findViewById(R.id.button1);
    btn1.setOnClickListener(
    new OnClickListener(){
    public void onClick(View v){
    mPreview = new Preview(getBaseContext());
    setContentView(mPreview);
    };
    }
    );
  }
  public boolean onCreateOptionsMenu(Menu menu){
//
menu.add(0, OPTION_SNAPSHOT, 0, R.string.take);
//
menu.add(0, OPTION_STOPCAMERA, 1, R.string.back);
//
return true;//super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
//
int itemId = item.getItemId();
//
switch(itemId){
case OPTION_SNAPSHOT:
//拍摄照片
mCamera.takePicture(null, null, jpegCallback);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
break;
case OPTION_STOPCAMERA:
mPreview = null;
setContentView(viewStart);
break;
}
return true;
}
private PictureCallback jpegCallback = new PictureCallback(){
//
public void onPictureTaken(byte[] data, Camera camera) {
try {
String name = new DateFormat().format("yyyyMMdd_hhmmss",
Calendar.getInstance(Locale.CHINA)) + ".jpg";
FileOutputStream fileout = new FileOutputStream("/mnt/sdcard/sdcard/DCIM/"+ name);
System.out.println(name);
fileout.write(data,0,data.length);
fileout.flush();
fileout.close();
} catch (IOException e) {
// TODO: handle exception
System.out.println(e);
}
}
};
class Preview extends SurfaceView implements SurfaceHolder.Callback
{
Preview(Context context)
{
super(context);
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
mCamera=Camera.open();
try
{
mCamera.setPreviewDisplay(holder);
}
catch(IOException exception)
{
mCamera.release();
mCamera=null;
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
mCamera.stopPreview();
mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// TODO Auto-generated method stub
Camera.Parameters parameters=mCamera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPreviewSize(1024, 1024);
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
}
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android文件操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

时间: 2016-06-26

Android编程实现摄像头临摹效果的方法

本文实例讲述了Android编程实现摄像头临摹效果的方法.分享给大家供大家参考,具体如下: 这篇文章结合本人的开发实例,介绍如何实现摄像头临摹效果,即将摄像头拍摄的画面作为临摹的物体投射到画纸上,用户可以在画纸上继续作画,效果如图1. 主要可以分成四步,第一步在AndroidManifest.xml文件里添加对摄像机的使用许可. <uses-permissionandroid:name="android.permission.CAMERA"/> 第二步在布局文件里使用fra

Android中判断是否有前置摄像头、后置摄像头的方法

通常我们进行摄像头操作,如扫描二维码需要判断是否有后置摄像头(Rear camera),比如Nexus 7 一代就没有后置摄像头,这样在尝试使用的时候,我们需要进行判断进行一些提示或者处理. 以下代码为一系列的方法,用来判断是否有前置摄像头(Front Camera),后置摄像头. 复制代码 代码如下: private static boolean checkCameraFacing(final int facing) {     if (getSdkVersion() < Build.VERS

Android判断用户是否允许了摄像头权限实例代码

如题,既然是判断用户是否允许了摄像头权限,那么,咱们就忽略是Manifest配置的问题,因为这是开发者的事. 用户在使用APP时,如果首次进入用摄像头的地方,手机会提示是否允许该应用使用摄像头.有些用户小手一抖.或者压根就不想开启摄像头,咔擦,就给你关了,那好了.下回再进入该功能,就会出现APP一片黑,或者崩溃的情况. 作为开发者,正常思路是要提示用户,摄像头权限被你关了,赶紧去手动开启,不然,就别想用该功能了!那,咱们该怎么实现这个思路呢? 一.判断摄像头权限 Android API没提供判断

android开发之调用手机的摄像头使用MediaRecorder录像并播放

我们玩玩手机的录像功能吧.做个DEMO. 看看录制过程: 复制代码 代码如下: mediarecorder = new MediaRecorder();// 创建mediarecorder对象 // 设置录制视频源为Camera(相机) mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4 mediarecorder.setOutputFo

Android实现调用摄像头

应用场景: 在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用. 知识点介绍: 使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature 1. 摄像头相关权限设置 <!--摄像头权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存

Android 开发随手笔记之使用摄像头拍照

在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面. 我们要添加如下权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> 1.调用系统Camera 调用系统

Android调用前后摄像头同时工作实例代码

硬件环境:小米4 Android版本:6.0 咱们先看效果图: 我把代码贴出来: AndroidMainfest.xml文件(需要新增camera权限): <uses-permission android:name="android.permission.CAMERA" /> activity_main.xml文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayo

Android实现手机摄像头的自动对焦

如何实现Android相机的自动对焦,而且是连续自动对焦的.当然直接调用系统相机就不用说了,那个很简单的.下面我们主要来看看如如何自己实现一个相机,并且实现自动连续对焦. 代码如下: public class MainActivity extends Activity { private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private boolean flag = false; private Strin

Android实现调用摄像头进行拍照功能

现在Android智能手机的像素都会提供照相的功能,大部分的手机的摄像头的像素都在1000万以上的像素,有的甚至会更高.它们大多都会支持光学变焦.曝光以及快门等等. 下面的程序Demo实例示范了使用Camera v2来进行拍照,当用户按下拍照键时,该应用会自动对焦,当对焦成功时拍下照片. layout/activity_main.xml界面布局代码如下: <?xml version="1.0" encoding="utf-8"?> <manifes

Android实现调用摄像头和相册的方法

Android调用摄像头是很方便的.先看一下界面 布局文件activity_main.xml源码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:l

Android实现调用摄像头拍照与视频功能

应用场景: 在Android开发过程中,有时需要调用手机自身设备的功能,上篇文章主要侧重摄像头拍照功能的调用.本篇文章将综合实现拍照与视频的操作. 知识点介绍: 该部分请阅读 [Android 调用摄像头功能] 使用方式: 第一步: 新建一个Android项目CameraPhotoVedio,包含两个Activity: MainActivity.CameraActivity. 第二步: activity_main.xml <RelativeLayout xmlns:android="htt

AngularJS中使用HTML5手机摄像头拍照

1. 项目背景 公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能.因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照.起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的. 这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图: 2. 如何调用摄像头 $scope.photoErr = false; $scope.photoBtnDiable = true; var mediaStream = null,track = nu

Android获取手机屏幕宽高、状态栏高度以及字符串宽高信息的方法

本文实例讲述了Android获取手机屏幕宽高.状态栏高度以及字符串宽高信息的方法.分享给大家供大家参考.具体如下: 首先定义TextView对象commentText 获取文字的宽高: TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); textPaint.setTextSize(commentText.getTextSize()); textPaint.setColor(Color.WHITE); FontMetrics fo

android 获取手机内存及 内存可用空间的方法

实例如下: //1.获取内存可用大小,内存路径 String path=Environment.getDataDirectory().getAbsolutePath(); String memoryAvaliSpace= Formatter.formatFileSize(this,getAvailSpace(path)); //2.获取sd卡可用大小,sd卡路径 String sdPath=Environment.getExternalStorageDirectory().getAbsolute

Android实现手机振动设置的方法

本文实例讲述了Android实现手机振动设置的方法.分享给大家供大家参考.具体如下: main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" androi

Android调用手机拍照功能的方法

本文实例讲述了Android调用手机拍照功能的方法.分享给大家供大家参考.具体如下: 一.main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" andr

Android自定义手机界面状态栏实例代码

前言 我们知道IOS上的应用,状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,那安卓是否可以呢?若是在安卓4.4之前,答案是否定的,但在4.4之后,谷歌允许开发者自定义状态栏背景颜色啦,这是个不错的体验!若你手机上安装有最新版的qq,并且你的安卓SDK版本是4.4及以上,你可以看下它的效果: 实现这个效果有两个方法: 1.在xml中设置主题或自定义style: Theme.Holo.Light.NoActionBar.TranslucentDecor Theme.Holo.NoActi