我做毕业设计时候需要实现先拍摄后上传的功能,还要支持多分辨率,虽然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"/>