С выходом новых версий 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();
}
Давайте запустим и посмотрим что у нас вышло:
Как видим, у нас в телефоне доступно 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.
Следующим шагом будет открытие камеры. Для этого в менеджере предусмотрен метод 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:30myCameras - нигде не объявлена, какого типа эта переменная?
sidadmin
Антон Тарасов, Статья обновлена и этот момент исправлен. Спасибо за отзыв.
Дмитрий
06 Мая 2016 в 12:04myCameras[id].setTextureView(mImageView); Тут ошибка, судя по всему. У класса CameraHelper нет метода setTextureView. По крайней мере, он не описан в данной статье.