Search code examples
androidandroid-cameraandroid-hardware

Video camera crashes after latest(4.4.2) Samsung/OS update


I am using custom camera in my application this works fine in jelly bean. Now after this Samsung Galaxy Tab OS update the custom camera is broken. I got this report from one of my friend i didn't saw that tablet. And i got crash report form Carshylytics.

My log report:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.x.y/com.x.y.tools.EnregistrementVideoStackActivity}: java.lang.RuntimeException: Unable to initialize media recorder
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2053)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2154)
       at android.app.ActivityThread.access$700(ActivityThread.java:146)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4949)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1043)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.RuntimeException: Unable to initialize media recorder
       at android.media.MediaRecorder.native_setup(MediaRecorder.java)
       at android.media.MediaRecorder.<init>(MediaRecorder.java:121)
       at com.x.y.tools.EnregistrementVideoStackActivity.<init>(EnregistrementVideoStackActivity.java:38)
       at java.lang.Class.newInstanceImpl(Class.java)
       at java.lang.Class.newInstance(Class.java:1319)
       at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2044)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2154)
       at android.app.ActivityThread.access$700(ActivityThread.java:146)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:4949)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1043)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
       at dalvik.system.NativeStart.main(NativeStart.java)

And this error line is

public MediaRecorder mrec = new MediaRecorder();

Why it is happen have any idea? How can i solve this issue. I hope the camera code is not needed. But anyone want to see the code i can post here.

EDIT:

My EnregistrementVideoStackActivity class:

 public class EnregistrementVideoStackActivity extends Activity implements
        SurfaceHolder.Callback {
    private SurfaceHolder surfaceHolder;
    private SurfaceView surfaceView;
    public MediaRecorder mrec = new MediaRecorder();
    private Button startRecording = null;
    private Button stopRecording = null;
    File video;
    private Camera mCamera;
    private String output_path;

    boolean isActivityRestarting = false;

    Chronometer myChronometer;
    Boolean recording = false;

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (recording == false) {
                finish();
            } else {
                stopRecording();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onRestart() {
        super.onRestart();
        isActivityRestarting = true;
        finish();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (isActivityRestarting) {
            return;
        }

        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        /*getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);*/

        setContentView(R.layout.camera_surface);
        Intent intent = getIntent();

        output_path = intent.getStringExtra("path");

        startRecording = (Button) findViewById(R.id.buttonstart);
        stopRecording = (Button) findViewById(R.id.buttonstop);
        try {
            // This case can actually happen if the user opens and closes the
            // camera too frequently.
            // The problem is that we cannot really prevent this from happening
            // as the user can easily
            // get into a chain of activites and tries to escape using the back
            // button.
            // The most sensible solution would be to quit the entire EPostcard
            // flow once the picture is sent.
            mCamera = Camera.open();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(),
                    "Please restart device, camera error", Toast.LENGTH_LONG)
                    .show();
            finish();
            return;
        }
        surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        myChronometer = (Chronometer) findViewById(R.id.chronometer1);

        startRecording.setOnClickListener(new OnClickListener() {

            public void onClick(View arg0) {
                try {
                    startRecording();
                    myChronometer.setBase(SystemClock.elapsedRealtime());
                    myChronometer.start();

                    startRecording.setClickable(false);
                } catch (Exception e) {
                    e.getMessage();
                    e.printStackTrace();
                    mrec.release();
                }

            }
        });
        stopRecording.setOnClickListener(new OnClickListener() {

            public void onClick(View arg0) {
                try {
                    stopRecording();
                    myChronometer.stop();
                    Intent intent = getIntent();
                    intent.putExtra("gallery", "viewed");
                    setResult(RESULT_OK, intent);
                } catch (Exception e) {
                    e.getMessage();
                }

            }
        });

        myChronometer
                .setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {

                    public void onChronometerTick(Chronometer chronometer) {
                        long myElapsedMillis = SystemClock.elapsedRealtime()
                                - myChronometer.getBase();
                        if (myElapsedMillis >= 120000) {
                            Toast.makeText(getApplicationContext(),
                                    "Maximum Video limit reached",
                                    Toast.LENGTH_LONG).show();
                            stopRecording();
                        }
                    }
                });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, 0, 0, "StartRecording");
        menu.add(0, 1, 0, "StopRecording");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case 0:
            try {
                startRecording();
            } catch (Exception e) {
                String message = e.getMessage();
                Log.e(null, "Problem Start" + message);
                mrec.release();
            }
            break;

        case 1: // GoToAllNotes
            mrec.stop();
            mrec.release();
            mrec = null;
            break;

        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void startRecording() throws IOException {
        recording = true;
        mrec = new MediaRecorder(); // Works well
        mCamera.unlock();
        mrec.setCamera(mCamera);
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setAudioSource(MediaRecorder.AudioSource.MIC);

        mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        mrec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        int width = 320;
        int height = 240;
        try {
            // Check what resolutions are supported by your camera
            List<Size> sizes = params.getSupportedPictureSizes();

            for (Size size : sizes) {

                Log.e("TAG", "Available resolution: " + size.width + " "
                        + size.height);
                width = size.width;
                height = size.height;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        mrec.setVideoFrameRate(30);
        mrec.setVideoSize(width, height);
        mrec.setVideoEncodingBitRate(1700000);
        mrec.setPreviewDisplay(surfaceHolder.getSurface());
        mrec.setOutputFile(output_path);
        mrec.prepare();
        mrec.start();
    }

    protected void stopRecording() {
        try {
            Log.e("stop recording", "Stop recording");
            recording = false;
            mrec.stop();
            mrec.release();
            mCamera.release();
            // go out

            Toast.makeText(getApplicationContext(),
                    "New Video Observation Saved", Toast.LENGTH_LONG).show();
        } catch (Exception npe) {
            npe.printStackTrace();
        }
        Intent intent = getIntent();
        setResult(RESULT_OK, intent);
        finish();

    }

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

    Parameters params;

    public void surfaceCreated(SurfaceHolder holder) {
        if (!isActivityRestarting) {
            if (mCamera != null) {
                params = mCamera.getParameters();
                mCamera.setParameters(params);
            } else {
                Toast.makeText(getApplicationContext(),
                        "Camera not available!", Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera.setPreviewCallback(null);
                mCamera = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (recording == false) {
            finish();
        } else {
            stopRecording();
        }
    }
}

Solution

  • I got the error Because of Video sizes are not set. I solve this

    int width = 320;
                int height = 240;
                try {
                    //get the available sizes of the video
                    List<Size> tmpList = getSupportedVideoSizes();
    
                    final List<Size> sizeList = new Vector<Size>();
    
                    // compare the apsect ratio of the candidate sizes against the
                    // real ratio
                    Double aspectRatio = (Double.valueOf(getWindowManager()
                            .getDefaultDisplay().getHeight()) / getWindowManager()
                            .getDefaultDisplay().getWidth());
                    for (int i = tmpList.size() - 1; i > 0; i--) {
                        Double tmpRatio = Double.valueOf(tmpList.get(i).height)
                                / tmpList.get(i).width;
    
                        if (Math.abs(aspectRatio - tmpRatio) < .15) {
                            width = tmpList.get(i).width;
                            height = tmpList.get(i).height;
                            sizeList.add(tmpList.get(i));
                        }
                    }
                    if (EnableLog.LOG_TAG) {
                        Log.e("tmpList", tmpList + "*");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
    mrec.setVideoSize(width, height);
    
    public List<Size> getSupportedVideoSizes() {
            if (params.getSupportedVideoSizes() != null) {
                return params.getSupportedVideoSizes();
            } else {
                // Video sizes may be null, which indicates that all the supported
                // preview sizes are supported for video recording.
                return params.getSupportedPreviewSizes();
            }
        }