Как программно включить фронтальную вспышку в Android?


233

Я хочу включить переднюю вспышку (не с предварительным просмотром камеры) программно в Android. Я погуглил это, но помощь, которую я нашел, отослала меня к этой странице

У кого-нибудь есть ссылки или пример кода?

Ответы:


401

Для этой проблемы вы должны:

  1. Проверить наличие фонарика или нет?

  2. Если так, то выключите / включите

  3. Если нет, то вы можете делать что угодно, в соответствии с потребностями вашего приложения.

Для проверки наличия вспышки в устройстве:

Вы можете использовать следующее:

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

который вернет истину, если вспышка доступна, ложь, если нет.

Смотрите:
http://developer.android.com/reference/android/content/pm/PackageManager.html для получения дополнительной информации.

Для включения / выключения фонарика:

Я погуглил и получил это об android.permission.FLASHLIGHT. Разрешение манифестов Android выглядит многообещающе:

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

Затем используйте Camera и установите Camera.Parameters . Основным параметром, используемым здесь, является FLASH_MODE_TORCH .

например.

Фрагмент кода для включения фонарика камеры.

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

Фрагмент кода для выключения света камеры.

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

Я только что нашел проект, который использует это разрешение. Проверьте код src быстрых настроек. здесь http://code.google.com/p/quick-settings/ (Примечание: эта ссылка теперь не работает)

Для фонарика смотрите http://code.google.com/p/quick-settings/source/browse/trunk/quick-settings/#quick-settings/src/com/bwx/bequick/flashlight (Примечание. сейчас сломан)

Update6 Вы также можете попробовать добавить SurfaceView, как описано в этом ответе, светодиодный фонарик на Galaxy Nexus, управляемый каким API? Похоже, это решение, которое работает на многих телефонах.

Обновление 5 Основное обновление

Я нашел альтернативную ссылку (для неработающих ссылок выше): http://www.java2s.com/Open-Source/Android/Tools/quick-settings/com.bwx.bequick.flashlight.htm Теперь вы можете использовать это ссылка на сайт. [Обновление: 14/9/2012 Ссылка не работает]

Обновление 1

Другой код OpenSource: http://code.google.com/p/torch/source/browse/

Обновление 2

Пример, показывающий, как включить светодиод на Motorola Droid: http://code.google.com/p/droidled/

Еще один открытый исходный код:

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

Обновление 3 (виджет для включения / выключения светодиода камеры)

Если вы хотите разработать виджет, который включает / выключает светодиод вашей камеры, то вы должны обратиться к моему виджету ответа для включения / выключения фонарика камеры в Android .

Обновление 4

Если вы хотите установить интенсивность света, исходящего от светодиода камеры, можете обратиться. Можно ли изменить яркость светодиода на устройстве Android? полный пост. Обратите внимание, что только корневые устройства HTC поддерживают эту функцию.

** Вопросы:**

Есть также некоторые проблемы при включении / выключении фонарика. например. для устройств, которые не имеют FLASH_MODE_TORCHили даже имеют, то фонарик не включается и т. д.

Обычно Samsung создает много проблем.

Вы можете обратиться к проблемам в приведенном ниже списке:

Используйте фонарик камеры в Android

Включите / выключите светодиод камеры / вспышку в Samsung Galaxy Ace 2.2.1 & Galaxy Tab


2
Спасибо за вашу помощь, это работает для меня! - Я просто скопировал интерфейс Flashlight и класс HtcLedFlashlight, затем я просто вызываю метод setOn с истинным / ложным HtcLedFlashlight и этим. --- Interface-Flashlight code.google.com/p/quick-settings/source/browse/trunk/… - Class-HtcLedFlashlight code.google.com/p/quick-settings/source/browse/trunk/…
Сайкет

1
@saiket: добро пожаловать ... если ваша проблема решена, пометьте этот ответ как решенный. так что это может быть полезно другим ..
Картик Домадия

1
@PolamReddyRajaReddy: Я думаю, что вы тестируете на устройстве Samsung. Я прав ?
Картик Домадия

7
для разрешений правильный код в файле манифеста: `<использование-разрешения android: name =" android.permission.CAMERA "/> <использование-разрешения android: name =" android.permission.FLASHLIGHT "/>`
ixeft

1
Также используйте: - camera.release ();
Четан

35

По моему опыту, если ваше приложение предназначено для работы как в книжной, так и в альбомной ориентации, вам нужно объявить переменную camкак статическую. В противном случае, onDestroy()который вызывается при переключении ориентации, разрушает его, но не освобождает камеру, поэтому невозможно снова открыть его.

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

чтобы проявить, я должен был поставить эту строку

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

от http://developer.android.com/reference/android/hardware/Camera.html

предложенные строки выше не работают для меня.


Вам не нужно проверять функцию системы, если камера выключена. Если cam! = Null, он был включен
Грег Эннис

1
Самая полезная часть для меня былаyou need to declare the variable cam as static
Алекс Джолиг

При импорте Cameraкласса в класс AndroidStudio обратите внимание на android.hardwareкласс ...
AN

32

В API 23 или выше (Android M, 6.0)

Код включения

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

Код выключения

camManager.setTorchMode(cameraId, false);

И разрешения

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

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ

Люди все еще голосуют против моего ответа, поэтому я решил опубликовать дополнительный код. Это было мое решение проблемы в тот день:

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

2
Что вы подразумеваете под «Обычно фронтальная камера находится в 0 положении»? Как я могу проверить, что впереди, а что нет? Кстати, передняя камера - это та, которая направлена ​​на текущего пользователя. Камера, обращенная назад, вероятно, всегда имеет вспышку. И как я могу проверить, включена ли вспышка или нет?
разработчик Android

13

Я получил AutoFlash свет с ниже простых трех шагов.

  • Я только что добавил разрешение камеры и вспышки в файл 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" />
  • В вашем коде камеры сделать так.

    //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 -> Now Перейдите в область Dim light и Snap photo, вы должны получить автоматическую вспышку, если устройство поддерживает.


9

Android Lollipop представил API Camera2 и устарел предыдущий API камеры. Однако использование устаревшего API для включения флэш-памяти по-прежнему работает и намного проще, чем использование нового API.

Кажется, что новый API предназначен для использования в специализированных полнофункциональных приложениях для камер, и что его архитекторы на самом деле не рассматривали более простые варианты использования, такие как включение фонарика. Чтобы сделать это сейчас, нужно получить CameraManager, создать CaptureSession с фиктивной поверхностью и, наконец, создать и запустить CaptureRequest. Обработка исключений, очистка ресурсов и длинные обратные вызовы включены!

Чтобы узнать, как включить фонарик на Lollipop и новее, взгляните на FlashlightController в проекте AOSP (попробуйте найти новейшие API-интерфейсы, которые были изменены). Не забудьте установить необходимые разрешения.


Android Marshmallow наконец-то представил простой способ включения вспышки с помощью setTorchMode .


1
Старый API android.hardware.Camera продолжает работать точно так же, как и раньше, поэтому нет фундаментальной причины, по которой вам нужно использовать android.hardware.camera2 для фонарика. Вполне возможно, что вы сможете снизить энергопотребление и нагрузку на процессор с помощью camera2, поскольку вам не нужно вести активный предварительный просмотр, чтобы включить фонарик.
Эдди Талвала

Я попробовал одну из более простых реализаций на двух устройствах Lollipop, и она не включала флэш-память, хотя она работала на всех нескольких устройствах до Lollipop, на которых я ее пробовал. Возможно, это просто ошибка в Lollipop. Если старые методы все еще работают для вас, и если вы не
являетесь пуристом

В настоящее время у меня есть Nexus 5 с Lollipop, и он отлично работает. У меня также есть приложение, созданное мной, работает и реализуется с помощью этих методов. На случай, если кто-то захочет попробовать. Я поставил ссылку на игровой магазин: play.google.com/store/apps/details?id=com.fadad.linterna. В основном важно убедиться, что камера активна или отключена перед запуском вспышки и разрешений.
ferdiado

Извините моя ошибка. Возможно, другое приложение использовало камеру, когда я пытался включить вспышку со старым API. Я обновил ответ.
LukaCiko

7

Полный код для Android фонарик приложение

манифест

  <?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;
          }
      }

  }

если вспышка уже включена до запуска вашего примера, то попытка выключить вспышку не будет работать ... у вас есть решение этой проблемы?
Тайфун,

7

Существуют разные способы доступа к Camera Flash в разных версиях Android. Немного API перестали работать в Lollipop, а затем он снова изменился в Marshmallow. Чтобы преодолеть это, я создал простую библиотеку, которую использовал в нескольких своих проектах, и она дает хорошие результаты. Это все еще не полностью, но вы можете попробовать проверить код и найти недостающие фрагменты. Вот ссылка - NoobCameraFlash .

Если вы просто хотите интегрировать в свой код, вы можете использовать Gradle для этого. Вот инструкции (взятые непосредственно из Readme) -

Шаг 1. Добавьте репозиторий JitPack в ваш файл сборки. Добавьте его в свой корневой build.gradle в конце репозитория:

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

Шаг 2. Добавьте зависимость

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

использование

Инициализировать NoobCameraManagerсинглтон.

NoobCameraManager.getInstance().init(this);

При желании вы можете установить уровень ведения журнала для отладки. В журнале используется библиотека LumberJack . LogLevel по умолчаниюLogLevel.None

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

После этого вам просто нужно вызвать синглтон, чтобы включить или выключить вспышку камеры.

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

Прежде чем инициализировать NoobCameraManager, вы должны позаботиться о разрешениях времени доступа к камере самостоятельно. В версии 0.1.2 или более ранних версиях мы использовали для поддержки разрешений непосредственно из библиотеки, но из-за зависимости от объекта Activity мы должны удалить его.

Flash тоже легко переключать

if(NoobCameraManager.getInstance().isFlashOn()){
    NoobCameraManager.getInstance().turnOffFlash();
}else{
    NoobCameraManager.getInstance().turnOnFlash();
}

Пожалуйста, добавьте поддержку использования контекста вместо активности. Спасибо!
Ваджира Ласантха

@VajiraLasantha Объект Activity необходим для получения разрешения. Я планировал полностью удалить требование, каким-то образом разделив разрешения. Это было отслежено здесь - github.com/Abhi347/NoobCameraFlash/issues/3 Тем временем вы можете изменить код, чтобы удалить требование, если хотите. Мне может понадобиться время, чтобы поработать над этим.
нуб

Да, я видел это. Я уже изменил вашу библиотеку для работы с Context, удалив разрешения. Потому что мое приложение уже делает проверки разрешений. Пожалуйста, дайте мне знать, когда вы выпустили правильную реализацию, которая поддерживает Context. Спасибо!
Ваджира Ласанта

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.
Пратик Бутани

Что делать, если на устройстве есть несколько вспышек? У некоторых есть фронтальная камера ...
Android-разработчик

0

Я реализовал эту функцию в своем приложении через фрагменты, используя SurfaceView. Ссылка на этот вопрос stackoverflow и его ответ можно найти здесь

Надеюсь это поможет :)


0

В «Зефире» и выше, ответ «setTorchMode ()» CameraManager, кажется, является ответом. Это работает для меня:

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

0

Попробуй это.

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

-3

Вы также можете использовать следующий код для выключения вспышки.

Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.