Android cameraSource.stop () que hace que la aplicación se congele

Estoy construyendo una aplicación que tiene un escáner qr usando el api de visión de google. Tengo problemas para detener la cámara después de leer el código qr. El flujo es MainActivity -> QrActivity una vez que el qr-code recibió una detección de la aplicación debe volver a la actividad principal.

Si no llamo cameraSource.release() funciona bien, pero el dispositivo se calienta mucho y tiene un impacto significativo en el drenaje de la batería. Sin embargo, si libero la fuente de la cámara, la mainActivity se vuelve inaplicable y la aplicación se bloqueará.

¿Por qué se está volviendo insensible? Y dónde está el lugar correcto para liberar la fuente de la cámara?

QrActivity

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qr); cancelBtn = (Button) findViewById(R.id.cancel_button); cancelBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); new QrReader(this); } 

Clase QrReader

 public class QrReader { private static final String TAG = "QrReader"; private SurfaceView cameraView; private TextView barcodeInfo; private BarcodeDetector barcodeDetector; private CameraSource cameraSource; private Activity mActivity; private AccessPointCredentials barCodeData; public QrReader(Activity activity) { this.mActivity = activity; cameraView = (SurfaceView) mActivity.findViewById(R.id.camera_view); barcodeInfo = (TextView) mActivity.findViewById(R.id.code_info); barcodeDetector = new BarcodeDetector.Builder(mActivity) .setBarcodeFormats(Barcode.QR_CODE) .build(); cameraSource = new CameraSource .Builder(mActivity, barcodeDetector) .setAutoFocusEnabled(true) .build(); cameraView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { cameraSource = new CameraSource .Builder(mActivity, barcodeDetector) .setAutoFocusEnabled(true) .setFacing(0) .build(); try { cameraSource.start(cameraView.getHolder()); } catch (Exception ioe) { ioe.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { // Log.i(TAG, "surfaceDestroyed: stopping camera Source"); // cameraSource.release(); } }); barcodeDetector.setProcessor(new Detector.Processor<Barcode>() { @Override public void release() { Log.i(TAG, "release: "); } @Override public void receiveDetections(Detector.Detections<Barcode> detections) { final SparseArray<Barcode> barCodes = detections.getDetectedItems(); if (barCodes.size() != 0) { Log.i(TAG, "received a Barcode"); barcodeInfo.post(new Runnable() { // Use the post method of the TextView public void run() { barcodeInfo.setText(barCodes.valueAt(0).displayValue); } }); Gson g = new Gson(); try { barCodeData = g.fromJson(barCodes.valueAt(0).rawValue, AccessPointCredentials.class); } catch (Exception e) { barCodeData = new AccessPointCredentials(); barCodeData.setSsid(barCodes.valueAt(0).rawValue); barCodeData.setPass(null); e.printStackTrace(); } connectToWifi(barCodeData); // CameraSource.release causes app to freeze // cameraSource.release(); } } }); } private void connectToWifi(final AccessPointCredentials credentials) { //wificonnect code } } 

Ha sido 3 meses, pero me tropecé con el mismo problema y averiguarlo. El código dentro del método receiveDetections se ejecuta en un hilo diferente, así que si quieres hacer algo que necesite el hilo ui que necesitas para publicarlo desde un handler:

 Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { cameraSource.release(); } }); 

Heyo, alguna actualización? Acabo de encontrar un problema similar, trato de lidiar con esos métodos de release , pero no funcionan. Sólo encontré una solución rápida / solución. Quisiera tener una solución elegante.

Mi caso es, un usuario de la aplicación puede escanear un QR-Code y luego hacer el pago.

MainActivity

  1. Menú del cajón ( https://github.com/mikepenz/MaterialDrawer )
  2. Contenedor de fragmentos (cambie los fragmentos cuando los usuarios hacen clic en el menú del cajón)

Todas mis otras vistas son Fragment / ListFragment

ScanMainController

  1. Detector de códigos de barras
  2. CameraSource
  3. SurfaceView

Mi escenario es así, una vez que escaneé el código QR, empujo a otra página para usar para hacer el pago. Pero necesito encontrar una manera de parar el explorador de QRCode mientras que sólo quiero que receiveDetections sea ​​llamado una vez solamente. En iOS, solía establecer el delegate to nil que hace el mismo trabajo que el cameraSource.release(); En Android. Pero entonces, simplemente no puedo encontrar una posición adecuada para llamar al método release() .

Si llamo proactivamente al release() , entonces cuando los usos quieran navegar a otra página haciendo clic en el menú del cajón, mi FragmentTransaction commit será disparado por la aplicación entera se congela. Y luego el sistema Android aparecerá me dicen que la aplicación no está respondiendo.

Rápidamente fijado mediante la adición de una bandera "booleana" dentro de la 'receiveDetections' para garantizar que sólo empujo la vista una vez. Funciona. Pero estoy buscando una forma más elegante y "correcta" manera de hacerlo.

Gracias

  • Utilizar cámara de teléfono inteligente desde una aplicación web para escanear código QR
  • Lector de códigos de barras / Qr para Android
  • ¿Por qué la vista previa de la cámara gira 90 grados en el emulador de Android?
  • Crear un código QR y mostrarlo en ImageView
  • Android con ZXing genera código QR
  • Función nativa para escanear código QR
  • Integre el escáner de código ZXing QR sin instalar BarCode Scanner
  • Javax.net.ssl.SSLException: nombre de host en el certificado no coincide con android
  • Autenticación de código Qr mediante Firebase
  • Cómo codificar información de contacto (MeCard) en Android mediante ZXing
  • Escáner QR con ZXing y ZBar no lee códigos de baja calidad en las tarjetas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.