首先,我们肯定要用到摄像头,因此需要在Manifest文件中声明使用权限:
<uses-permission android:name="android.permission.CAMERA" />
如果还要使用一些硬件属性,那还要做额外的声明,例如:
<uses-feature android:name="android.hardware.camera"/> <uses-feature:name="android.hardware.camera.autofocus"/>
当我们在录制的时候,通常都想要看到我们正在拍什么,这就需要预览,而预览需要在一个SurfaceView上实现,因此我们要添加一个控件:
<SurfaceView android:id="@+id/surface_camera" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:layout_weight="1"> </SurfaceView>
然后,我们来实现这个Activity:
public class CustomVideoCamera extends Activity implements SurfaceHolder.Callback{ private static final String TAG = "CAMERA_TUTORIAL"; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private Camera camera; private boolean previewRunning; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.camera_surface); surfaceView = (SurfaceView) findViewById(R.id.surface_camera); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); if (camera != null){ Camera.Parameters params = camera.getParameters(); camera.setParameters(params); } else { Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show(); finish(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (previewRunning){ camera.stopPreview(); } Camera.Parameters p = camera.getParameters(); p.setPreviewSize(width, height); p.setPreviewFormat(PixelFormat.JPEG); camera.setParameters(p); try { camera.setPreviewDisplay(holder); camera.startPreview(); previewRunning = true; } catch (IOException e) { Log.e(TAG,e.getMessage()); e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.stopPreview(); previewRunning = false; camera.release(); } }
接着,我们就可以录制了:
private MediaRecorder mediaRecorder; private final int maxDurationInMs = 20000; private final long maxFileSizeInBytes = 500000; private final int videoFramesPerSecond = 20; public boolean startRecording(){ try { camera.unlock(); mediaRecorder = new MediaRecorder(); mediaRecorder.setCamera(camera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); mediaRecorder.setMaxDuration(maxDurationInMs); tempFile = new File(getCacheDir(),cacheFileName); mediaRecorder.setOutputFile(tempFile.getPath()); mediaRecorder.setVideoFrameRate(videoFramesPerSecond); mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight()); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); mediaRecorder.setMaxFileSize(maxFileSizeInBytes); mediaRecorder.prepare(); mediaRecorder.start(); return true; } catch (IllegalStateException e) { Log.e(TAG,e.getMessage()); e.printStackTrace(); return false; } catch (IOException e) { Log.e(TAG,e.getMessage()); e.printStackTrace(); return false; } }
停止拍摄,则:
public void stopRecording(){ mediaRecorder.stop(); camera.lock(); }
这样的话,通过编译之后,在Android OS 2.1 和 2.2上都能实现了,但在部分机器上会有些小问题,主要是预览上,看到app内的预览是另开线程做的,不知道是否会有改善?