Android L Camera2 API sample ver2 - startPreview&takePicture

1. Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.camera2te"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="21"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera2.full" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

2. layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.camera2te.MainActivity" >

    <TextureView
        android:id="@+id/texture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/btn_takepicture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/picture" />

</RelativeLayout>

3. Java file

package com.example.camera2te;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;

public class MainActivity extends Activity {

	private final static String TAG = "Camera2testJ";
	private Size mPreviewSize;

	private TextureView mTextureView;
	private CameraDevice mCameraDevice;
	private CaptureRequest.Builder mPreviewBuilder;
	private CameraCaptureSession mPreviewSession;

	private Button mBtnShot;

	private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_main);

		mTextureView = (TextureView)findViewById(R.id.texture);
		mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);

		mBtnShot = (Button)findViewById(R.id.btn_takepicture);
		mBtnShot.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				Log.e(TAG, "mBtnShot clicked");
				takePicture();
			}

		});

	}

	protected void takePicture() {
		Log.e(TAG, "takePicture");
		if(null == mCameraDevice) {
			Log.e(TAG, "mCameraDevice is null, return");
			return;
		}

		CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
		try {
			CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraDevice.getId());

			Size[] jpegSizes = null;
			if (characteristics != null) {
	            jpegSizes = characteristics
	                    .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
	                    .getOutputSizes(ImageFormat.JPEG);
	        }
			int width = 640;
            int height = 480;
            if (jpegSizes != null && 0 < jpegSizes.length) {
                width = jpegSizes[0].getWidth();
                height = jpegSizes[0].getHeight();
            }

            ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
            List<Surface> outputSurfaces = new ArrayList<Surface>(2);
            outputSurfaces.add(reader.getSurface());
            outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture()));

            final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(reader.getSurface());
            captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

            // Orientation
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

            final File file = new File(Environment.getExternalStorageDirectory()+"/DCIM", "pic.jpg");

            ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {

				@Override
				public void onImageAvailable(ImageReader reader) {

					Image image = null;
					try {
                        image = reader.acquireLatestImage();
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] bytes = new byte[buffer.capacity()];
                        buffer.get(bytes);
                        save(bytes);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (image != null) {
                            image.close();
                        }
                    }
				}

				private void save(byte[] bytes) throws IOException {
                    OutputStream output = null;
                    try {
                        output = new FileOutputStream(file);
                        output.write(bytes);
                    } finally {
                        if (null != output) {
                            output.close();
                        }
                    }
                }

            };

            HandlerThread thread = new HandlerThread("CameraPicture");
            thread.start();
            final Handler backgroudHandler = new Handler(thread.getLooper());
            reader.setOnImageAvailableListener(readerListener, backgroudHandler);

            final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {

				@Override
				public void onCaptureCompleted(CameraCaptureSession session,
						CaptureRequest request, TotalCaptureResult result) {

					super.onCaptureCompleted(session, request, result);
					Toast.makeText(MainActivity.this, "Saved:"+file, Toast.LENGTH_SHORT).show();
					startPreview();
				}

            };

            mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {

				@Override
				public void onConfigured(CameraCaptureSession session) {

					try {
						session.capture(captureBuilder.build(), captureListener, backgroudHandler);
					} catch (CameraAccessException e) {

						e.printStackTrace();
					}
				}

				@Override
				public void onConfigureFailed(CameraCaptureSession session) {

				}
			}, backgroudHandler);

		} catch (CameraAccessException e) {
			e.printStackTrace();
		}

	}

	@Override
	protected void onResume() {
		super.onResume();
		Log.e(TAG, "onResume");
	}

	private void openCamera() {

		CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
		Log.e(TAG, "openCamera E");
		try {
			String cameraId = manager.getCameraIdList()[0];
			CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
			StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
			mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];

			manager.openCamera(cameraId, mStateCallback, null);
		} catch (CameraAccessException e) {
			e.printStackTrace();
		}
		Log.e(TAG, "openCamera X");
	}

	private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener(){

		@Override
		public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
			Log.e(TAG, "onSurfaceTextureAvailable, width="+width+",height="+height);
			openCamera();
		}

		@Override
		public void onSurfaceTextureSizeChanged(SurfaceTexture surface,
				int width, int height) {
			Log.e(TAG, "onSurfaceTextureSizeChanged");
		}

		@Override
		public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
			return false;
		}

		@Override
		public void onSurfaceTextureUpdated(SurfaceTexture surface) {
			//Log.e(TAG, "onSurfaceTextureUpdated");
		}

	};

	private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

		@Override
		public void onOpened(CameraDevice camera) {

			Log.e(TAG, "onOpened");
			mCameraDevice = camera;
			startPreview();
		}

		@Override
		public void onDisconnected(CameraDevice camera) {

			Log.e(TAG, "onDisconnected");
		}

		@Override
		public void onError(CameraDevice camera, int error) {

			Log.e(TAG, "onError");
		}

	};

	@Override
	protected void onPause() {

		Log.e(TAG, "onPause");
		super.onPause();
		if (null != mCameraDevice) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
	}

	protected void startPreview() {

		if(null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
			Log.e(TAG, "startPreview fail, return");
			return;
		}

		SurfaceTexture texture = mTextureView.getSurfaceTexture();
		if(null == texture) {
			Log.e(TAG,"texture is null, return");
			return;
		}

		texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
		Surface surface = new Surface(texture);

		try {
			mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
		} catch (CameraAccessException e) {

			e.printStackTrace();
		}
		mPreviewBuilder.addTarget(surface);

		try {
			mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {

				@Override
				public void onConfigured(CameraCaptureSession session) {

					mPreviewSession = session;
					updatePreview();
				}

				@Override
				public void onConfigureFailed(CameraCaptureSession session) {

					Toast.makeText(MainActivity.this, "onConfigureFailed", Toast.LENGTH_LONG).show();
				}
			}, null);
		} catch (CameraAccessException e) {

			e.printStackTrace();
		}
	}

	protected void updatePreview() {

		if(null == mCameraDevice) {
			Log.e(TAG, "updatePreview error, return");
		}

		mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
		HandlerThread thread = new HandlerThread("CameraPreview");
		thread.start();
		Handler backgroundHandler = new Handler(thread.getLooper());

		try {
			mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
		} catch (CameraAccessException e) {

			e.printStackTrace();
		}
	}
}
时间: 2024-10-17 23:01:59

Android L Camera2 API sample ver2 - startPreview&takePicture的相关文章

Android L Camera2 API sample ver1 - startPreview

1. Manifest : <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.camera2te" android:versionCode="1" android:versionNam

Android L Camera2 API 使用实例程序汇总

在网上发现几个使用Camera API2开发的实例程序,总结一下方便后续参考: 1.Camera2 Basic : https://github.com/googlesamples/android-Camera2Basic This sample demonstrates how to use basic functionalities of Camera2 API. You can learn how to iterate through characteristics of all the

Android L New API之Verctor动画 1 —— SVG Path

导入 1.VectorDrawable是Android L中新增的一个API,让你可以创建基于XML的矢量图,并结合AnimatedVectorDrawable来实现动画效果. 2.Android L新增支持Vector标签,可以使用Path创建动画,同时支持SVG格式. SVG 简介 1.SVG 指可伸缩矢量图形 (Scalable Vector Graphics)2.SVG 用来定义用于网络的基于矢量的图形3.SVG 使用 XML 格式定义图形4.SVG 图像在放大或改变尺寸的情况下其图形质

Android L Camera2 PreviewBuilder set CaptureRequest.CONTROL_EFFECT_MODE not work.

设备 : Nexus 7 wifi 2013 软件版本 : razor-lpx13d-preview-ae4f461f.tgz mCameraManager.openCamera(mCameraID, mStateCallback, null); mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mCameraDevice.createCaptureSession(Arrays

Android L / 5.0 帮助文档 API21文档 sample demo源码 下载

如无法登陆google,浏览android官网也是问题,这里提供android L的官方文档资料下载.API版本21 参考文档较大,解压后最好使用IE浏览器打开,并工具选项卡中设置为脱机工作模式, 如是,则打开文档速度会加快许多.否则发送js请求等待google响应,会出现加载十分缓慢的现象. 也可修改网页源码,使之不发送访问google的请求,请自行百度,etc 如果想用google搜索,又无法打开google网站,可以试用下谷粉搜索 http://www.gfsoso.com/ Androi

Android 5.0 API

Android 5.0 API 在本文档中展开 更新目标 API 级别 重要的行为变更 界面 通知 图形 媒体 存储 无线和连接 Project Volta Android 在办公和教育中的应用 系统 打印框架 测试和辅助功能 IME 清单声明 API Differences API level 20 to 21 ? L Developer Preview to 21 ? See Also Android 5.0 Behavior Changes Android Lollipop Highlig

Android L 64bit 预览版来了!Android L模拟器配置及创建项目

Android L: Android L可能就是Android Lollipop(4.5或者5.0),因为Google一直以来都是用甜点为版本命名. 而据说在10月中旬也就是15或16号Google的发布会上应该会推出Nexus 6和Nexus 9,这两个新品都是搭载Android L,而Nexus 9应该是搭载Navidia的64位CPU, 而且之前的Nexus5和7应该都会接到升级推送.(期待Nexus9好久了,希望金属机身啊) 而就在昨天10.9号,Google发布了Android L 6

Android Camera API/Camera2 API 相机预览及滤镜、贴纸等处理

Android Lollipop 增加了Camera2 API,并将原来的Camera API标记为废弃了.相对原来的Camera API来说,Camera2是重新定义的相机 API,也重构了相机 API 的架构.初看之下,可能会感觉Camera2使用起来比Camera要复杂,然而使用过后,你也许就会喜欢上使用Camera2了.无论是Camera还是Camera2,当相机遇到OpenGL就比较好玩了. 问题及思路 Camera的预览比较常见的是使用SurfaceHolder来预览,Camera2

一劳永逸搭建android开发环境(android官网reference sample api tutorial全下载)

[摘要]本文简单介绍了android开发环境的搭建,重点介绍了SDK manager和AVD升级问题:并提供了android reference,sample,api,及docs的下载信息. [1]为何写这个题目呢? 1.工欲其事必先利器: 2.墙内的世界太烦躁,健康向上的东西也得不到: 3.google及其android在墙外: 4.SDK不好太多,太零散,非得用管理工具才好使: 如果你会翻越长城这堵世界奇迹之墙,你可以在android官网https://developer.android.c