我遇到了同样的问题。我查了一下,这是我的活动。我花了一些力气让它不崩溃,所以这是最终的结果。它在用户单击 REC 按钮之前显示预览。(我也显示倒计时,但不要介意)。另请注意,在此示例中(单击时)在主线程上完成了太多工作。这里有一些东西不是最佳实践,但对于一个工作示例,我认为它已经足够好了。
import android.app.Activity;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
public class MainActivity extends Activity implements SurfaceHolder.Callback {
private static final String LOG_TAG = MainActivity.class.getCanonicalName();
Button myButton;
MediaRecorder mediaRecorder;
SurfaceHolder surfaceHolder;
boolean recording;
private TextView mTimer;
private Camera mCamera;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recording = false;
mediaRecorder = new MediaRecorder();
mCamera = Camera.open();
initMediaRecorder();
SurfaceView myVideoView = (SurfaceView) findViewById(R.id.videoview);
surfaceHolder = myVideoView.getHolder();
surfaceHolder.addCallback(this);
myButton = (Button) findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
mTimer = (TextView) findViewById(R.id.timer);
}
private Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener() {
@Override
public void onClick(final View arg0) {
CountDownTimer countDownTimer = new CountDownTimer(90 * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mTimer.setText(String.valueOf(millisUntilFinished / 1000));
}
@Override
public void onFinish() {
onClick(arg0);
}
};
if (recording) {
// Stop recording and finish
try {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
finish();
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to stop recorder", e);
}
} else {
// Release the camera and start recording
mCamera.release();
countDownTimer.start();
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
}
}
};
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
prepareMediaRecorder();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
private void initMediaRecorder() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(CamcorderProfile.QUALITY_CIF);
mediaRecorder.setProfile(camcorderProfile_HQ);
File file = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "myvideo.mp4");
if (file.exists()) {
file.delete();
}
mediaRecorder.setOutputFile(file.getAbsolutePath());
mediaRecorder.setMaxDuration(90000); // Set max duration 90 sec.
mediaRecorder.setMaxFileSize(15000000); // Set max file size 15M
}
private void prepareMediaRecorder() {
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException | IOException e) {
Log.e(LOG_TAG, "Failed to prepare recorder", e);
}
}
}