camera app not working?

2019-01-12 04:32发布

问题:

I got following stack trace

04-17 12:11:56.378: D/ATRecorder(10379): com.htc.autotest.dlib.RecordEngine in loader dalvik.system.DexClassLoader@40528b78
04-17 12:11:56.408: D/WindowManagerImpl(10379): addView, new view, mViews[0]: com.android.internal.policy.impl.PhoneWindow$DecorView@40520738
04-17 12:11:56.428: D/WindowManagerImpl(10379): addView, new view, mViews[1]: android.widget.LinearLayout@40525d00
04-17 12:11:56.438: D/WindowManagerImpl(10379): finishRemoveViewLocked, mViews[1]: android.widget.LinearLayout@40525d00
04-17 12:11:56.718: D/TAG(10379): Error setting camera preview: setPreviewDisplay failed
04-17 12:11:56.748: D/TAG(10379): Error starting camera preview: setPreviewDisplay failed
04-17 12:12:07.558: D/View(10379): onTouchEvent: viewFlags: 0x18004001
04-17 12:12:07.568: D/View(10379): onTouchEvent: isFocusable: true, isFocusableInTouchMode: false, isFocused: false; focusTaken: false
04-17 12:12:07.588: V/MediaRecorderJNI(10379): start
04-17 12:12:07.598: V/MediaRecorderJNI(10379): getMediaRecorder E
04-17 12:12:11.632: V/MediaRecorderJNI(10379): process_media_recorder_call
04-17 12:12:11.642: W/IMediaDeathNotifier(10379): media server died
04-17 12:12:11.642: V/MediaRecorderJNI(10379): JNIMediaRecorderListener::notify
04-17 12:12:11.642: V/MediaRecorderJNI(10379): notify msgType 0x1, ext1 0x64
04-17 12:12:11.642: W/Camera(10379): ICamera died
04-17 12:12:11.642: W/Camera(10379): Camera server died!
04-17 12:12:11.702: E/Camera(10379): Error 100

and my code is

public class VideoDemoActivity extends Activity {
/** Called when the activity is first created. */

private Camera mCamera;
private CameraPreview mPreview;
private Button btnCapture,btnStop;

private MediaRecorder mMediaRecorder;
FrameLayout preview;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    initialize();

    if (!checkCameraHardware(this)) {

        Toast.makeText(this, "Camera not found", Toast.LENGTH_SHORT).show();
        finish();

    } else {

        Toast.makeText(this, "Camera found", Toast.LENGTH_SHORT).show();
    }

    mCamera = getCameraInstance();
    mPreview = new CameraPreview(this, mCamera);
    preview.addView(mPreview);

    System.out.println(prepareVideoRecorder());


    btnCapture.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            try {

                mMediaRecorder.start();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    });

    btnStop.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mMediaRecorder.stop();
        }
    });

}

private void initialize() {
    // TODO Auto-generated method stub

    preview = (FrameLayout) findViewById(R.id.camera_preview);
    btnCapture = (Button) findViewById(R.id.button_capture);
    btnStop = (Button) findViewById(R.id.button_stop);
}

public Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){

        e.printStackTrace();

    }
    return c; // returns null if camera is unavailable
}

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
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();

     releaseMediaRecorder();       // if you are using MediaRecorder, release it first
     releaseCamera();              // release the camera immediately on pause event

}

private boolean prepareVideoRecorder(){


    mMediaRecorder = new MediaRecorder();


    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    mMediaRecorder.setOutputFile(getOutputMediaFile().toString());



    try 
    {
        mMediaRecorder.prepare();

    } catch (IllegalStateException e) {
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    }
    return true;
}

private void releaseMediaRecorder(){
    if (mMediaRecorder != null) {
        mMediaRecorder.reset();   // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        mCamera.lock();           // lock camera for later use
    }
}

private void releaseCamera(){
    if (mCamera != null){
        mCamera.release();        // release the camera for other applications
        mCamera = null;
    }
}

private static File getOutputMediaFile(){

     File mediaFile = new File(Environment.getExternalStorageDirectory()+"/video.mp4");

    return mediaFile;
}

}

So please help me in solving this problem.. If I remove the method

prepareVideoRecorder()

then it previews the camera properly.. but after this method execution it does not show any preview..and it fails

mMediaRecorder.start();

pleas help me out..

回答1:

You have to unlock the camera before creating MediaRecorder. And lock it before releasing it.

Try this code, it will work Have fun...

package com.marcodinacci.book.acb;

import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ToggleButton;

public class MediaRecorderRecipe extends Activity implements SurfaceHolder.Callback {

    private final String VIDEO_PATH_NAME = "/mnt/sdcard/VGA_30fps_512vbrate.mp4";

    private MediaRecorder mMediaRecorder;
    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mHolder;
    private View mToggleButton;
    private boolean mInitSuccesful;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.media_recorder_recipe);

        // we shall take the video in landscape orientation
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton);
        mToggleButton.setOnClickListener(new OnClickListener() {
            @Override
            // toggle video recording
            public void onClick(View v) {
                if (((ToggleButton)v).isChecked()) {
                    mMediaRecorder.start();
                    try {
                        Thread.sleep(10 * 1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    finish();
                }
                else {
                    mMediaRecorder.stop();
                    mMediaRecorder.reset();
                    try {
                        initRecorder(mHolder.getSurface());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });     
    }

    /* Init the MediaRecorder, the order the methods are called is vital to
     * its correct functioning */
    private void initRecorder(Surface surface) throws IOException {
        // It is very important to unlock the camera before doing setCamera
        // or it will results in a black preview
        if(mCamera == null) {
            mCamera = Camera.open();
            mCamera.unlock();
        }

        if(mMediaRecorder == null)  mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setPreviewDisplay(surface);
        mMediaRecorder.setCamera(mCamera);

        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
       //       mMediaRecorder.setOutputFormat(8);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(640, 480);
        mMediaRecorder.setOutputFile(VIDEO_PATH_NAME);

        try {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e) {
            // This is thrown if the previous calls are not called with the 
            // proper order
            e.printStackTrace();
        }

        mInitSuccesful = true;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if(!mInitSuccesful)
                initRecorder(mHolder.getSurface());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        shutdown();
    }

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

    private void shutdown() {
        // Release MediaRecorder and especially the Camera as it's a shared
        // object that can be used by other applications
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mCamera.release();

        // once the objects have been released they can't be reused
        mMediaRecorder = null;
        mCamera = null;
    }

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.marcodinacci.book.acb"
      android:versionCode="1"
      android:versionName="1.0">

     <uses-sdk android:minSdkVersion="7" />
     <uses-permission android:name="android.permission.CAMERA"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-feature android:name="android.hardware.camera.autofocus" />

     <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name="MediaRecorderRecipe"
              android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

     </application>
</manifest>

media_recorder_recipe.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ToggleButton
         android:id="@+id/toggleRecordingButton"
         android:layout_width="fill_parent"
         android:textOff="Start Recording" 
         android:textOn="Stop Recording"
         android:layout_height="wrap_content"/>

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <SurfaceView android:id="@+id/surfaceView" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"></SurfaceView>
    </FrameLayout>

</LinearLayout>


回答2:

Have you given the permissions in the manifest?

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name = "android.permission.RECORD_AUDIO"/>