我希望摄像机在更改为录像机 Activity 时启动录像机,而不是在事件监听器上启动录像机。但是,当我尝试在oncreate上运行它时,它将崩溃一次,然后将按预期运行。
我在MediaRecorder.start()和myCamera.unlock上遇到错误。我该如何调试?
package com.abacus.surveillance;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
import android.os.Handler;
public class RecordActivity extends AppCompatActivity {
private static Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
Button restore;
SurfaceHolder surfaceHolder;
boolean recording;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.activity_record);
//Get Camera for preview
myCamera = getCameraInstance();
if(myCamera == null){
Log.d("ON Create","Failed to get camera");
} else {
Log.d("ON Create","Got camera");
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (Button)findViewById(R.id.mybutton);
restore = (Button)findViewById(R.id.restorebtn);
myButton.setOnClickListener(myButtonOnClickListener);
restore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(RecordActivity.this, MainActivity.class));
}
});
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
startRecord();
}
}, 3000);
}
Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener(){
@Override
public void onClick(View v) {
startRecord();
}
};
private void startRecord(){
if(recording){
try{
mediaRecorder.stop();
releaseMediaRecorder();
//finish();
myButton.setText("REC");
}catch(Exception e){
e.printStackTrace();
}
}else{
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(RecordActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
Log.d("start", "started");
recording = true;
myButton.setText("STOP");
}
}
private Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
Log.d("open", "open");
}
catch (Exception e){
Log.d("notopen", "notopen");
Log.e("camera", e.getMessage());
}
return c;
}
private boolean prepareMediaRecorder(){
Log.d("prep", "prepcamera");
myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
//myCamera.setDisplayOrientation(90);
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(60000);
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
try {
mediaRecorder.prepare();
Log.d("prepare", "prepared");
//mediaRecorder.start();
} catch (IllegalStateException e) {
Log.d("fail", "failed");
e.printStackTrace();
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d("fail", "failed2");
e.printStackTrace();
releaseMediaRecorder();
return false;
}
return true;
}
@Override
protected void onPause() {
super.onPause();
releaseMediaRecorder();
releaseCamera();
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
myCamera.lock();
}
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release();
myCamera = null;
}
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
int height) {
if (mHolder.getSurface() == null){
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("prevfail","fail");
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
}
Logcat
04-04 17:07:42.237 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:42.237 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:42.257 22448-22448/com.abacus.surveillance I/Choreographer: Skipped 42 frames! The application may be doing too much work on its main thread.
04-04 17:07:43.118 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:43.118 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:43.929 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:43.929 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:44.029 22448-22448/com.abacus.surveillance I/Choreographer: Skipped 96 frames! The application may be doing too much work on its main thread.
04-04 17:07:44.169 22448-22448/com.abacus.surveillance D/AndroidRuntime: Shutting down VM
04-04 17:07:44.169 22448-22448/com.abacus.surveillance W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x418ccda0)
04-04 17:07:44.199 22448-22448/com.abacus.surveillance E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abacus.surveillance, PID: 22448
java.lang.RuntimeException: Method called after release()
at android.hardware.Camera.setPreviewDisplay(Native Method)
at android.hardware.Camera.setPreviewDisplay(Camera.java:530)
at com.abacus.surveillance.RecordActivity$MyCameraSurfaceView.surfaceCreated(RecordActivity.java:263)
at android.view.SurfaceView.updateWindow(SurfaceView.java:602)
at android.view.SurfaceView.access$000(SurfaceView.java:94)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:183)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:891)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2193)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1251)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6540)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
at android.view.Choreographer.doCallbacks(Choreographer.java:613)
at android.view.Choreographer.doFrame(Choreographer.java:583)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Logcat 2
04-04 17:19:30.573 2479-2479/com.abacus.surveillance E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abacus.surveillance, PID: 2479
java.lang.NullPointerException
at com.abacus.surveillance.RecordActivity.startRecord(RecordActivity.java:136)
at com.abacus.surveillance.RecordActivity.access$000(RecordActivity.java:40)
at com.abacus.surveillance.RecordActivity$2.run(RecordActivity.java:90)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
最佳答案
对于第一个例外,请尝试像这样更改surfaceCreated()
:
@Override
public void surfaceCreated(SurfaceHolder holder) {
if( mCamera != null ){
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("prevfail","fail");
}
}
}
对于第二个例外,请尝试如下操作:
private void startRecord(){
if(recording){
try{
if( mediaRecorder != null )
mediaRecorder.stop();
releaseMediaRecorder();
//finish();
myButton.setText("REC");
}catch(Exception e){
e.printStackTrace();
}
}else{
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(RecordActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
else{
mediaRecorder.start();
Log.d("start", "started");
recording = true;
myButton.setText("STOP");
}
}
}