Android手机拍照

参考:

视频教程:http://v.youku.com/v_show/id_XNjI5MzkzMjQ4.html

官方API档file:///D:/Android/androidstudio/sdk/docs/guide/topics/media/camera.html

java程序

  1 package com.example.x_yp.system_camera;
  2 
  3 
  4 import java.io.File;
  5 import java.io.FileOutputStream;
  6 
  7 import android.os.Bundle;
  8 import android.util.Log;
  9 import android.view.View;
 10 import android.widget.Button;
 11 import android.widget.FrameLayout;
 12 import android.app.Activity;
 13 import android.content.Context;
 14 import android.content.pm.PackageManager;
 15 import android.hardware.Camera;
 16 import android.hardware.Camera.AutoFocusCallback;
 17 import android.hardware.Camera.PictureCallback;
 18 
 19 public class MainActivity extends Activity {
 20     protected static final String TAG = "main";
 21     private Camera mCamera;
 22     private CameraPreview mPreview;
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27 
 28         mCamera = getCameraInstance();
 29 
 30         // 创建预览类,并与Camera关联,最后添加到界面布局中
 31         mPreview = new CameraPreview(this, mCamera);
 32         FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
 33         preview.addView(mPreview);
 34 
 35 
 36         Button captureButton = (Button) findViewById(R.id.button_capture);
 37         captureButton.setOnClickListener(new View.OnClickListener() {
 38             @Override
 39             public void onClick(View v) {
 40                 // 在捕获图片前进行自动对焦
 41                 mCamera.autoFocus(new AutoFocusCallback() {
 42                     
 43                     @Override
 44                     public void onAutoFocus(boolean success, Camera camera) {
 45                         // 从Camera捕获图片
 46                         mCamera.takePicture(null, null, mPicture);
 47                     }
 48                 });                
 49             }
 50         });
 51     }
 52 
 53     /** 检测设备是否存在Camera硬件 */
 54     private boolean checkCameraHardware(Context context) {
 55         if (context.getPackageManager().hasSystemFeature(
 56                 PackageManager.FEATURE_CAMERA)) {
 57             // 存在
 58             return true;
 59         } else {
 60             // 不存在
 61             return false;
 62         }
 63     }
 64 
 65     /** 打开一个Camera */
 66     public static Camera getCameraInstance() {
 67         Camera c = null;
 68         try {
 69             c = Camera.open(); 
 70         } catch (Exception e) {
 71             Log.d(TAG, "打开Camera失败失败");
 72         }
 73         return c; 
 74     }
 75 
 76     private PictureCallback mPicture = new PictureCallback() {
 77 
 78         @Override
 79         public void onPictureTaken(byte[] data, Camera camera) {
 80             // 获取Jpeg图片,并保存在sd卡上
 81             File pictureFile = new File("/sdcard/" + System.currentTimeMillis() + ".jpg");
 82             try {
 83                 FileOutputStream fos = new FileOutputStream(pictureFile);
 84                 fos.write(data);
 85                 fos.close();
 86             } catch (Exception e) {
 87                 Log.d(TAG, "保存图片失败");
 88             }
 89         }
 90     };
 91 
 92     @Override
 93     protected void onDestroy() {
 94         // 回收Camera资源
 95         if(mCamera!=null){
 96             mCamera.stopPreview();
 97             mCamera.release();
 98             mCamera=null;
 99         }
100         super.onDestroy();
101     }
102     
103 }
package com.example.x_yp.system_camera;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * 定义一个预览类
 */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "main";
    private SurfaceHolder mHolder;
    private Camera mCamera;

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

        // 通过SurfaceView获得SurfaceHolder
        mHolder = getHolder();
        // 为SurfaceHolder指定回调
        mHolder.addCallback(this);
        // 设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到界面 在Android3.0之后弃用
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // 当Surface被创建之后,开始Camera的预览
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "预览失败");
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Surface发生改变的时候将被调用,第一次显示到界面的时候也会被调用
        if (mHolder.getSurface() == null){
          // 如果Surface为空,不继续操作
          return;
        }

        // 停止Camera的预览
        try {
            mCamera.stopPreview();
        } catch (Exception e){
            Log.d(TAG, "当Surface改变后,停止预览出错");
        }

        // 在预览前可以指定Camera的各项参数

        // 重新开始预览
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "预览Camera出错");
        }
    }
}

 布局文件

<?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>

权限设置

 <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android源码框架分析

Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制

App在后台久置后,再次从桌面或最近的任务列表唤醒时经常会发生崩溃,这往往是App在后台被系统杀死,再次恢复的时候遇到了问题,而在使用FragmentActiv...

2083
来自专栏向治洪

开源库BaseRecyclerViewAdapterHelper

相信大家RecyclerView应该不会陌生,大多数开发者应该都使用上它了,它也是google推荐替换ListView的控件,但是用过它的同学应该都知道它在某些...

2926
来自专栏java初学

android入门 — ListView点击事件

3579
来自专栏何俊林

音视频的采集、编码、封包成 mp4 输出

使用 Android Camera API 完成音视频的采集、编码、封包成 mp4 输出 基于android.hardware.Camera,创建一个横屏应用,...

1604
来自专栏Android相关

AAC---LifeCycle

LifeCycle最主要解决的问题是在Activity或者Fragment的生命周期中功能与页面状态之间的关系,以及对于功能太多时,onResume以及onPa...

1475
来自专栏向治洪

android几种常见的启动模式

launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和...

2036
来自专栏林冠宏的技术文章

为什么我的子线程更新了 UI 没报错?借此,纠正一些Android 程序员的一个知识误区

开门见山: 这个误区是:子线程不能更新 UI ,其应该分类讨论,而不是绝对的。 半小时前,我的 XRecyclerView 群里面,一位群友私聊我,问题是: ...

2237
来自专栏Android中高级开发

Android使用百度地图定位并显示手机位置后使用前置摄像头“偷拍”

拿到这个需求后,对于摄像头的使用不太熟悉,于是我先做了定位手机并在百度地图上显示的功能

3832
来自专栏Android常用基础

MVC、MVP、MVVM的理解与使用

对于MVC、MVP、MVVM,这都是Android开发的一种架构,随着日积月累的开发,很对人对这几种模式是再熟悉不过了。不过当初我在学习的时候是因为看一个开源项...

881
来自专栏沃趣科技

Oracle 12c ASM专题|Flex Diskgroup相关概念

原文链接 https://martincarstenbach.wordpress.com/2017/07/11/12-2-new-feature-the-fle...

3667

扫码关注云+社区

领取腾讯云代金券