无法在Oncreate中启动录像机

时间:2014-04-03 07:04:42

标签: java android android-mediarecorder

我制作了一个简单的录像机应用程序,其中视频开始录制按钮点击。这是我的代码:

package com.example.videocapture2;

import java.io.IOException;

import android.app.Activity; 
import android.content.pm.ActivityInfo;
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.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements  SurfaceHolder.Callback,android.media.MediaRecorder.OnInfoListener{
    MediaRecorder recorder;
    SurfaceHolder holder;
    Button Rec = null;
    boolean recording = false;
    int count =1;
    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    recorder = new MediaRecorder();
    initRecorder();
    setContentView(R.layout.activity_main);

    SurfaceView cameraView = (SurfaceView) findViewById(R.id.videoview);

    holder = cameraView.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    recorder.start();  //This is the line pointed to by the IllegalStateException

    //cameraView.setClickable(true);
   // cameraView.setOnClickListener(this);

    Rec = (Button)findViewById(R.id.mybutton);
    Rec.setOnClickListener(new View.OnClickListener() {

        @Override
         public void onClick(View v) {
            if (recording) {
                recorder.stop();
                recording = false;

                // Let's initRecorder so we can record again
                initRecorder();
                prepareRecorder();
            } else {
                recording = true;
                recorder.start();
            }
        }
    });
}

private void initRecorder() {
    recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

    CamcorderProfile cpHigh = CamcorderProfile
            .get(CamcorderProfile.QUALITY_HIGH);
    recorder.setProfile(cpHigh);
    recorder.setOutputFile("/sdcard/videocapture_example"+count+".mp4");
    recorder.setMaxDuration(50000); // 50 seconds
    recorder.setMaxFileSize(2*1048576); // Approximately 5 megabytes
    count++;
}

private void prepareRecorder() {
    recorder.setPreviewDisplay(holder.getSurface());

    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
        finish();
    } catch (IOException e) {
        e.printStackTrace();
        finish();
    }
}



public void surfaceCreated(SurfaceHolder holder) {
    prepareRecorder();
}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
}

public void surfaceDestroyed(SurfaceHolder holder) {
    if (recording) {
        recorder.stop();
        recording = false;
    }
    recorder.release();
    //Toast.makeText(getApplicationContext(), "Video is saved", Toast.LENGTH_LONG).show();
    //finish();
}

@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
    // TODO Auto-generated method stub
    System.out.println("Reached onInfoListener");
    if(what==android.media.MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)
    {
        Toast.makeText(getApplicationContext(), "Video clip recorded", Toast.LENGTH_LONG).show();
    }
}


}

我应该做些什么更改才能调用

recorder.start();

来自onCreate,或者更确切地说是在我启动应用之后,而不是在OnClick方法中?此外,如果我尝试直接从OnCreate调用它,它会在recorder.start()语句的行中抛出 IllegalStateException

logcat的:

04-03 12:48:51.005: E/Trace(26160): error opening trace file: No such file or directory (2)
04-03 12:48:51.025: V/ActivityThread(26160): Class path:   /data/app/com.example.videocapture2-2.apk, JNI path:  /data/data/com.example.videocapture2/lib
04-03 12:48:51.174: I/System.out(26160): In surface view:false
04-03 12:48:51.174: E/MediaRecorder(26160): start called in an invalid state: 4
04-03 12:48:51.175: D/AndroidRuntime(26160): Shutting down VM
04-03 12:48:51.175: W/dalvikvm(26160): threadid=1: thread exiting with uncaught  exception (group=0x41bd88a8)
04-03 12:48:51.178: E/AndroidRuntime(26160): FATAL EXCEPTION: main
04-03 12:48:51.178: E/AndroidRuntime(26160): java.lang.RuntimeException: Unable to start   activity ComponentInfo{com.example.videocapture2/com.example.videocapture2.MainActivity}:  java.lang.IllegalStateException
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2225)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread.access$600(ActivityThread.java:151)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1301)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.os.Looper.loop(Looper.java:153)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread.main(ActivityThread.java:5096)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at java.lang.reflect.Method.invokeNative(Native Method)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at java.lang.reflect.Method.invoke(Method.java:511)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at dalvik.system.NativeStart.main(Native Method)
04-03 12:48:51.178: E/AndroidRuntime(26160): Caused by: java.lang.IllegalStateException
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.media.MediaRecorder.native_start(Native Method)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.media.MediaRecorder.start(MediaRecorder.java:728)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at com.example.videocapture2.MainActivity.onCreate(MainActivity.java:51)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.Activity.performCreate(Activity.java:5244)
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1082) 
04-03 12:48:51.178: E/AndroidRuntime(26160):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
04-03 12:48:51.178: E/AndroidRuntime(26160):    ... 11 more

尝试解决此问题:

1)如果我将它保留在onCreate

中,它就不起作用

2)如果我将它保存在一个从onCreate调用的新线程中,它就不起作用。

3)如果我将其保留在onClick中,并使用

模拟点击代码,它也不起作用

myButton.performClick(); 以上所有方案都会出现相同的异常错

但有趣的是,如果

recorder.start(); 提到有保持在buttonClick事件,它工作正常。

我无法理解为什么?有人可以帮我解决这个问题吗?我需要在活动启动后立即录制和保存视频。

1 个答案:

答案 0 :(得分:0)

因为将记录器对象加载到内存需要一些时间。所以它会显示非法状态异常。

如果你想在onCreate中使用它,请使用处理程序来延迟。

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        recorder.start();
        }
    }, 1000);

<强>更新

把recorder.start();在prepareRecorder()方法

private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());

try {
    recorder.prepare();
    recorder.start();
} catch (IllegalStateException e) {
    e.printStackTrace();
    finish();
} catch (IOException e) {
    e.printStackTrace();
    finish();
}
}