我做毕业设计时候需要实现先拍摄后上传的功能,还要支持多分辨率,虽然MediaRecorder的教程很丰富,但是实现起来却一波三折,这里记录下来的代码也只是在我自己的2.3的Android上跑起来没有问题。在有些Moto的机子上会失败,具体原因还未分析出来。
直接上代码:根据MediaRecorder的状态
package net.john.media; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.pm.ActivityInfo; import android.hardware.Camera; import android.hardware.Camera.Size; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.Window; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemSelectedListener; public class MediaRecorderDemoActivity extends Activity implements SurfaceHolder.Callback { private Button button_start; private Button button_stop; private Button button_back; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private File storageDir; private File tempFile; private MediaRecorder mediaRecorder; private Camera camera; private Spinner spinner; private int width; private int height; private int hou; private int min; private int sec; private Handler handler; private TextView textView_time; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); // no title //screen orientation landscape this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setContentView(R.layout.main); button_start = (Button)this.findViewById(R.id.button_start); button_stop = (Button)this.findViewById(R.id.button_stop); button_back = (Button)this.findViewById(R.id.button_back); surfaceView = (SurfaceView)this.findViewById(R.id.surfaceView); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(MediaRecorderDemoActivity.this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); spinner = (Spinner)this.findViewById(R.id.spinner_size); width = 480; height = 320; handler = new Handler(); textView_time = (TextView)this.findViewById(R.id.textView_time); button_start.setOnClickListener(btnStartListener); button_stop.setOnClickListener(btnStopListener); button_back.setOnClickListener(btnBackListener); spinner.setOnItemSelectedListener(spinnerListener); boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); if (sdCardExist) { storageDir = new File(Environment.getExternalStorageDirectory().toString() + File.separator + "Demo" + File.separator); if (!storageDir.exists()) { storageDir.mkdir(); } button_stop.setVisibility(View.GONE); } else { button_start.setVisibility(View.GONE); Toast.makeText(MediaRecorderDemoActivity.this, "SDcard is not exist", Toast.LENGTH_LONG).show(); } } private View.OnClickListener btnStartListener = new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub button_start.setVisibility(View.GONE); button_stop.setVisibility(View.VISIBLE); spinner.setVisibility(View.GONE); hou = 0; min = 0; sec = 0; handler.postDelayed(refreshTime, 1000); try { tempFile = File.createTempFile("Demo", ".3gp", storageDir); mediaRecorder = new MediaRecorder(); mediaRecorder.setCamera(camera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.setVideoSize(width, height); mediaRecorder.setVideoFrameRate(16); mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); mediaRecorder.setOutputFile(tempFile.getAbsolutePath()); mediaRecorder.prepare(); mediaRecorder.start(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; private View.OnClickListener btnStopListener = new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub button_start.setVisibility(View.VISIBLE); button_stop.setVisibility(View.GONE); spinner.setVisibility(View.VISIBLE); handler.removeCallbacks(refreshTime); if (mediaRecorder != null) { try { mediaRecorder.stop(); mediaRecorder.release(); Log.e("Demo", tempFile.getAbsolutePath()); } catch(RuntimeException e) { Log.e("Demo", e.getMessage()); } } } }; private View.OnClickListener btnBackListener = new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub finish(); } }; private OnItemSelectedListener spinnerListener = new Spinner.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Spinner spinner = (Spinner)arg0; String wh[] = spinner.getSelectedItem().toString().split("\\*"); width = Integer.parseInt(wh[0]); height = Integer.parseInt(wh[1]); try { camera.lock(); camera.stopPreview(); Camera.Parameters para = camera.getParameters(); para.setPreviewSize(width, height); camera.setParameters(para); camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); Log.d("Demo", camera.getParameters().getPreviewSize().width + "*" + camera.getParameters().getPreviewSize().height); camera.unlock(); } catch (IOException e) { // TODO Auto-generated catch block Log.e("Demo", e.getMessage()); } } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }; private Runnable refreshTime = new Runnable() { @Override public void run() { // TODO Auto-generated method stub sec++; handler.postDelayed(refreshTime, 1000); if (sec >= 60) { sec = sec % 60; min++; } if (min >= 60) { min = min % 60; hou++; } textView_time.setText(timeFormat(hou) + ":" + timeFormat(min) + ":" + timeFormat(sec)); } }; private String timeFormat(int t) { if (t / 10 == 0) { return "0" + t; } else { return t + ""; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub camera = Camera.open(); List<Size> supportedSize = camera.getParameters().getSupportedPreviewSizes(); if (supportedSize != null) { List<String> list = new ArrayList<String>(); for (Size s: supportedSize) { list.add(s.width + "*" + s.height); } list.remove(0); // 在使用G7的摄像头支持的最大分辨率进行拍摄的时候会出现stop failed错误,无法关闭MediaRecorder,原因不明! ArrayAdapter<String> adapter = new ArrayAdapter<String>(MediaRecorderDemoActivity.this, android.R.layout.simple_spinner_dropdown_item, list); spinner.setAdapter(adapter); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub camera.release(); } }
三个权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>