Разработка Android приложений для Lollipop используя Camera2 API Часть 1

4.713 (8)

С выходом новых версий android разработчики добавляют новые возможности для работы с мобильными устройствами. Так, с выходом Lollipop стал доступен новый интерфейс для работы с камерой. Все новые возможности находятся теперь в пакете android.hardware.camera2 и доступны только начиная с ветки api 21
Давайте рассмотрим, что нам подготовили разработчики. Создадим новый проект в Android Studio и обязательно укажем, что наше приложение поддерживается начиная с api 21.
Первым делом укажем нашему приложению, что нам нужно использовать камеру, и нам необходимо разрешения на это. Отрываем AndroidManifest.xmlи дописываем туда:

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

также можем добавить, что если наше устройство не поддерживает камеру и автофокус, то приложение не будет установлено

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Открываем наш MainActivity и удаляем все не нужное. Оставляем только метод onCreate. Для работы с камерами предусмотрен CameraManager, объект которого нам необходимо получить.  Объявим в нашем activity новое поле 

 private CameraManager mCameraManager    = null;

и в методе  onCreate получим экземпляр:

mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

И так первое, что мы попробуем, это получить список наших камер. Для этого в менеджере предусмотрен метод getCameraIdList()

try {
    // Получения списка камер в устрйстве
    String[] cameraList = mCameraManager.getCameraIdList();
    for (String cameraID : cameraList) {
        Log.i(LOG_TAG, "cameraID: "+cameraID);
    } 
} catch (CameraAccessException e) {
    Log.e(LOG_TAG,e.getMessage());
    e.printStackTrace();
}

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

использования android camera2

Как видим, у нас в телефоне доступно 2 камеры. Для получения характеристик необходимо использовать метод getCameraCharacteristics(String cameraId). Этот метод возвращает объект класса CameraCharacteristics, в котором сконцентрированы параметры по камере. В данном классе сконцентрировано огромное количество параметров, которые раньше небыли доступны. Полный список можно посмотреть в документации. Мы постараемся получить список разрешений, которые поддерживает данная камера. Для этого добавим в наш цикл следующий код:

// Получения характеристик камеры
CameraCharacteristics cc = mCameraManager.getCameraCharacteristics(cameraID);
// Получения списка выходного формата, который поддерживает камера
StreamConfigurationMap configurationMap =
        cc.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

// Получения списка разрешений которые поддерживаются для формата jpeg
Size[] sizesJPEG = configurationMap.getOutputSizes(ImageFormat.JPEG);

if (sizesJPEG != null) {
    for (Size item:sizesJPEG) {
        Log.i(LOG_TAG, "w:"+item.getWidth()+" h:"+item.getHeight());
    }
}  else {
    Log.e(LOG_TAG, "camera with id: "+cameraID+" don`t support JPEG");
}

 При запуске увидим список разрешений, которые можем использовать для формата jpeg.

список разрешений android camera2

Следующим шагом будет открытие камеры. Для этого в менеджере предусмотрен метод openCamera. Так как у нас 2 камеры попытаемся работать сразу с двумя.
Давайте попробуем добавить дополнительный класс, который будет обрабатывать запросы по каждой камере.  Так же, для удобства, добавим библиотеку для работы с аннотациями. Открываем  build.gradleи добавляем 

compile 'com.android.support:support-annotations:22.2.0'

Создадим класс CameraHelper, через который мы будем работать с камерой, и перенесем туда то, что мы уже написали.  

public class CameraHelper {

    private CameraManager mCameraManager    = null;
    private String mCameraID    = null;

    public CameraHelper(@NonNull CameraManager cameraManager, @NonNull String cameraID) {
        mCameraManager  = cameraManager;
        mCameraID       = cameraID;
    }

    public void viewFormatSize(int formatSize) {
        // Получения характеристик камеры
        CameraCharacteristics cc = null;
        try {
            cc = mCameraManager.getCameraCharacteristics(mCameraID);

            // Получения списка выходного формата, который поддерживает камера
            StreamConfigurationMap configurationMap =
                    cc.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

            // Получения списка разрешений которые поддерживаются для формата jpeg
            Size[] sizesJPEG = configurationMap.getOutputSizes(ImageFormat.JPEG);

            if (sizesJPEG != null) {
                for (Size item:sizesJPEG) {
                    Log.i(MainActivity.LOG_TAG, "w:" + item.getWidth() + " h:" + item.getHeight());
                }
            } else {
                Log.e(MainActivity.LOG_TAG, "camera with id: "+mCameraID+" don`t support format: "+formatSize);
            }

        } catch (CameraAccessException e) {
            Log.e(MainActivity.LOG_TAG,e.getMessage());
            //e.printStackTrace();
        }
    }

}

Как можно заметить, в конструкторе класса используем аннотацию @NonNull. Таким образом мы указали себе (и параллельно работающим разработчикам) подсказку, что эти поля не должны быть  null! 

В MainActivity необходимо теперь добавить массив наших CameraHelper для дальшейшей работы с ними:


CameraHelper[] myCameras = null;

Далее нам необходимо переделать вывод информации по камере относительно того, что мы написали выше. Теперь наш вывод информации в методеonCreate выглядит следующим образом: 


try{
   // Получение списка камер с устройства
   String[] cameraList = mCameraManager.getCameraIdList();
   //создаем место для наших камер
   myCameras = new CameraHelper[cameraList.length]

   // создаем обработчики для нашых камер и выводим информацию по камере
   for (String cameraID : cameraList) {
       Log.i(LOG_TAG, "cameraID: "+cameraID);
       int id = Integer.parseInt(cameraID);

       // создаем обработчик для камеры
       myCameras[id] = new CameraHelper(mCameraManager,cameraID);

       // выводим инормацию по камере
       myCameras[id].viewFormatSize(ImageFormat.JPEG);
   }
}
catch(CameraAccessException e){
   Log.e(LOG_TAG, e.getMessage());
   e.printStackTrace();
}

продолжение в следущей части ... Часть 2 Часть 3

 

Комментарий (3)

Антон Тарасов

12 Мая 2017 в 10:30

myCameras - нигде не объявлена, какого типа эта переменная?

0/ 0
ответить

sidadmin

Антон Тарасов, Статья обновлена и этот момент исправлен. Спасибо за отзыв.

Дмитрий

06 Мая 2016 в 12:04

myCameras[id].setTextureView(mImageView); Тут ошибка, судя по всему. У класса CameraHelper нет метода setTextureView. По крайней мере, он не описан в данной статье.

0/ 0
ответить

Войдите с помощью соцсетей:
или
введите свои данные: