Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Большинство камер на телефоне имеют светодиодную вспышку, которую можно использовать как фонарик. Пример нужно использовать на реальном устройстве, а не на эмуляторе. Кроме того, есть информация, что некоторые производители выпускают собственные драйвера для вспышки, которые заменяют стандартные системные функции работы с камерой.
В API 21 класс Camera объявлен устаревшим и теперь рекомендуют пользоваться пакетом android.hardware.camera2. Данный пример написан для старой версии на тот случай, если вам хочется поддерживать устаревшие устройства.
Управлять вспышкой можно через метод setFlashMode(Parameters.FLASH_MODE_TORCH). Для начала мы должны убедиться, что устройство поддерживает вспышку.
Добавим в разметку кнопку ToggleButton:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="20dp"
android:text="Фонарик"
android:textSize="25sp" />
<ToggleButton
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="20dp"
android:textOff="Вкл."
android:textOn="Выкл." />
</LinearLayout>
Добавим разрешения и требуемые возможности для устройства в манифест:
<uses-feature
android:name="android.hardware.Camera"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.FLASHLIGHT"
android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
Напишем код для включения и выключения фонарика:
package ru.alexanderklimov.torch;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
public class MainActivity extends Activity {
private final int FLASH_NOT_SUPPORTED = 0;
private final int FLASH_TORCH_NOT_SUPPORTED = 1;
private Camera mCamera = null;
private Camera.Parameters mParameters;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ToggleButton toggleButton = findViewById(R.id.toggleButton);
// если камера имеет вспышку
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
toggleButton
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// включаем вспышку
if (isChecked) {
if (mCamera == null) {
mCamera = Camera.open();
mParameters = mCamera.getParameters();
List flashModesList = mParameters
.getSupportedFlashModes();
if (flashModesList
.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
mParameters
.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParameters);
mCamera.startPreview();
} else {
showDialog(MainActivity.this,
FLASH_TORCH_NOT_SUPPORTED);
}
}
} else { // выключаем вспышку
mParameters
.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParameters);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
});
} else {
showDialog(MainActivity.this, FLASH_NOT_SUPPORTED);
}
}
@Override
protected void onStop() {
super.onStop();
if (mCamera != null) {
mCamera.release();
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.release();
}
}
public void showDialog(Context context, int dialogId) {
AlertDialog alertDialog;
AlertDialog.Builder builder;
switch (dialogId) {
case FLASH_NOT_SUPPORTED:
builder = new AlertDialog.Builder(context);
builder.setMessage("Ваше устройство не поддерживает вспышку")
.setCancelable(false)
.setNeutralButton("Close", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog = builder.create();
alertDialog.show();
break;
case FLASH_TORCH_NOT_SUPPORTED:
builder = new AlertDialog.Builder(context);
builder.setMessage("Ваше устройство не поддерживает вспышку")
.setCancelable(false)
.setNeutralButton("Close", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog = builder.create();
alertDialog.show();
}
}
}
Стоит помнить, что производители порой заменяют системные файлы для работы с камерой и вспышкой на свои и в этом случае стандартный код может не работать на определённых устройствах. Часть методов может быть лишней, например, startPreview()/stopPreview(), но иногда без них код не работает на части телефонов. Также на форумах встречал упоминания о проблемах с вызовом метода getSupportedFlashModes(), когда константа Parameters.FLASH_MODE_TORCH не срабатывала, так как производители использовали свои значения типа on вместо torch для данной константы и т.д. Как вариант, попробуйте убрать проверку либо ищите описание константы для конкретного устройства.