13

Ho un problema riguardante la fotocamera nella build Marshmallow più recente, in particolare la torcia. su qualsiasi versione pre-Marshmallow tutto quello che devo fare per attivare il flash on/off è stato il seguente:Controllo torcia in Marshmallow

private void turnFlashOn(final Camera camera, int flashLightDurationMs) { 
    if (!isFlashOn()) { 
     final List<String> supportedFlashModes = camera.getParameters().getSupportedFlashModes(); 
     if (supportedFlashModes != null && supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) { 
      mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
      camera.setParameters(mParams); 
     } 
    } 
} 

e

private void turnFlashOff(Camera camera) { 
    if (camera != null) { 
     final List<String> supportedFlashModes = camera.getParameters().getSupportedFlashModes(); 
     if (supportedFlashModes != null && supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) { 
      mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
      camera.setParameters(mParams); 
     } 
    } 
} 

Purtroppo, dispositivi Marshmallow ha cominciato a bloccarsi in natura. In qualche modo camera.getParameters() e camera.setParameters() cominciarono a fallire con messaggi come:

RuntimeException: getParameters fallito (parametri vuoto)

RuntimeException: setParameters fallito

ho provato avviare e arrestare l'anteprima prima di ottenere il parametri, che non generano più errori. Tuttavia l'anteprima non viene ripresa quando chiamo camera.startPreview().

Temo di rilasciare la fotocamera e riaprirla è fuori questione in quanto ciò richiede alcuni secondi e produrrebbe una brutta esperienza.

Qualche suggerimento su come accendere/spegnere la torcia in Marshmallow in modo affidabile?

risposta

0

Aggiorna l'app per verificare le autorizzazioni in fase di esecuzione. Devi avere android.permission.CAMERA concesso. Includerlo nel manifesto della tua app non te lo concederà su Marshmallow. Dovrai rilevare se è stato concesso o meno e richiederlo.

+0

ho già il permesso fotocamera. Non ho il targeting 23, quindi non ho ancora bisogno di verificare le autorizzazioni di runtime, giusto? –

+0

Sì e no. Se non hai scelto come target 23, l'autorizzazione dovrebbe essere già stata concessa. Tuttavia, l'utente può disattivare questa autorizzazione dopo l'installazione. In tal caso, è necessario verificare (se in esecuzione su un dispositivo API 23) se si dispone dell'autorizzazione o meno. Se non lo fai perché l'utente l'ha rifiutato, le API della fotocamera potrebbero restituire dati vuoti o nulli. Questo talk fornirà maggiori dettagli sulle modifiche ai permessi per Marshmallow: https://youtu.be/WGz-alwVh8A?list=PLnVy79PaFHMUqqvwbjyKJZv1N8rzHOCBi –

+0

Hai ragione, è proprio così. Tuttavia, l'app si arresta in modo anomalo anche con autorizzazioni concesse, quindi sembra che qualcosa di correlato all'API di Camera sia cambiato e si comporta in modo diverso rispetto a Lollipop o Kitkat. –

4

Google ha introdotto torchmode in OS 6 (Android M).
se il vostro scopo è solo quello di accendere/spegnere il flash, sotto il codice può aiutare con che:

private static void handleActionTurnOnFlashLight(Context context){ 
    try{ 

     CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 
     String[] list = manager.getCameraIdList(); 
     manager.setTorchMode(list[0], true); 
    } 
    catch (CameraAccessException cae){ 
     Log.e(TAG, cae.getMessage()); 
     cae.printStackTrace(); 
    } 
} 

private static void handleActionTurnOffFlashLight(Context context){ 
    try{ 
     CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 
     manager.setTorchMode(manager.getCameraIdList()[0], false); 
    } 
    catch (CameraAccessException cae){ 
     Log.e(TAG, cae.getMessage()); 
     cae.printStackTrace(); 
    } 
} 

Tutto quello che dovete fare è: ottenere l'elenco di cameraid dal quale ID della telecamera zero (0) è la tua fotocamera principale per cui desideri attivare/disattivare il flash. Basta passare l'ID fotocamera a setTochMode API con valore booleano per attivarlo o disattivarlo.

Si noti che questa parte di codice funziona solo con OS 6, quindi è necessario controllare il sistema operativo del dispositivo e in base a ciò è necessario selezionare le API da chiamare per i dispositivi pre-marshmallow.

Contrassegnare questo come soluzione se risolve il problema.

1

Come Saurabh7474 has responded, per verificare la versione di Android e utilizzare l'API setTorchMode è molto corretto.

Anche se è possibile utilizzare anche params.setFlashMode (...) in marshmallow utilizzando

mCamera.setPreviewTexture (new SurfaceTexture (100)) 

dopo Camera.open (...) e prima di chiamare mCamera.startPreview();

try { 
       Log.i(TAG, "getCamera"); 
       int requestedCameraId = getIdForRequestedCamera(mFacing); 
       if (requestedCameraId == -1) { 
        throw new RuntimeException("Could not find requested camera."); 
       } 
       mCamera = Camera.open(requestedCameraId); 
       mCamera.setPreviewTexture(new SurfaceTexture(DUMMY_TEXTURE_NAME)); 
       params = mCamera.getParameters(); 
      } catch (RuntimeException e) { 
       Log.e("Failed to Open. Error:", e.getMessage()); 
      } catch (IOException e) { 
       Log.e("Failed to Open. can't setPreviewTexture:", e.getMessage()); 
      } 

poi quando si desidera, è possibile utilizzare

 mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
     camera.setParameters(mParams); 

La mia risposta si basa su esempi CameraSource di Vision API che utilizza params.setFlashMode (...) e lavora in Api 23 e sopra. Se si decide di ispezionare CameraSource, il metodo della chiave che ha risolto lo stesso problema è "start()", nella linea 312 ...

https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java

La ragione è possibile trovare qui https://stackoverflow.com/a/33333046/4114846

0

costruzione off di risposta di Saurabh7474, è possibile alternare torchMode del Marshmallow registrando un torchCallback:

final CameraManager mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 
CameraManager.TorchCallback torchCallback = new CameraManager.TorchCallback() { 
    @Override 
    public void onTorchModeUnavailable(String cameraId) { 
     super.onTorchModeUnavailable(cameraId); 
    } 

    @Override 
    public void onTorchModeChanged(String cameraId, boolean enabled) { 
     super.onTorchModeChanged(cameraId, enabled); 
     boolean currentTorchState = enabled; 
     try { 
      mCameraManager.setTorchMode(cameraId, !currentTorchState); 
     } catch (CameraAccessException e){} 



    } 
}; 

mCameraManager.registerTorchCallback(torchCallback, null);//fires onTorchModeChanged upon register 
mCameraManager.unregisterTorchCallback(torchCallback); 
Problemi correlati