Reputation: 55
I have integrated camera in my app.When user click on capture button i am making toolbar hide so that camera preview screen size increases.This crashes the app on stopping the recording on line - mMediaRecorder.stop();
.
java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.stop(MediaRecorder.java)
However if i don't hide the toolbar or never show the toolbar then there is no crash.So the problem is because the camera params changes after i hide the toolbar.How could i resolve this?I have seen this answer and added tht code to CameraPreview
class.
private Camera mCamera;
private CameraPreview mPreview;
mCamera = getCameraInstance();
mCamera.setDisplayOrientation(90);
mPreview = new CameraPreview(mActivity, mCamera);
preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(mPreview);
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mToolbar.setVisibility(View.GONE);
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
}
}
}):
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock();
}
}):
CameraPreview.class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
// if(mCamera==null)
// mCamera = getCameraInstance();
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(profile.videoFrameWidth,profile.videoFrameHeight);
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("error", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
Log.e("surfaceDestroyed issue","surfaceDestroyed called");
if ((mCamera != null)&&(!CameraActivity.getInstance().getOnBackPressedListener().isPreview())) {
Log.e("surfaceDestroyed issue","surface destroyed");
try {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}catch(Exception e){}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("error", "Error starting camera preview: " + e.getMessage());
}
}
public static 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; // returns null if camera is unavailable
}
Error-
java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.stop(MediaRecorder.java)
at xyzCameraFragment$5.onClick(CameraFragment.java:208)
at android.view.View.performClick(View.java:4761)
at android.view.View$PerformClick.run(View.java:19767)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
Upvotes: 3
Views: 2647
Reputation: 6588
In you capture click set a boolean
variable
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mToolbar.setVisibility(View.GONE);
startCapture = true;
}):
Hiding the ToolBar
causes surfaceChanged
to get called.
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("error", "Error starting camera preview: " + e.getMessage());
}
//Check if capture is set and start recording
if(startCapture)
{
if (prepareVideoRecorder()) {
mMediaRecorder.start();
}
startCapture = false;
}
}
Upvotes: 1