Usa la linterna de la cámara en Android

Estoy tratando de usar la linterna LED de las cámaras en un widget. He encontrado varios hilos sobre este tema (es decir, el que se menciona más adelante …), ahora estoy tratando de controlar la luz usando:

Camera cam = Camera.open(); Parameters p = cam.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); cam.setParameters(p); cam.release(); 

En AndroidManifest.xml probé diferentes permisos, actualmente tengo:

      

Estoy probando esto en mi Galaxy Tab ya que no tengo ningún otro dispositivo Android a mano: la luz no se enciende. Entonces tengo algunas preguntas ahora:

  1. ¿Hay alguna manera de probar el comportamiento de la luz led en el emulador?
  2. ¿Estoy haciendo algo mal aquí?
  3. De acuerdo con esta pregunta que trata el mismo problema, funciona de manera diferente en el Galaxy Tab. ¿Cómo?
  4. Y, por último, si funciona de manera diferente, empiezo a preguntarme si es solo Galaxy Tab o si otros dispositivos también usan métodos diferentes. Sería difícil probarlo entonces y me parece bastante extraño.

Gracias por cualquier idea!

Por cierto, probé rápidamente con ajustes rápidos, que se mencionan aquí varias veces. La linterna tampoco funciona con configuraciones rápidas.

Tenga en cuenta que Galaxy Tab stil usa Android 2.2. Veo que hubo algunos cambios entre 2.2 y 2.3.

Comentario: Sé que tiene que funcionar de alguna manera, ya que he encontrado otras aplicaciones en el mercado que funcionan perfectamente con el Galaxy Tab.

Comentario 2: si configuro cam.setParameters (p); y solicite directamente a la cámara el estado actual con getFlashMode () devuelve FLASH_MODE_TORCH correctamente. Sin embargo, si suelto la cámara y la vuelvo a abrir, devuelve FLASH_MODE_OFF. Es casi como si el objeto de la cámara conociera la solicitud pero realmente no la transmitiera al hardware.

Después de comentar Konstantins, eliminé cam.release (); parte. Tiene razón, la configuración no persiste si sueltas la cámara. Si usa cam.open () nuevamente, obtendrá una instancia nueva con la luz apagada. Sin embargo, la luz aún no funciona en la pestaña galaxia. Entonces, supongo que es difícil mantener la luz encendida si estás tratando de controlarlo a través de un widget. Tan pronto como finalice el servicio en segundo plano, el objeto de la cámara se liberará automáticamente y, por lo tanto, la luz se apagará nuevamente. Mis preguntas aún permanecen, especialmente por qué la cámara no se enciende en primer lugar.

    Cada dispositivo es un poco diferente. A Samsung especialmente le gusta complicar las cosas a los desarrolladores de aplicaciones.

    En el Galaxy Tab deberías ser bueno con:

     Camera cam; void ledon() { cam = Camera.open(); Parameters params = cam.getParameters(); params.setFlashMode(Parameters.FLASH_MODE_ON); cam.setParameters(params); cam.startPreview(); cam.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { } }); } void ledoff() { cam.stopPreview(); cam.release(); } 

    Si eso no funciona, podría ser una cuestión de establecer FLASH_MODE_OFF inicialmente y cambiarlo después de la vista previa de inicio.

    No debe liberar la cámara después de configurar los parámetros. Descubrí que el flash está activado (en modo antorcha) después de haber comenzado la vista previa. (Se aplica a Motorola desafía, 2.1)

    También es una buena idea verificar los modos de flash compatibles, antes de intentar activarlos.

    Moverse con la configuración de la cámara en Android es el vudú más oscuro: muchos dispositivos se comportan de manera diferente y parece que no hay una manera confiable de dirigirlos a todos con una sola pieza de código. La apuesta más segura es configurar siempre la cámara correctamente cuando se llame al método onResume () . También consideraría hacer lo mismo en onConfigChange () , porque al menos el bloqueador de pantalla de Motorola puede forzar su aplicación al modo vertical y reiniciarla por completo.

    Ps Supongo que cuando cierras la cámara, la aplicación de cámara nativa se cierra y luego se recrea en un estado fresco.

    Lo he hecho de la siguiente manera, que funciona en muchos teléfonos:

      String manuName = android.os.Build.MANUFACTURER.toLowerCase(); Camera mCamera; 

    El siguiente código muestra cómo apagar y encender las luces:

      private void processOnClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera == null) { try { mCamera = Camera.open(); } catch (Exception e) { e.printStackTrace(); } } if (mCamera != null) { final Parameters params = mCamera.getParameters(); List flashModes = params.getSupportedFlashModes(); if (flashModes == null) { return; } else { if (count == 0) { params.setFlashMode(Parameters.FLASH_MODE_OFF); mCamera.setParameters(params); mCamera.startPreview(); } String flashMode = params.getFlashMode(); if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) { if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) { params.setFlashMode(Parameters.FLASH_MODE_TORCH); mCamera.setParameters(params); } else { // Toast.makeText(this, // "Flash mode (torch) not supported",Toast.LENGTH_LONG).show(); params.setFlashMode(Parameters.FLASH_MODE_ON); mCamera.setParameters(params); try { mCamera.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { count = 1; } }); } catch (Exception e) { e.printStackTrace(); } } } } } } if (mCamera == null) { return; } } private void processOffClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera != null) { count = 0; mCamera.stopPreview(); } } } 

    Debajo está la clase DroidLED:

      class DroidLED { private Object svc = null; private Method getFlashlightEnabled = null; private Method setFlashlightEnabled = null; @SuppressWarnings("unchecked") public DroidLED() throws Exception { try { // call ServiceManager.getService("hardware") to get an IBinder for the service. // this appears to be totally undocumented and not exposed in the SDK whatsoever. Class sm = Class.forName("android.os.ServiceManager"); Object hwBinder = sm.getMethod("getService", String.class).invoke(null, "hardware"); // get the hardware service stub. this seems to just get us one step closer to the proxy Class hwsstub = Class.forName("android.os.IHardwareService$Stub"); Method asInterface = hwsstub.getMethod("asInterface", android.os.IBinder.class); svc = asInterface.invoke(null, (IBinder) hwBinder); // grab the class (android.os.IHardwareService$Stub$Proxy) so we can reflect on its methods Class proxy = svc.getClass(); // save methods getFlashlightEnabled = proxy.getMethod("getFlashlightEnabled"); setFlashlightEnabled = proxy.getMethod("setFlashlightEnabled", boolean.class); } catch(Exception e) { throw new Exception("LED could not be initialized"); } } public boolean isEnabled() { try { return getFlashlightEnabled.invoke(svc).equals(true); } catch(Exception e) { return false; } } public void enable(boolean tf) { try { setFlashlightEnabled.invoke(svc, tf); } catch(Exception e) {} } 

    }

    Los siguientes permisos se deben establecer en su AndroidManifest.xml:

           

    Esto funciona para mí en un HTC Desire … (con 2.2) (por supuesto, con los permisos de cámara y linterna):

      Camera mycam = Camera.open(); Parameters p = mycam.getParameters();// = mycam.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); mycam.setParameters(p); //time passes try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } p.setFlashMode(Parameters.FLASH_MODE_OFF); mycam.release(); 

    También podría intentar agregar una vista de superficie. Por favor, eche un vistazo a mi respuesta a la linterna LED en Galaxy Nexus controlable por qué API?

    Por favor use este enlace:

    http://www.androidhive.info/2013/04/android-developing-flashlight-application/

    Fue muy útil para mí.

     private Camera camera; void openCam(){ camera = Camera.open(); if (camera != null) { Camera.Parameters params = camera.getParameters(); camera.setParameters(params); } Camera.Parameters p = camera.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); camera.setParameters(p); } 

    establecer permiso en Manifiesto :