Android SDK支持操作Android设备内置的照相机。从Android2.3开始,支持操作多个摄像头(主要指前置摄像头和后置照相机)。通过照相机可以拍照和录像。
SurfaceView、
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" > 6 7 <Button 8 android:id="@+id/btnTakePicture" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="拍照" /> 12 13 <ImageView 14 android:id="@+id/imageview" 15 android:layout_width="320dp" 16 android:layout_height="240dp" /> 17 18 </LinearLayout>
1 import android.app.Activity; 2 import android.content.Intent; 3 import android.graphics.Bitmap; 4 import android.os.Bundle; 5 import android.provider.MediaStore; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 import android.widget.ImageView; 10 11 public class Main extends Activity implements OnClickListener { 12 private ImageView imageView; 13 14 @Override 15 public void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.main); 18 19 Button btnTakePicture = (Button) findViewById(R.id.btnTakePicture); 20 btnTakePicture.setOnClickListener(this); 21 22 imageView = (ImageView) findViewById(R.id.imageview); 23 } 24 25 public void onClick(View view) { 26 // 调用系统拍照 27 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 28 // 显示拍照窗口 29 startActivityForResult(intent, 1); 30 } 31 32 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 33 if (requestCode == 1) { 34 if (resultCode == Activity.RESULT_OK) { 35 Bitmap cameraBitmap = (Bitmap) data.getExtras().get("data"); 36 imageView.setImageBitmap(cameraBitmap); 37 } 38 } 39 } 40 41 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="cn.eoe.system.camera" android:versionCode="1" 4 android:versionName="1.0"> 5 <application android:icon="@drawable/icon" android:label="@string/app_name"> 6 <activity android:name=".Main" android:label="@string/app_name"> 7 <intent-filter> 8 <action android:name="android.intent.action.MAIN" /> 9 <category android:name="android.intent.category.LAUNCHER" /> 10 </intent-filter> 11 </activity> 12 </application> 13 <uses-sdk android:minSdkVersion="7" /> 14 </manifest>
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" > 6 7 <Button 8 android:id="@+id/btnTakePicture" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="录像" /> 12 13 <VideoView 14 android:id="@+id/videoview" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" /> 17 18 </LinearLayout>
1 import android.app.Activity; 2 import android.content.Intent; 3 import android.database.Cursor; 4 import android.net.Uri; 5 import android.os.Bundle; 6 import android.provider.MediaStore; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button; 10 import android.widget.MediaController; 11 import android.widget.VideoView; 12 13 public class Main extends Activity implements OnClickListener { 14 public VideoView videoView; 15 16 @Override 17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main); 20 Button btnTakePicture = (Button) findViewById(R.id.btnTakePicture); 21 btnTakePicture.setOnClickListener(this); 22 23 videoView = (VideoView) findViewById(R.id.videoview); 24 25 } 26 27 public void onClick(View view) { 28 Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 29 startActivityForResult(intent, 1); 30 } 31 32 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 33 if (requestCode == 1) { 34 if (resultCode == Activity.RESULT_OK) { 35 Uri uri = data.getData(); 36 Cursor cursor = this.getContentResolver().query(uri, null, 37 null, null, null); 38 39 if (cursor.moveToFirst()) { 40 // 取出路径 41 String videoPath = cursor.getString(cursor 42 .getColumnIndex("_data")); 43 // 加载 44 videoView.setVideoURI(Uri.parse(videoPath)); 45 // 设置视频控制控件(停止,快进等)。 46 videoView.setMediaController(new MediaController(this)); 47 // 播放。 48 videoView.start(); 49 } 50 } 51 } 52 } 53 54 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="cn.eoe.record.video" android:versionCode="1" 4 android:versionName="1.0"> 5 <application android:icon="@drawable/icon" android:label="@string/app_name"> 6 <activity android:name="Main" android:label="@string/app_name"> 7 <intent-filter> 8 <action android:name="android.intent.action.MAIN" /> 9 <category android:name="android.intent.category.LAUNCHER" /> 10 </intent-filter> 11 </activity> 12 </application> 13 <uses-sdk android:minSdkVersion="7" /> 14 </manifest>
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
{ return true; } else { return false; }
}
1 package cn.eoe.custom.camera; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.util.List; 6 7 import android.app.Activity; 8 import android.content.Context; 9 import android.hardware.Camera; 10 import android.hardware.Camera.PictureCallback; 11 import android.hardware.Camera.Size; 12 import android.os.Bundle; 13 import android.view.SurfaceHolder; 14 import android.view.SurfaceView; 15 import android.view.View; 16 import android.view.View.OnClickListener; 17 import android.view.ViewGroup; 18 import android.view.Window; 19 import android.view.WindowManager; 20 21 public class CustomCameraActivity extends Activity { 22 private Camera mCamera; 23 private Preview mPreview; 24 25 @Override 26 protected void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 // 设置为全屏 29 requestWindowFeature(Window.FEATURE_NO_TITLE); 30 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 31 mPreview = new Preview(this); 32 setContentView(mPreview); 33 } 34 35 protected void onResume() { 36 super.onResume(); 37 // 打开照相机 38 mCamera = Camera.open(); 39 mPreview.setCamera(mCamera); 40 } 41 42 protected void onPause() { 43 super.onPause(); 44 45 if (mCamera != null) { 46 mCamera.release(); 47 mCamera = null; 48 mPreview.setCamera(null); 49 } 50 } 51 52 class Preview extends ViewGroup implements SurfaceHolder.Callback, 53 OnClickListener { 54 55 SurfaceView mSurfaceView; 56 SurfaceHolder mHolder; // 存储事件回掉 57 Size mPreviewSize; // 当前窗口预览尺寸 58 List<Size> mSupportedPreviewSizes; // 相机中的预览尺寸 59 Camera mCamera; 60 Context mContext; 61 62 public Preview(Context context) { 63 super(context); 64 mContext = context; 65 mSurfaceView = new SurfaceView(context); 66 addView(mSurfaceView); 67 mHolder = mSurfaceView.getHolder(); 68 mHolder.addCallback(this); 69 70 } 71 72 public void setCamera(Camera camera) { 73 mCamera = camera; 74 if (mCamera != null) { 75 // 获得当前相机可支持预览的尺寸。 76 mSupportedPreviewSizes = mCamera.getParameters() 77 .getSupportedPictureSizes(); 78 // 调整布局。 79 requestLayout(); 80 } 81 } 82 83 private PictureCallback mPictureCallback = new PictureCallback() { 84 85 @Override 86 public void onPictureTaken(byte[] data, Camera camera) { 87 mCamera.startPreview(); 88 File pictureFile = new File("/sdcard/image.jpg"); 89 try { 90 FileOutputStream fos = new FileOutputStream(pictureFile); 91 fos.write(data); 92 fos.close(); 93 } catch (Exception e) { 94 // TODO: handle exception 95 } 96 97 } 98 }; 99 100 public void onClick(View view) { 101 mCamera.takePicture(null, null, mPictureCallback); 102 } 103 104 @Override 105 public void surfaceChanged(SurfaceHolder holder, int format, int width, 106 int height) { 107 // 设置预览的尺寸(不支持比如:200 200这种尺寸)。 108 Camera.Parameters parameters = mCamera.getParameters(); 109 parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 110 111 mCamera.setParameters(parameters); 112 mCamera.startPreview(); // 预览 113 114 } 115 116 @Override 117 public void surfaceCreated(SurfaceHolder holder) { 118 try { 119 if (mCamera != null) { 120 // 将 Camera和SurfaceView进行一个关联。 121 mCamera.setPreviewDisplay(holder); 122 } 123 } catch (Exception e) { 124 // TODO: handle exception 125 } 126 127 } 128 129 @Override 130 public void surfaceDestroyed(SurfaceHolder holder) { 131 // TODO Auto-generated method stub 132 if (mCamera != null) { 133 // 停止预览 134 mCamera.stopPreview(); 135 } 136 } 137 138 @Override // 调整预览尺寸。 139 protected void onLayout(boolean changed, int l, int t, int r, int b) { 140 if (changed && getChildCount() > 0) { //子视图 141 // 获得子视图。 142 final View child = getChildAt(0); 143 144 // viewGroup 145 int width = r - l; 146 int height = b - t; 147 148 // 实际窗口尺寸。 149 int previewWidth = width; 150 int previewHeight = height; 151 152 // mPreviewSize 图像产生的。 153 if (mPreviewSize != null) { 154 // 把前两个初始值覆盖。 155 previewWidth = mPreviewSize.width; 156 previewHeight = mPreviewSize.height; 157 } 158 // 手机屏幕的宽高比大于采集图像的宽高比。 159 if (width * previewHeight > height * previewWidth) { 160 final int scaledChildWidth = previewWidth * height 161 / previewHeight; 162 // child.layout((width - scaledChildWidth)/2, 163 // 0,(width+scaledChildWidth)/2,height); 164 165 child.layout(100, 100, 340, 240); 166 } else { 167 final int scaledChildHeight = previewHeight * width 168 / previewWidth; 169 child.layout(0, (height - scaledChildHeight) / 2, width, 170 (height + scaledChildHeight) / 2); 171 } 172 173 } 174 175 } 176 177 private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 178 double ASPECT_TOLERANCE = 0.1; 179 double targetRatio = (double) w / h; 180 if (sizes == null) 181 return null; 182 183 Size optimalSize = null; 184 double minDiff = Double.MAX_VALUE; 185 int targetHeight = h; 186 187 for (Size size : sizes) { 188 double ratio = (double) size.width / size.height; 189 if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) { 190 continue; 191 } 192 if (Math.abs(size.height - targetHeight) < minDiff) { 193 optimalSize = size; 194 minDiff = Math.abs(size.height - targetHeight); 195 } 196 } 197 198 if (optimalSize == null) { 199 minDiff = Double.MAX_VALUE; 200 for (Size size : sizes) { 201 if (Math.abs(size.height - targetHeight) < minDiff) { 202 optimalSize = size; 203 minDiff = Math.abs(size.height - targetHeight); 204 } 205 } 206 } 207 return optimalSize; 208 } 209 210 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 211 int width = resolveSize(getSuggestedMinimumWidth(), 212 widthMeasureSpec); 213 int height = resolveSize(getSuggestedMinimumHeight(), 214 heightMeasureSpec); 215 216 setMeasuredDimension(width, height); 217 218 if (mSupportedPreviewSizes != null) { 219 mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, 220 width, height); 221 } 222 } 223 224 } 225 226 }