Как программно включить фронтальную вспышку в Android?
Я хочу включить переднюю вспышку (не с предварительным просмотром камеры) программно в Android. Я погуглил это, но помощь, которую я нашел, отослала меня к этой странице
У кого-нибудь есть ссылки или пример кода?
13 ответов
Для этой проблемы вы должны:
Проверить наличие фонарика или нет?
Если так, то выключите / включите
Если нет, то вы можете делать что угодно, в соответствии с потребностями вашего приложения.
Для проверки наличия вспышки в устройстве:
Вы можете использовать следующее:
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/ (Примечание. сейчас сломан)
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
В 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; // Usually back camera is at 0 position.
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; // Usually front camera is at 0 position.
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();
}
}
}
По моему опыту, если ваше приложение предназначено для работы как в портретной, так и в альбомной ориентации, вам нужно объявить переменную 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
предложенные строки выше не работают для меня.
Я получил 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();
Построить + Выполнить -> Теперь перейдите в область "Тусклый свет" и "Привязать фотографию", вы должны получить автоматическую вспышку, если устройство поддерживает.
Существуют разные способы доступа к 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. Log Level по умолчанию 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();
}
Android Lollipop представил API Camera2 и устарел предыдущий API камеры. Однако использование устаревшего API для включения флэш-памяти все еще работает и намного проще, чем использование нового API.
Кажется, что новый API предназначен для использования в специализированных полнофункциональных приложениях для камер, и что его архитекторы на самом деле не рассматривали более простые варианты использования, такие как включение фонарика. Чтобы сделать это сейчас, нужно получить CameraManager, создать CaptureSession с фиктивной поверхностью и, наконец, создать и запустить CaptureRequest. Обработка исключений, очистка ресурсов и длинные обратные вызовы включены!
Чтобы узнать, как включить фонарик на Lollipop и новее, взгляните на FlashlightController в проекте AOSP (попробуйте найти новейшие API-интерфейсы более старых версий, которые были изменены). Не забудьте установить необходимые разрешения.
Android Marshmallow наконец-то представил простой способ включения вспышки с помощью setTorchMode.
Полный код для 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;
}
}
}
Версия Котлина 2022 года:
fun Context.isFlashLightAvailable() = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)
val Context.camaraManager: CameraManager get() = getSystemService(CameraManager::class.java)
fun Context.toggleFlashLight(on: Boolean) {
camaraManager.run {
val firstCameraWithFlash = cameraIdList.find { camera ->
getCameraCharacteristics(camera).keys.any { it == FLASH_INFO_AVAILABLE }
}
firstCameraWithFlash?.let {
runCatching { setTorchMode(it, on) }.onFailure { Timber.e(it, "Error setTorchMode") }
} ?: Timber.e(Throwable("toggleFlashLight"), "Camera with flash not found")
}
}
или с функцией приостановки, которая возвращает результат
suspend fun Context.toggleFlashLightWithResult(on: Boolean): Boolean {
return suspendCancellableCoroutine { cont ->
runCatching {
camaraManager.run {
val firstCameraWithFlash = cameraIdList.find { camera ->
getCameraCharacteristics(camera).keys.any { it == FLASH_INFO_AVAILABLE }
}
val callback = object : CameraManager.TorchCallback() {
override fun onTorchModeChanged(cameraId: String, enabled: Boolean) {
super.onTorchModeChanged(cameraId, enabled)
if (cont.isActive) cont.resume(enabled)
}
}
if (firstCameraWithFlash == null) {
Timber.e(Throwable("toggleFlashLight"), "Camera with flash not found")
cont.resume(false)
} else {
Timber.tag("~!").d("firstCameraWithFlash: $firstCameraWithFlash")
setTorchMode(firstCameraWithFlash, on)
registerTorchCallback(mainExecutor, callback)
}
cont.invokeOnCancellation { unregisterTorchCallback(callback) }
}
}
.onFailure { Timber.e(it, "Error toggleFlashLight") }
}
}
В "Зефире" и выше, ответ "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);
Попробуй это.
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();
}
Я реализовал эту функцию в своем приложении через фрагменты, используя SurfaceView. Ссылка на этот вопрос stackru и его ответ можно найти здесь
Надеюсь это поможет:)
Когда я обновил свою версию SDK, вспышка камеры перестала работать с исключением нулевого указателя. Я обнаружил, что мне нужно было установить targetSDKVersion на 22 в build.gradle. Когда я попробовал 23, приложение рухнуло.
targetSdkVersion 22
Вы также можете использовать следующий код для выключения вспышки.
Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);