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(); } }
- ¿Por qué onResume método de un fragmento nunca se disparó después de despedir un DialogFragment que se inició desde el fragmento?
- Se reanuda el fragmento que no es el más alto en backstack
- ViewPager con fragmentos - onPause (), onResume ()?
- Get onPause & onResume como eventos en el nivel de aplicación / tarea
- Android onResume adaptador de lista de actualización
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)
- ¿Cómo usar onResume ()?
- ¿Cómo volver a la misma instancia de actividad después de reanudarla?
- Ciclo de vida de la actividad de Android: ¿para qué sirven todos estos métodos?
- ¿Qué método de actividad se llama cuando ocurren cambios de orientación?
- usando onResume y onPause
- Android: ejecuta el código onResume y onPause para todas las actividades de la aplicación?
- Fragmento onResume () & onPause () no se llama en backstack
- ¿Se llama al método onResume después de que una alerta se descarta en Android?
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.