让我们来看一下完整的示例。下面编写的代码可在Android 2.2 和更高版本上运行,但是只须稍作改动,这段代码应该就能在Android 1.6 和更高版本上运行。在注释中特别注明了要求高于1.6版本的部分。
1 package com.nthm.androidtest; 2 3 import java.io.FileNotFoundException; 4 import java.io.IOException; 5 import java.io.OutputStream; 6 import java.util.Iterator; 7 import java.util.List; 8 import android.app.Activity; 9 import android.content.ContentValues; 10 import android.content.res.Configuration; 11 import android.hardware.Camera; 12 import android.net.Uri; 13 import android.os.Bundle; 14 import android.provider.MediaStore.Images.Media; 15 import android.view.SurfaceHolder; 16 import android.view.SurfaceView; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 20 public class SnapShot extends Activity implements OnClickListener,SurfaceHolder.Callback,Camera.PictureCallback{ 21 private SurfaceView cameraView; 22 private SurfaceHolder surfaceHolder; 23 private Camera camera; 24 25 @Override 26 protected void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 setContentView(R.layout.snapshot); 29 cameraView=(SurfaceView) findViewById(R.id.CameraView); 30 31 surfaceHolder=cameraView.getHolder(); 32 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 33 surfaceHolder.addCallback(this); 34 35 cameraView.setFocusable(true); 36 cameraView.setFocusableInTouchMode(true); 37 cameraView.setClickable(true); 38 cameraView.setOnClickListener(this); 39 } 40 @Override 41 public void onClick(View v) { 42 camera.takePicture(null, null, this); 43 44 }
随后是之前所描述的onPictureTaken方法。
1 @Override 2 public void onPictureTaken(byte[] data, Camera camera) { 3 Uri imageFileUri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues()); 4 try { 5 OutputStream imageFileOS=getContentResolver().openOutputStream(imageFileUri); 6 imageFileOS.write(data); 7 imageFileOS.flush(); 8 imageFileOS.close(); 9 } catch (FileNotFoundException e) { 10 e.printStackTrace(); 11 }catch (IOException e) { 12 e.printStackTrace(); 13 } 14 camera.startPreview(); 15 }
最后,需要使用各种的SurfaceView.Callback方法,在其中可以建立Camera对象。
1 @Override 2 public void surfaceCreated(SurfaceHolder holder) { 3 camera=Camera.open(); 4 try { 5 camera.setPreviewDisplay(holder); 6 Camera.Parameters parameters=camera.getParameters(); 7 if(this.getResources().getConfiguration().orientation!=Configuration.ORIENTATION_LANDSCAPE){ 8 //这是一个众所周知但未文档化的特性 9 parameters.set("orientation", "portrait"); 10 //对于Android 2.2及其以上版本 11 camera.setDisplayOrientation(90); 12 //对于Android 2.0及其以上版本取消注释 13 parameters.setRotation(90); 14 } 15 //用于Android 2.0 和更高版本的效果 16 List<String> colorEffects=parameters.getSupportedColorEffects(); 17 Iterator<String> cei=colorEffects.iterator(); 18 while(cei.hasNext()){ 19 String currentEffect=cei.next(); 20 if(currentEffect.equals(Camera.Parameters.EFFECT_SOLARIZE)){ 21 parameters.setColorEffect(currentEffect); 22 } 23 } 24 //结束Android 2.0 和更高版本的效果 25 camera.setParameters(parameters); 26 } catch (IOException e) { 27 camera.release(); 28 } 29 } 30 31 @Override 32 public void surfaceChanged(SurfaceHolder holder, int format, int width, 33 int height) { 34 camera.startPreview(); 35 } 36 37 @Override 38 public void surfaceDestroyed(SurfaceHolder holder) { 39 camera.stopPreview(); 40 camera.release(); 41 } 42 }
以上是Snapshot活动的代码。下面是该活动正在使用的布局XML,它位于res/layout/snapshot.xml中。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <SurfaceView 7 android:id="@+id/CameraView" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 /> 11 </LinearLayout>
最后,需要在AndroidMainfest.xml文件中添加CAMERA权限。以下是整个代码清单。
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.nthm.androidtest" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="21" /> 10 <uses-permission android:name="android.permission.CAMERA"/> 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name=".SnapShot" 18 android:label="@string/app_name" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 </application> 26 27 </manifest>
这个示例包括了构建一个基于摄像头的定制应用程序的基本要素。接下来,让我们看看如何扩展这个应用程序,实现在内置Camera应用程序中不存在的功能。