Android地狱:MediaRecorder.Start()总是抛出IllegalStateException

时间:2014-12-31 02:56:06

标签: android android-camera surfaceview android-fragmentactivity android-mediarecorder

我有这个相机应用预览好,但每当我尝试录制它时,给我一个非法的感觉就像我的MediaRecorder没有正确设置但是确实如此。我必须注意,我正在使用模拟器来模拟前后凸轮。

 package l33trus.com.shite


 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.Camera;
 import android.hardware.Camera.CameraInfo;
 import android.media.CamcorderProfile;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;

 import java.io.IOException;
 import java.util.Calendar;



  public class VideoCapture extends Fragment implements OnClickListener,  SurfaceHolder.Callback ,MediaRecorder.OnInfoListener,Camera.PictureCallback
{
public static final String LOGTAG = "VIDEOCAPTURE";

private static final int PICTURE_SIZE_MAX_WIDTH = 0;
String[] varNames;  // for reflection function

private MediaRecorder recorder;
private MediaPlayer mp;
private SurfaceHolder holder;
int cameraCount = 0;
private CamcorderProfile camcorderProfile;
//final MediaPlayer interfaceSounds;
Cvars varPtr; // static global variable class

private ImageView isRecordingView;
private boolean photoMode; // if not in photo mode it's in video mode
private Camera camera;
private Camera.Size mPreviewSize;
private ImageButton recordButton;
private RawCallback rawCallback;
private SurfaceView cameraView;
CameraInfo cameraInfo = new CameraInfo();
private int resid = 0;
private int cameraId;
String fileExtension = ".mp4";

private boolean recording = false;

public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

private View currentView;
private LayoutInflater inflateTmp;

private boolean usecamera = true;
private boolean previewRunning = false;
private boolean paused = false;


@Override
public void onSaveInstanceState(Bundle state)
{
    super.onSaveInstanceState(state);

}

public VideoCapture()
{

}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
{
    View rootView = inflater.inflate(R.layout.videocapture, container, false);
    recordButton = (ImageButton) rootView.findViewById(R.id.recordButton);
    SurfaceView cameraView = (SurfaceView) rootView.findViewById(R.id.CameraView);

    initRecorder();
    holder = cameraView.getHolder();
    holder.addCallback(this);

    previewRunning = true;

    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
    {
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    recordButton.setOnClickListener(this);
    cameraView.setClickable(true);
    cameraView.setOnClickListener(this);
    this.currentView = rootView;
    this.inflateTmp = inflater;

    return rootView;
}

private void initRecorder()
{

    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

    CamcorderProfile cpHigh = CamcorderProfile.get(cameraInfo.facing,CamcorderProfile.QUALITY_HIGH);
    recorder.setProfile(cpHigh);
    String fileName = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
    recorder.setOutputFile(varPtr.DefaultStorageDir + fileName  + ".mp4");
    recorder.setMaxDuration(50000); // 50 seconds

}


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

    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
        Toast toasty = Toast.makeText(this.getActivity(),"IllegalStateException prepareRecorder",Toast.LENGTH_LONG);
    } catch (IOException e) {
        e.printStackTrace();
        Toast toasty = Toast.makeText(this.getActivity(),"IOException prepareRecorder",Toast.LENGTH_LONG);
    }
}


public void onRecordStop() // handles manually stopping of the record and also called if it is closed when a tab or orientation is changed
{
    recorder.stop();
    recorder.release();
    recording = false;
    varPtr.recording = false;

     isRecordingView.setImageResource(R.drawable.notrecordingimage);
     recordButton.setImageResource(R.drawable.recording_button);
}

public void onRecordStart()
{
    recording = true;
    varPtr.recording = recording;
    isRecordingView.setImageResource(R.drawable.recordingimage);
    recordButton.setImageResource(R.drawable.record_stop_button);
}


@Override
public void onClick(View v)
{
    switch (v.getId())
    {
        case R.id.recordButton:
            if(photoMode)
            {
                //camera.takePicture(shutter,mPicture,new ImageCaptureCallback(this));

            }
            if (recording)
            {
                recorder.stop();

                if (usecamera)
                 {
                    try {
                        camera.reconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                recorder.release();   
                prepareRecorder();
            }
            else
            {
                onRecordStart();
                recorder.start();

                Log.v(LOGTAG, "Recording Started");
            }
            recording ^= true;
            varPtr.recording = recording;
            break;
        case R.id.CameraView:

            break;
        case R.id.photoToggleButton:
            photoMode ^= true;
            break;
        case R.id.videoToggleButton:
            photoMode ^= true;
            break;
    }
}

private Camera getCameraInstance()
{
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    } catch (Exception e) {
        // Camera is not available (in use or does not exist)
    }
    return c;
}


private boolean checkCameraHardware(Context context)
{
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
    {
        // this device has a camera
        return true;
    }
    else
    {
        // no camera on this device
        return false;
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder)
{
    Log.v(LOGTAG, "surfaceCreated");
    // configure(camera);
    if(! checkCameraHardware(getActivity().getApplicationContext()))
    {
        getActivity().finish();
    }
    prepareRecorder();

    try
    {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
        previewRunning = true;
    } catch (IOException e)
    {
        Log.e(LOGTAG,e.getMessage());
        e.printStackTrace();
    } catch (NullPointerException e)
    {
        Log.e("WTF","This sucks");
        e.printStackTrace();
    }

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
    Log.v(LOGTAG, "surfaceChanged");
    if (!recording && usecamera)
    {

        try
        {
            Camera.Parameters p = camera.getParameters();

            p.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
            p.setPreviewFrameRate(camcorderProfile.videoFrameRate);

            camera.setParameters(p);

            holder = cameraView.getHolder();
            holder.addCallback(this);
            camera.setPreviewDisplay(holder);
            camera.startPreview();
            previewRunning = true;
        }
        catch (IOException e)
        {
            Log.e(LOGTAG,e.getMessage());
            e.printStackTrace();
        }
        catch(NullPointerException e)
        {
            Log.e("WTF","I hate my life");
            e.printStackTrace();
        }
        prepareRecorder();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    Log.v(LOGTAG, "surfaceDestroyed");
    if (recording)
    {
        recorder.stop();
        onRecordStop();
    }

}

@Override
public void onPause()
{
    super.onPause();
    holder.removeCallback(this); //http://stackoverflow.com/questions/12411346/camera-is-null-when-the-surfacecreated-method-is-executed-for-second-time
    camera.release();
}

@Override
public void onInfo(MediaRecorder mr, int what, int extra)
{

}

@Override
public void onPictureTaken(byte[] data, Camera camera) 
{

}
}

这是logcat所说的

start called in an invalid state: 4
1762-1762/com.L33TRUS.shite D/AndroidRuntime﹕ Shutting down VM
1762-1762/com.L33TRUS.shite W/dalvikvm﹕ threadid=1: thread exiting with uncaught  exception (group=0x409961f8)
1762-1762/com.L33TRUS.shite E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException
        at android.media.MediaRecorder.start(Native Method)
        at l33trus.com.moment.Fragments.VideoCapture.onClick(VideoCapture.java:194)

1 个答案:

答案 0 :(得分:0)

通过清理像这样的文件名来修复

 fileName = fileName.replaceAll(":", "~");
    fileName = fileName.replaceAll(",","");
    fileName = fileName.replaceAll(" ","_");

还确保在通过mkdirs()调用

打开文件之前创建了dirs