La aplicación se bloquea cuando se reanuda

Estoy creando una sencilla aplicación de linterna, pero cada vez que dejo la aplicación y la vuelvo a abrir, se bloquea. ¿Me estoy perdiendo algo en mi código, porque no estoy seguro de qué, a continuación es un error cuando se bloquea. Por favor, hágamelo saber lo que tengo que hacer para solucionar este problema de curriculum vitae:

package com.example.gkvxm.materiallight; import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.Toast; import com.dd.CircularProgressButton; import java.io.IOException; public class FlashLightActivity extends Activity implements SurfaceHolder.Callback { private boolean isLigtOn = false; private Camera camera; @Override protected void onStart(){ super.onStart(); SurfaceView preview = (SurfaceView)findViewById(R.id.PREVIEW); SurfaceHolder mHolder = preview.getHolder(); mHolder.addCallback(this); } @Override protected void onStop(){ super.onStop(); if(camera!=null){ camera.release(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_flash_light); Context context = this; PackageManager pm = context.getPackageManager(); if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { Toast.makeText(FlashLightActivity.this, "Your Device is not supported", Toast.LENGTH_SHORT).show(); Log.e("err", "Device is not supported"); return; } camera = Camera.open(); final Camera.Parameters p = camera.getParameters(); final CircularProgressButton circularButton1 = (CircularProgressButton) findViewById(R.id.btnWithText); circularButton1.setIndeterminateProgressMode(true); circularButton1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isLigtOn) { turnOffFlash(p); Toast.makeText(FlashLightActivity.this, "Lights Off!", Toast.LENGTH_SHORT).show(); } else { turnOnFlash(p); Toast.makeText(FlashLightActivity.this, "Lights On!", Toast.LENGTH_SHORT).show(); } if (circularButton1.getProgress() == 0) { simulateSuccessProgress(circularButton1); } else { circularButton1.setProgress(0); } } }); } private void turnOnFlash(Camera.Parameters p){ p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); camera.setParameters(p); camera.startPreview(); isLigtOn = true; } private void turnOffFlash(Camera.Parameters p){ p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); camera.setParameters(p); camera.stopPreview(); isLigtOn = false; } @Override public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){ } @Override public void surfaceCreated(SurfaceHolder holder){ try{ Log.i("SurfaceHolder","Setting preview"); camera.setPreviewDisplay(holder); } catch (IOException e){ e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder){ Log.i("SurfaceHOlder", "stopping preview"); camera.stopPreview(); holder = null; } private void simulateSuccessProgress(final CircularProgressButton button) { ValueAnimator widthAnimation = ValueAnimator.ofInt(1, 100); widthAnimation.setDuration(1500); widthAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); button.setProgress(value); } }); widthAnimation.start(); } private void simulateErrorProgress(final CircularProgressButton button) { ValueAnimator widthAnimation = ValueAnimator.ofInt(1, 99); widthAnimation.setDuration(1500); widthAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); button.setProgress(value); if (value == 99) { button.setProgress(-1); } } }); widthAnimation.start(); } } 

 05-22 03:08:35.646 13909-13909/com.example.gkvxm.materiallight E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.example.gkvxm.materiallight, PID: 13909 java.lang.RuntimeException: Camera is being used after Camera.release() was called at android.hardware.Camera._stopPreview(Native Method) at android.hardware.Camera.stopPreview(Camera.java:732) at com.example.gkvxm.materiallight.FlashLightActivity.surfaceDestroyed(FlashLightActivity.java:129) at android.view.SurfaceView.updateWindow(SurfaceView.java:564) at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:238) at android.view.View.dispatchWindowVisibilityChanged(View.java:8785) at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1164) at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1164) at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1164) at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1164) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1318) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 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:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

La cámara se está utilizando después de llamar a Camera.release (). Por lo tanto, mirando el ciclo de vida de la actividad que necesita para abrir la cámara en onStart () o onRestart (). Así que este código puede funcionar bien …

  package com.example.gkvxm.materiallight; import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.Toast; import com.dd.CircularProgressButton; import java.io.IOException; public class FlashLightActivity extends Activity implements SurfaceHolder.Callback { private boolean isLigtOn = false; private Camera camera; @Override protected void onStart(){ super.onStart(); camera = Camera.open(); final Camera.Parameters p = camera.getParameters(); SurfaceView preview = (SurfaceView)findViewById(R.id.PREVIEW); SurfaceHolder mHolder = preview.getHolder(); mHolder.addCallback(this); } @Override protected void onStop(){ super.onStop(); if(camera!=null){ camera.release(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_flash_light); Context context = this; PackageManager pm = context.getPackageManager(); if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { Toast.makeText(FlashLightActivity.this, "Your Device is not supported", Toast.LENGTH_SHORT).show(); Log.e("err", "Device is not supported"); return; } camera = Camera.open(); final Camera.Parameters p = camera.getParameters(); final CircularProgressButton circularButton1 = (CircularProgressButton) findViewById(R.id.btnWithText); circularButton1.setIndeterminateProgressMode(true); circularButton1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isLigtOn) { turnOffFlash(p); Toast.makeText(FlashLightActivity.this, "Lights Off!", Toast.LENGTH_SHORT).show(); } else { turnOnFlash(p); Toast.makeText(FlashLightActivity.this, "Lights On!", Toast.LENGTH_SHORT).show(); } if (circularButton1.getProgress() == 0) { simulateSuccessProgress(circularButton1); } else { circularButton1.setProgress(0); } } }); } private void turnOnFlash(Camera.Parameters p){ p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); camera.setParameters(p); camera.startPreview(); isLigtOn = true; } private void turnOffFlash(Camera.Parameters p){ p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); camera.setParameters(p); camera.stopPreview(); isLigtOn = false; } @Override public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){ } @Override public void surfaceCreated(SurfaceHolder holder){ try{ Log.i("SurfaceHolder","Setting preview"); camera.setPreviewDisplay(holder); } catch (IOException e){ e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder){ Log.i("SurfaceHOlder", "stopping preview"); camera.stopPreview(); holder = null; } private void simulateSuccessProgress(final CircularProgressButton button) { ValueAnimator widthAnimation = ValueAnimator.ofInt(1, 100); widthAnimation.setDuration(1500); widthAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); button.setProgress(value); } }); widthAnimation.start(); } private void simulateErrorProgress(final CircularProgressButton button) { ValueAnimator widthAnimation = ValueAnimator.ofInt(1, 99); widthAnimation.setDuration(1500); widthAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); button.setProgress(value); if (value == 99) { button.setProgress(-1); } } }); widthAnimation.start(); } } 

Como el registro dice que la Camera is being used after Camera.release() was called . Por lo tanto, mirando el ciclo de vida de la actividad que necesita para abrir la cámara en onStart() o en onRestart()

Esta excepción se debe a camera.release(); Se llama en el método onStop() de su actividad. Después de liberar la instancia de la cámara, está reutilizando la instancia liberada.

  camera = Camera.open(); 

Mover la línea anterior de OnCreate() a onStart()

Está liberando la instancia de la cámara en onPause () que es correcta debido a la documentación:

Public final void release ()

Se agrega en el nivel 1 de API. Desconecta y libera los recursos de objetos de la cámara.

Debe llamar a esta función tan pronto como termine con el objeto Cámara.

Pero también es necesario volver a abrirlo en onResume (), como lo hace en onCreate, ya que onCreate () no siempre se llama cuando se reanuda la aplicación.

Como ellos declaran aquí :

Importante: Llamada de liberación () para liberar la cámara para su uso por otras aplicaciones. Las aplicaciones deben liberar la cámara inmediatamente en onPause () (y re-open () en onResume ()).

Consulte esto para obtener más información sobre el ciclo de vida de la aplicación para Android.

¡Buena suerte!

Puede ser que sea camera.release(); En onStop() . Y cuando surfaceDestroyed llamada usted ha utilizado camera.stopPreview();

Por lo que la camera está liberada y se va a stopePreview . Thats manera usted está consiguiendo La Camera is being used after Camera.release() was called este error.

Así que tienes que cange que.

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

Y en la surfaceDestroyed

 @Override public void surfaceDestroyed(SurfaceHolder holder){ Log.i("SurfaceHOlder", "stopping preview"); camera.stopPreview(); camera.release(); holder = null; } 

Tengo el mismo problema con la clase de cámara. Utilice esta línea onResume ()

 mCameraPreview.getHolder().removeCallback(mCameraPreview); 

Y su trabajo ahora.

  • Android ViewPager setCurrentItem no funciona después de onResume
  • Actividad que no llama onDestroy () después de terminar ()
  • ¿Por qué onResume se llama cuando abro por primera vez la pestaña de un tabhost?
  • Reemplazar un Fragmento consigo mismo no muestra nada
  • Cómo probar automáticamente onResume el comportamiento llamando onDestroy usando Robotium?
  • Android: "Nivel de aplicación" Pausa y reanudar
  • ciclo de vida de la actividad Android
  • Determine si la actividad se adelantó debido a la navegación posterior
  • No se puede reanudar la actividad
  • ¿Cómo reinicio una actividad en android?
  • Error en el administrador de descargas android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.