可以参考:http://www.android-doc.com/guide/topics/media/camera.html

一、添加相应的权限

 <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" /><!-- 拍照的功能 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape"><!-- 写死横屏 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
 </activity>

二、布局文件的配置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

三、系统关键代码和注释

创建预览类CameraPreview:

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    public static final String TAG = "camera";
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        //获取surfaceview的控制器
        mHolder = getHolder();
        //创建侦听
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            //设置摄像头预览界面在holder对应的那个surfaceview
            mCamera.setPreviewDisplay(holder);
            //开始预览
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

主类MainActivity:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(checkCameraHardware(this)){
            // Create an instance of Camera
            //创建摄像头实例
            mCamera = getCameraInstance();
        } else {
            return;
        }

        // Create our Preview view and set it as the content of our activity.
        //创建预览类的对象
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        //把预览类设置为帧布局的子节点
        preview.addView(mPreview);

        //给按钮设置监听
        Button captureButton = (Button) findViewById(R.id.button_capture);
        captureButton.setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //设置聚焦
                    mCamera.autoFocus(new AutoFocusCallback() {

                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {
                             //进行拍照
                            mCamera.takePicture(null, null, mPicture);
                        }
                    });

                }
            }
        );
    }

    /** 检测手机是否有摄像头 */
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    /** 一个获取摄像头对象的安全实例 */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); //获取第一个后置摄像头的实例
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    private PictureCallback mPicture = new PictureCallback() {

        //拍照时会调用此方法
        //data:照片的字节数组
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            try {
                File pictureFile = new File("sdcard/mr.jpg");
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d(CameraPreview.TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(CameraPreview.TAG, "Error accessing file: " + e.getMessage());
            } finally {
                //拍照完成后重新进入预览
                camera.startPreview();
            }
        }
    };

}

显示效果:

Android中实现自定义的拍照应用的更多相关文章

  1. Android中制作自定义dialog对话框的实例

    http://www.jb51.net/article/83319.htm   这篇文章主要介绍了Android中制作自定义dialog对话框的实例分享,安卓自带的Dialog显然不够用,因而我们要继 ...

  2. Android 中使用自定义字体的方法

    1.Android系统默认支持三种字体,分别为:“sans”, “serif”, “monospace 2.在Android中可以引入其他字体 . <?xml version="1.0 ...

  3. Android中的自定义Adapter(继承自BaseAdapter)——与系统Adapter的调用方法一致——含ViewHolder显示效率的优化(转)

    Android中很多地方使用的是适配器(Adapter)机制,那我们就要好好把这个Adapter利用起来,并且用出自己的特色,来符合我们自行设计的需要喽~~~ 下面先上一个例子,是使用ViewHold ...

  4. Android中的自定义视图控件

    简介 当现有控件不能满足需求时,就需要自定义控件. 自定义控件属性 自定义控件首先要继承自View,重写两个构造函数. 第一个是代码中使用的: public MyRect(Context contex ...

  5. Android中使用自定义View实现下载进度的显示

    一般有下载功能的应用都会有这样一个场景,需要一个图标来标识不同的状态.之前在公司的项目中写过一个,今天抽空来整理一下. 一般下载都会有这么几种状态:未开始.等待.正在下载.下载结束,当然有时候会有下载 ...

  6. android中通过自定义xml实现你需要的shape效果 xml属性配置

    在Android开发过程中,经常需要改变控件的默认样式, 那么通常会使用多个图片来解决.不过这种方式可能需要多个图片,比如一个按钮,需要点击时的式样图片,默认的式样图片,然后在写一个selector的 ...

  7. Android中的自定义注解(反射实现-运行时注解)

    预备知识: Java注解基础 Java反射原理 Java动态代理 一.布局文件的注解 我们在Android开发的时候,总是会写到setContentView方法,为了避免每次都写重复的代码,我们需要使 ...

  8. android中checkbox自定义样式

    1.首先res/drawable中定义checkbox_style.xml样式: <?xml version="1.0" encoding="utf-8" ...

  9. android中实现自定义广播

    自定义广播分两个步骤:1.发送广播 2.接收广播 一.先看如何接收广播: 我使用的是Android Studio,File->New->Other->Broadcast Receiv ...

随机推荐

  1. 160个crackme-之Afkayas.1

    工具: OD 环境: windows XP 运行: 我们先运行一下这个小程序,看看它到底是干什么的.运行后发现它要我们输入Type In your Name 和Type In your Serial ...

  2. 116、Android获取Manifest中&lt;meta-data&gt;元素的值

    在AndroidManifest.xml中,<meta-data>元素可以作为子元素, 被包含在<activity>.<application> .<serv ...

  3. EF 底层基础方法

    1 using System; 2 using System.Data; 3 using System.Collections.Generic; 4 using System.Data.Entity; ...

  4. 关于mac下面用Parallels装ubuntu时分辨率问题[已解决]

    最近由于要深入下Android系统,在Parallels虚拟机上安装了ubuntu系统,刚开始安装成功的时候,分辨率只有800*600.本来想着去设置里面改动呢,可是坑爹的是设置里面只有800*600 ...

  5. top free综合监控工具

    top选项: -d:指定刷新时间间隔 -n:指定刷新次数 -u:指定只显示user用户的进程信息 -p:指定只显示pid的进程信息 [root@linuxzgf ~]# top Mem: 817449 ...

  6. Linux下tmpfs介绍及使用

    tmpfs介绍 tmpfs是一种虚拟内存文件系统,而不是块设备.是基于内存的文件系统,创建时不需要使用mkfs等初始化它最大的特点就是它的存储空间在VM(virtual memory),VM是由lin ...

  7. eclipse配置mahout

    1.在elcipse上建立一个java project 项目名:mymahout 2.建立libs文件夹,在mahout 0.9的lib文件夹下找到一下java包 其中log4j.properties ...

  8. Qt on Android

    Qt on Android Episode 7(翻译) http://blog.csdn.net/foruok/article/details/46323129 Android基础整理之四大组件Act ...

  9. Google Map 根据坐标 获取地址信息

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.X ...

  10. hadoop 测试框架

    hadoop 0.21以前的版本中(这里拿0.20为例,其他版本可能有少许不同),所有的测试相关代码都是放置在${HADOOP_HOME}/src/test下,在该目录下,是按照不同的目录来区分针对不 ...