¿Cómo encender la luz del flash frontal mediante programación en Android?

233

Quiero encender la luz del flash frontal (no con la vista previa de la cámara) mediante programación en Android. Busqué en Google pero la ayuda que encontré me remitió a esta página

¿Alguien tiene algún enlace o código de muestra?

saiket
fuente

Respuestas:

401

Para este problema debes:

  1. ¿Verifica si la linterna está disponible o no?

  2. Si es así, apague / encienda

  3. Si no es así, puede hacer lo que sea, según las necesidades de su aplicación.

Para verificar la disponibilidad de flash en el dispositivo:

Puedes usar lo siguiente:

 context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

que devolverá verdadero si hay un flash disponible, falso si no.

Consulte:
http://developer.android.com/reference/android/content/pm/PackageManager.html para obtener más información.

Para encender / apagar la linterna:

Busqué en Google y obtuve esto sobre android.permission.FLASHLIGHT. El permiso de los manifiestos de Android parece prometedor:

 <!-- Allows access to the flashlight -->
 <permission android:name="android.permission.FLASHLIGHT"
             android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
             android:protectionLevel="normal"
             android:label="@string/permlab_flashlight"
             android:description="@string/permdesc_flashlight" />

Luego use la Cámara y configure Camera.Parameters . El parámetro principal utilizado aquí es FLASH_MODE_TORCH .

p.ej.

Fragmento de código para encender la linterna de la cámara.

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

Fragmento de código para apagar la luz LED de la cámara.

  cam.stopPreview();
  cam.release();

Acabo de encontrar un proyecto que utiliza este permiso. Verifique el código src de la configuración rápida. aquí http://code.google.com/p/quick-settings/ (Nota: este enlace ahora está roto)

Para Flashlight, busque directamente http://code.google.com/p/quick-settings/source/browse/trunk/quick-settings/#quick-settings/src/com/bwx/bequick/flashlight (Nota: este enlace es ahora roto)

Actualización6 También podría intentar agregar un SurfaceView como se describe en esta respuesta Linterna LED en Galaxy Nexus controlable por qué API? Esta parece ser una solución que funciona en muchos teléfonos.

Actualización 5 Actualización importante

He encontrado un enlace alternativo (para los enlaces rotos anteriores): http://www.java2s.com/Open-Source/Android/Tools/quick-settings/com.bwx.bequick.flashlight.htm Ahora puede usar esto enlace. [Actualización: 14/9/2012 Este enlace ahora está roto]

Actualización 1

Otro código de código abierto: http://code.google.com/p/torch/source/browse/

Actualización 2

Ejemplo que muestra cómo habilitar el LED en un Motorola Droid: http://code.google.com/p/droidled/

Otro código fuente abierto:

http://code.google.com/p/covedesigndev/
http://code.google.com/p/search-light/

Actualización 3 (widget para encender / apagar la cámara led)

Si desea desarrollar un widget que encienda / apague el led de su cámara, debe consultar mi widget de respuesta para encender / apagar la linterna de la cámara en Android .

Actualización 4

Si desea establecer la intensidad de la luz que emerge del LED de la cámara, puede consultar ¿Puedo cambiar la intensidad del LED de un dispositivo Android?Publicación completa. Tenga en cuenta que solo los dispositivos HTC rooteados son compatibles con esta función.

** Cuestiones:**

También hay algunos problemas al encender / apagar la linterna. p.ej. para los dispositivos que no tienen FLASH_MODE_TORCHo incluso si tienen, entonces la linterna no enciende, etc.

Por lo general, Samsung crea muchos problemas.

Puede consultar los problemas en la siguiente lista:

Use la linterna de la cámara en Android

Encienda / apague la cámara LED / luz de flash en Samsung Galaxy Ace 2.2.1 y Galaxy Tab

Kartik Domadiya
fuente
2
Gracias por tu ayuda, ¡funciona para mí! - Acabo de copiar la interfaz Flashlight y la clase HtcLedFlashlight, luego llamo al método setOn con verdadero / falso HtcLedFlashlight y eso. --- Interface-Flashlight code.google.com/p/quick-settings/source/browse/trunk/… - Class-HtcLedFlashlight code.google.com/p/quick-settings/source/browse/trunk/…
saiket
1
@saiket: bienvenido ... si su problema está resuelto, marque esta respuesta como resuelta. para que pueda ser útil para los demás ..
Kartik Domadiya
1
@PolamReddyRajaReddy: Creo que estás probando en un dispositivo Samsung. Estoy en lo correcto ?
Kartik Domadiya
77
para permisos, el código correcto en el archivo de manifiesto es: `<uses-permission android: name =" android.permission.CAMERA "/> <uses-permission android: name =" android.permission.FLASHLIGHT "/>`
ixeft
1
Utilice también: - camera.release ();
Chetan
35

Según mi experiencia, si su aplicación está diseñada para funcionar tanto en orientación vertical como horizontal, debe declarar la variable camcomo estática. De lo contrario, lo onDestroy()que se llama al cambiar de orientación, lo destruye pero no libera la cámara, por lo que no es posible volver a abrirla.

package com.example.flashlight;

import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

public static Camera cam = null;// has to be static, otherwise onDestroy() destroys it

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

public void flashLightOn(View view) {

    try {
        if (getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)) {
            cam = Camera.open();
            Parameters p = cam.getParameters();
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            cam.setParameters(p);
            cam.startPreview();
        }
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(getBaseContext(), "Exception flashLightOn()",
                Toast.LENGTH_SHORT).show();
    }
}

public void flashLightOff(View view) {
    try {
        if (getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)) {
            cam.stopPreview();
            cam.release();
            cam = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(getBaseContext(), "Exception flashLightOff",
                Toast.LENGTH_SHORT).show();
    }
}
}

para manifestar tuve que poner esta línea

    <uses-permission android:name="android.permission.CAMERA" />

de http://developer.android.com/reference/android/hardware/Camera.html

Las líneas sugeridas arriba no funcionaban para mí.

Ján Lazár
fuente
No necesita verificar la función del sistema si la cámara está apagada. If cam! = Null, se activó
Greg Ennis
1
La parte más útil para mí fueyou need to declare the variable cam as static
Alex Jolig
Al importar CameraClase en AndroidStudio prestar atención para ser android.hardwareclase ...
AN
32

En API 23 o superior (Android M, 6.0)

Activar código

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = null; 
    try {
        cameraId = camManager.getCameraIdList()[0];
        camManager.setTorchMode(cameraId, true);   //Turn ON
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

APAGUE el código

camManager.setTorchMode(cameraId, false);

Y permisos

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>

EDICION ADICIONAL

La gente todavía votaba mi respuesta, así que decidí publicar código adicional. Esta fue mi solución para el problema en el pasado:

public class FlashlightProvider {

private static final String TAG = FlashlightProvider.class.getSimpleName();
private Camera mCamera;
private Camera.Parameters parameters;
private CameraManager camManager;
private Context context;

public FlashlightProvider(Context context) {
    this.context = context;
}

private void turnFlashlightOn() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        try {
            camManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            String cameraId = null; 
            if (camManager != null) {
                cameraId = camManager.getCameraIdList()[0];
                camManager.setTorchMode(cameraId, true);
            }
        } catch (CameraAccessException e) {
            Log.e(TAG, e.toString());
        }
    } else {
        mCamera = Camera.open();
        parameters = mCamera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
}

private void turnFlashlightOff() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        try {
            String cameraId;
            camManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            if (camManager != null) {
                cameraId = camManager.getCameraIdList()[0]; // Usually front camera is at 0 position.
                camManager.setTorchMode(cameraId, false);
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    } else {
        mCamera = Camera.open();
        parameters = mCamera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        mCamera.setParameters(parameters);
        mCamera.stopPreview();
    }
}
}
Jack el destripador
fuente
2
¿Qué quiere decir con "Por lo general, la cámara frontal está en la posición 0"? ¿Cómo puedo verificar cuál está al frente y cuál no? Por cierto, la cámara frontal es la que está dirigida al usuario actual. La cámara trasera es la que probablemente siempre tenga flash. ¿Y cómo puedo verificar si el flash está encendido o apagado?
Desarrollador de Android
13

Obtuve la luz AutoFlash con los siguientes tres pasos simples.

  • Acabo de agregar permiso de cámara y flash en el archivo Manifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
  • En su Código de cámara, haga lo siguiente.

    //Open Camera
    Camera  mCamera = Camera.open(); 
    
    //Get Camera Params for customisation
    Camera.Parameters parameters = mCamera.getParameters();
    
    //Check Whether device supports AutoFlash, If you YES then set AutoFlash
    List<String> flashModes = parameters.getSupportedFlashModes();
    if (flashModes.contains(android.hardware.Camera.Parameters.FLASH_MODE_AUTO))
    {
         parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
    }
    mCamera.setParameters(parameters);
    mCamera.startPreview();
  • Construir + Ejecutar -> Ahora Vaya al área de luz tenue y Capture foto, debería obtener luz de flash automático si el dispositivo lo admite.

swiftBoy
fuente
9

Android Lollipop introdujo la API de camera2 y desaprobó la API de cámara anterior. Sin embargo, usar la API en desuso para encender el flash aún funciona y es mucho más simple que usar la nueva API.

Parece que la nueva API está diseñada para su uso en aplicaciones dedicadas de cámara con todas las funciones y que sus arquitectos realmente no consideraron casos de uso más simples, como encender la linterna. Para hacer eso ahora, uno debe obtener un CameraManager, crear una CaptureSession con una Surface ficticia y finalmente crear e iniciar una CaptureRequest. ¡Manejo de excepciones, limpieza de recursos y devoluciones de llamadas largas incluidas!

Para ver cómo encender la linterna en Lollipop y más reciente, eche un vistazo a FlashlightController en el proyecto AOSP (intente encontrar las API más nuevas y antiguas que se han modificado). No olvide establecer los permisos necesarios.


Android Marshmallow finalmente introdujo una forma simple de encender el flash con setTorchMode .

LukaCiko
fuente
1
La antigua API android.hardware.Camera continúa funcionando exactamente como antes, por lo que no hay una razón fundamental por la que necesite usar android.hardware.camera2 para la linterna. Sin embargo, es posible que pueda reducir el consumo de energía y la carga de la CPU con la cámara2, ya que no necesita mantener una vista previa activa para habilitar la linterna.
Eddy Talvala
Probé una de las implementaciones más simples en dos dispositivos Lollipop y no encendió el flash, a pesar de que funcionó en todos los dispositivos anteriores a Lollipop en los que lo probé. Quizás eso sea solo un error en Lollipop. Si los métodos anteriores aún funcionan para usted y si no es un purista de Java, continúe utilizando la API anterior, ya que es mucho más simple :)
LukaCiko
Actualmente tengo un Nexus 5 con Lollipop y funciona perfectamente. También poseo una aplicación creada por mí mismo que funciona y se implementa con estos métodos. En caso de que alguien quiera probarlo. Puse un enlace a Play Store: play.google.com/store/apps/details?id=com.fadad.linterna. Lo más importante es asegurar que la cámara esté activa o desactivada antes de ejecutar el flash y los permisos.
ferdiado
Perdón mi error. Probablemente otra aplicación estaba usando la cámara cuando intenté encender el flash con la antigua API. He actualizado la respuesta.
LukaCiko
7

Código completo para la aplicación Android Flashlight

Manifiesto

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.user.flashlight"
      android:versionCode="1"
      android:versionName="1.0">

      <uses-sdk
          android:minSdkVersion="8"
          android:targetSdkVersion="17"/>

      <uses-permission android:name="android.permission.CAMERA" />
      <uses-feature android:name="android.hardware.camera"/>

      <application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" >
          <activity
              android:name=".MainActivity"
              android:label="@string/app_name" >
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />

                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      </application>

  </manifest>

XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OFF"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="turnFlashOnOrOff" />
</RelativeLayout>

MainActivity.java

  import android.app.AlertDialog;
  import android.content.DialogInterface;
  import android.content.pm.PackageManager;
  import android.hardware.Camera;
  import android.hardware.Camera.Parameters;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Button;

  import java.security.Policy;

  public class MainActivity extends AppCompatActivity {

      Button button;
      private Camera camera;
      private boolean isFlashOn;
      private boolean hasFlash;
      Parameters params;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          button = (Button) findViewById(R.id.button);

          hasFlash = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

          if(!hasFlash) {

              AlertDialog alert = new AlertDialog.Builder(MainActivity.this).create();
              alert.setTitle("Error");
              alert.setMessage("Sorry, your device doesn't support flash light!");
              alert.setButton("OK", new DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                      finish();
                  }
              });
              alert.show();
              return;
          }

          getCamera();

          button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {

                  if (isFlashOn) {
                      turnOffFlash();
                      button.setText("ON");
                  } else {
                      turnOnFlash();
                      button.setText("OFF");
                  }

              }
          });
      }

      private void getCamera() {

          if (camera == null) {
              try {
                  camera = Camera.open();
                  params = camera.getParameters();
              }catch (Exception e) {

              }
          }

      }

      private void turnOnFlash() {

          if(!isFlashOn) {
              if(camera == null || params == null) {
                  return;
              }

              params = camera.getParameters();
              params.setFlashMode(Parameters.FLASH_MODE_TORCH);
              camera.setParameters(params);
              camera.startPreview();
              isFlashOn = true;
          }

      }

      private void turnOffFlash() {

              if (isFlashOn) {
                  if (camera == null || params == null) {
                      return;
                  }

                  params = camera.getParameters();
                  params.setFlashMode(Parameters.FLASH_MODE_OFF);
                  camera.setParameters(params);
                  camera.stopPreview();
                  isFlashOn = false;
              }
      }

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

      @Override
      protected void onPause() {
          super.onPause();

          // on pause turn off the flash
          turnOffFlash();
      }

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

      @Override
      protected void onResume() {
          super.onResume();

          // on resume turn on the flash
          if(hasFlash)
              turnOnFlash();
      }

      @Override
      protected void onStart() {
          super.onStart();

          // on starting the app get the camera params
          getCamera();
      }

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

          // on stop release the camera
          if (camera != null) {
              camera.release();
              camera = null;
          }
      }

  }
RAP
fuente
si el flash ya está encendido antes de comenzar su ejemplo, entonces intentar apagar el flash no funcionará ... ¿tiene una solución para ese problema?
Taifun
7

Hay diferentes formas de acceder a Camera Flash en diferentes versiones de Android. Pocas API dejaron de funcionar en Lollipop y luego se cambió nuevamente en Marshmallow. Para superar esto, he creado una biblioteca simple que he estado usando en algunos de mis proyectos y está dando buenos resultados. Todavía está incompleto, pero puede intentar verificar el código y encontrar las piezas que faltan. Aquí está el enlace: NoobCameraFlash .

Si solo desea integrarse en su código, puede usar gradle para eso. Aquí están las instrucciones (tomadas directamente del archivo Léame):

Paso 1. Agregue el repositorio JitPack a su archivo de compilación. Agréguelo en su raíz build.gradle al final de los repositorios:

allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
}

Paso 2. Agregar la dependencia

dependencies {
        compile 'com.github.Abhi347:NoobCameraFlash:0.0.1'
  }

Uso

Inicializa el NoobCameraManagersingleton.

NoobCameraManager.getInstance().init(this);

Opcionalmente, puede establecer el Nivel de registro para el registro de depuración. El registro utiliza la biblioteca LumberJack . El nivel de registro predeterminado esLogLevel.None

NoobCameraManager.getInstance().init(this, LogLevel.Verbose);

Después de eso, solo necesita llamar al singleton para encender o apagar el flash de la cámara.

NoobCameraManager.getInstance().turnOnFlash();
NoobCameraManager.getInstance().turnOffFlash();

Debe tener en cuenta los permisos de tiempo de ejecución para acceder a la cámara usted mismo, antes de inicializar NoobCameraManager. En la versión 0.1.2 o anterior solíamos proporcionar soporte para permisos directamente desde la biblioteca, pero debido a la dependencia del objeto Actividad, tenemos que eliminarlo.

También es fácil alternar Flash

if(NoobCameraManager.getInstance().isFlashOn()){
    NoobCameraManager.getInstance().turnOffFlash();
}else{
    NoobCameraManager.getInstance().turnOnFlash();
}
novato
fuente
Agregue soporte para usar Contexto en lugar de Actividad. ¡Gracias!
Vajira Lasantha
@VajiraLasantha El objeto Actividad es necesario para tomar el permiso. Estaba planeando eliminar el requisito por completo separando los permisos de alguna manera. Se ha rastreado aquí: github.com/Abhi347/NoobCameraFlash/issues/3 Mientras tanto, puede modificar el código para eliminar el requisito si lo desea. Puede que necesite algo de tiempo para trabajar en ello.
noob
Sí, lo vi Ya he alterado su lib para trabajar con Context eliminando cosas de permisos. Porque mi aplicación ya hace validaciones de permisos. Avíseme cuando haya lanzado una implementación adecuada que admita Context. ¡Gracias!
Vajira Lasantha
You have to take care of the runtime permissions to access Camera yourself, before initializing the NoobCameraManager. In version 0.1.2 or earlier we used to provide support for permissions directly from the library, but due to dependency on the Activity object, we have to remove it.
Pratik Butani
¿Qué pasa si hay múltiples flashes en el dispositivo? Algunos tienen en la cámara frontal ...
desarrollador de Android
0

He implementado esta función en mi aplicación a través de fragmentos usando SurfaceView. Puede encontrar el enlace a esta pregunta de stackoverflow y su respuesta aquí

Espero que esto ayude :)

Michele La Ferla
fuente
0

En Marshmallow y versiones posteriores, `setTorchMode () 'de CameraManager parece ser la respuesta. Esto funciona para mi:

 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);
aecl755
fuente
0

Prueba esto.

CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = null; // Usually front camera is at 0 position.
    try {
        cameraId = camManager.getCameraIdList()[0];
        camManager.setTorchMode(cameraId, true);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
Jaswant Singh
fuente
-3

También puede usar el siguiente código para apagar el flash.

Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
belphegor
fuente