Освой 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 для данной константы и т.д. Как вариант, попробуйте убрать проверку либо ищите описание константы для конкретного устройства.

Кот-фонарик

Дополнительное чтение

Фонарик (Camera2)

Реклама