Como ativar a luz do flash frontal programaticamente no Android?

233

Quero ativar a luz do flash frontal (não com a visualização da câmera) programaticamente no Android. Pesquisei no Google, mas a ajuda que encontrei me encaminhava para esta página

Alguém tem links ou código de amostra?

saiket
fonte

Respostas:

401

Para esse problema, você deve:

  1. Verifique se a lanterna está disponível ou não?

  2. Se sim, então Desligue / Ligue

  3. Caso contrário, você pode fazer o que for, de acordo com as necessidades do seu aplicativo.

Para verificar a disponibilidade do flash no dispositivo:

Você pode usar o seguinte:

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

que retornará true se houver um flash disponível, false se não estiver.

Consulte:
http://developer.android.com/reference/android/content/pm/PackageManager.html para obter mais informações.

Para ligar / desligar a lanterna:

Eu pesquisei e consegui isso sobre android.permission.FLASHLIGHT. A permissão dos manifestos do Android parece promissora:

 <!-- 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" />

Em seguida, faça uso da câmera e defina Camera.Parameters . O principal parâmetro usado aqui é FLASH_MODE_TORCH .

por exemplo.

Snippet de código para ligar a lanterna da câmera.

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

Fragmento de código para desligar a luz led da câmera.

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

Acabei de encontrar um projeto que usa essa permissão. Verifique o código src das configurações rápidas. aqui http://code.google.com/p/quick-settings/ (Nota: este link agora está quebrado)

Para o Flashlight, consulte diretamente http://code.google.com/p/quick-settings/source/browse/trunk/quick-settings/#quick-settings/src/com/bwx/bequick/flashlight (Nota: este link é agora quebrado)

Atualização6 Você também pode tentar adicionar um SurfaceView conforme descrito nesta resposta Lanterna LED no Galaxy Nexus controlável por qual API? Esta parece ser uma solução que funciona em muitos telefones.

Update 5 Major Update

Encontrei um link alternativo (para os links quebrados acima): http://www.java2s.com/Open-Source/Android/Tools/quick-settings/com.bwx.bequick.flashlight.htm Agora você pode usar este ligação. [Atualização: 14/9/2012 Este link está quebrado agora]

Atualização 1

Outro código de código aberto: http://code.google.com/p/torch/source/browse/

Atualização 2

Exemplo que mostra como ativar o LED em um Motorola Droid: http://code.google.com/p/droidled/

Outro código-fonte aberto:

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

Atualização 3 (Widget para ligar / desligar o led da câmera)

Se você deseja desenvolver um widget que liga / desliga o led da câmera, deve consultar a minha resposta Widget para ativar / desativar a lanterna da câmera no android .

Atualização 4

Se você deseja definir a intensidade da luz que sai do LED da câmera, pode consultar Posso alterar a intensidade do LED de um dispositivo Android? post completo. Observe que apenas os dispositivos HTC raiz suportam esse recurso.

** Problemas:**

Também existem alguns problemas ao ligar / desligar a lanterna. por exemplo. para os dispositivos que não possuem FLASH_MODE_TORCHou mesmo se tiverem, a lanterna não liga etc.

Normalmente, a Samsung cria muitos problemas.

Você pode consultar os problemas na lista abaixo:

Use a lanterna da câmera no Android

Ligue / desligue o LED da câmera / luz do flash no Samsung Galaxy Ace 2.2.1 e Galaxy Tab

Kartik Domadiya
fonte
2
Obrigado pela vossa ajuda, funciona para mim! - Acabei de copiar a interface Flashlight e a classe HtcLedFlashlight, então chamo setOn método com true / false HtcLedFlashlight e esse. --- Interface-Flashlight code.google.com/p/quick-settings/source/browse/trunk/… - Class-HtcLedFlashlight code.google.com/p/quick-settings/source/browse/trunk/…
saiket 20/05
1
@ saiket: bem-vindo .. se o seu problema for resolvido, marque esta resposta como resolvida. de modo que possa ser útil aos outros ..
Kartik Domadiya
1
@PolamReddyRajaReddy: Acho que você está testando no dispositivo Samsung. Estou correcto ?
Kartik Domadiya 14/11
7
para permissões, o código correto no arquivo de manifesto é: `<uses-permission android: name =" android.permission.CAMERA "/> <uses-permission android: name =" android.permission.FLASHLIGHT "/>`
ixeft
1
Também use: - camera.release ();
Chetan
35

Pela minha experiência, se seu aplicativo foi projetado para funcionar na orientação retrato e paisagem, você precisa declarar a variável camcomo estática. Caso contrário, onDestroy()que é chamado de alternância de orientação, a destrói, mas não libera a Câmera, portanto não é possível reabri-la novamente.

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 eu tive que colocar essa linha

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

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

as linhas sugeridas acima não estavam funcionando para mim.

Ján Lazár
fonte
Você não precisa verificar o recurso do sistema se a câmera estiver desligada. Se cam! = Nulo, ele foi ativado
Greg Ennis
1
A parte mais útil para mim foiyou need to declare the variable cam as static
Alex Jolig 18/09/2015
Quando importação CameraClasse em AndroidStudio prestar atenção a ser android.hardwareclasse ...
AN
32

Na API 23 ou superior (Android M, 6.0)

Código de ativação

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();
    }
}

Desativar código

camManager.setTorchMode(cameraId, false);

E permissões

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

EDIÇÃO ADICIONAL

As pessoas ainda votaram na minha resposta, então eu decidi postar código adicional Esta foi a minha solução para o problema no passado:

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 o Estripador
fonte
2
O que você quer dizer com "Geralmente a câmera frontal está na posição 0"? Como posso verificar o que está na frente e o que não está? Aliás, a câmera frontal é aquela direcionada ao usuário atual. A câmera traseira é a que provavelmente sempre tem flash. E como posso verificar se o flash está ligado ou desligado?
desenvolvedor Android
13

Eu obtive a luz AutoFlash com três etapas abaixo simples.

  • Acabei de adicionar a permissão Camera e Flash no arquivo 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" />
  • No código da sua câmera, faça isso.

    //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();
  • Build + Run -> Agora vá para Dim light area e Snap photo, você deve obter a luz do flash automático se o dispositivo suportar.

swiftBoy
fonte
9

O Android Lollipop introduziu a API camera2 e substituiu a API da câmera anterior. No entanto, o uso da API reprovada para ativar o flash ainda funciona e é muito mais simples do que usar a nova API.

Parece que a nova API foi projetada para uso em aplicativos dedicados de câmera com todos os recursos e que seus arquitetos não consideraram casos de uso mais simples, como acender a lanterna. Para fazer isso agora, é necessário obter um CameraManager, criar uma CaptureSession com uma superfície fictícia e, finalmente, criar e iniciar um CaptureRequest. Manipulação de exceção, limpeza de recursos e retornos de chamada longos incluídos!

Para ver como ativar a lanterna no Lollipop e mais recentes, dê uma olhada no FlashlightController no projeto AOSP (tente encontrar as APIs de uso mais recentes e antigas que foram modificadas). Não se esqueça de definir as permissões necessárias.


O Android Marshmallow finalmente introduziu uma maneira simples de ligar o flash com o setTorchMode .

LukaCiko
fonte
1
A antiga API android.hardware.Camera continua funcionando exatamente como antes, portanto não há motivo fundamental para usar o android.hardware.camera2 como lanterna. No entanto, é possível reduzir o consumo de energia e a carga da CPU com a camera2, pois você não precisa manter uma visualização ativa para ativar a lanterna.
Eddy Talvala
Eu tentei uma das implementações mais simples em dois dispositivos Lollipop e não ligou o flash, mesmo que funcionasse em todos os vários dispositivos pré-Lollipop em que eu experimentei. Talvez seja apenas um bug no pirulito. Se os métodos antigos ainda funcionam para você e se você não for um purista Java continuar usando o antigo API, pois é muito mais simples :)
LukaCiko
Atualmente, tenho um Nexus 5 com pirulito e funciona perfeitamente. Eu também possuo um aplicativo criado por mim e funciona com esses métodos. Caso alguém queira experimentar. Coloquei um link para a play store: play.google.com/store/apps/details?id=com.fadad.linterna O mais importante é garantir que a câmera esteja ativa ou desativada antes de executar o flash e as permissões.
ferdiado
Desculpe meu erro. Outro aplicativo provavelmente estava usando a câmera quando tentei ligar o flash com a API antiga. Eu atualizei a resposta.
27615 LukaCiko
7

Código completo para Android Flashlight App

Manifesto

  <?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
fonte
se o flash já estiver ligado antes de iniciar o seu exemplo, tentar desligar o flash não funcionará ... você tem uma solução para esse problema?
Taifun
7

Existem diferentes maneiras de acessar o Flash da câmera em diferentes versões do Android. Poucas APIs pararam de funcionar no Lollipop e depois foram alteradas novamente no Marshmallow. Para superar isso, criei uma biblioteca simples que tenho usado em alguns dos meus projetos e está dando bons resultados. Ainda está incompleto, mas você pode tentar verificar o código e encontrar as peças que faltam. Aqui está o link - NoobCameraFlash .

Se você deseja integrar apenas no seu código, use gradle para isso. Aqui estão as instruções (extraídas diretamente do Leia-me) -

Etapa 1. Adicione o repositório do JitPack ao seu arquivo de construção. Adicione-o em seu root build.gradle no final dos repositórios:

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

Etapa 2. Adicione a dependência

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

Uso

Inicialize o NoobCameraManagersingleton.

NoobCameraManager.getInstance().init(this);

Você pode opcionalmente definir o nível de log para o log de depuração. O log usa a biblioteca LumberJack . O LogLevel padrão éLogLevel.None

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

Depois disso, basta ligar para o singleton para ativar ou desativar o flash da câmera.

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

Você precisa cuidar das permissões de tempo de execução para acessar a Câmera antes de inicializar o NoobCameraManager. Na versão 0.1.2 ou anterior, costumávamos fornecer suporte para permissões diretamente da biblioteca, mas devido à dependência do objeto Activity, precisamos removê-lo.

Também é fácil alternar o Flash

if(NoobCameraManager.getInstance().isFlashOn()){
    NoobCameraManager.getInstance().turnOffFlash();
}else{
    NoobCameraManager.getInstance().turnOnFlash();
}
novato
fonte
Por favor, adicione suporte para o uso de contexto em vez de atividade. Obrigado!
Vajira Lasantha
@VajiraLasantha O objeto Activity é necessário para obter a permissão. Eu estava planejando remover completamente o requisito, separando as permissões de alguma forma. Foi rastreado aqui - github.com/Abhi347/NoobCameraFlash/issues/3 Nesse meio tempo, você pode modificar o código para remover o requisito, se desejar. Eu posso precisar de algum tempo para trabalhar nisso.
Noob
Sim, eu vi isso. Eu já alterei sua lib para trabalhar com o Contexto removendo os itens de permissão. Porque meu aplicativo já faz validações de permissão. Informe-me quando você lançou uma implementação adequada que suporta o Contexto. Obrigado!
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
E se houver vários flashes no dispositivo? Alguns têm na frente da câmera ...
desenvolvedor Android
0

Eu implementei essa função no meu aplicativo por meio de fragmentos usando o SurfaceView. O link para esta pergunta do stackoverflow e sua resposta podem ser encontrados aqui

Espero que isto ajude :)

Michele La Ferla
fonte
0

No Marshmallow e acima, o `setTorchMode () 'do CameraManager parece ser a resposta. Isso funciona para mim:

 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
fonte
0

Tente isso.

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
fonte
-3

Você também pode usar o seguinte código para desligar o flash.

Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
Belphegor
fonte