Пример: Скачать среду можно с сайта для разработчиков Android (http://developer.android.com/sdk/index.html). Там скачать можно только Android Studio |
Многооконное приложение
12.3 Настройка интерфейса и реализация логики активности для работы с камерой
Настроим интерфейс активности для работы с камерой. Нам понадобится окно предварительного просмотра, добавим в окно активности элемент SurfaceView. А так же нам понадобится кнопка для выполнения снимков, добавим в окно активности элемент ImageButton. Далее предлагаем настроить интерфейс самостоятельно. В нашем случае активность выглядит так, как показано на рис. 12.1.
Реализуем логику активности, в данном случае необходимо при нажатии на кнопку выполнить снимок. Работаем с java файлом, описывающим соответствующий класс активности, CameraActivity.java.
Объявим следующие поля класса активности:
private Camera camera; //для проведения всех операций с камерой private SurfaceHolder surfaceHolder; //для задания preview private SurfaceView preview; //для отображения окна предпросмотра private View shotBtn; //для выполнения снимка (кнопка)
Для начала работы с камерой необходимо ее инициализировать, сделать это лучше в методе onResume() класса активности, для инициализации используется следующая конструкция:
camera = Camera.open();
После завершения работы с камерой, необходимо ее освободить для других приложений, сделать это лучше в методе onPause() класса активности, для освобождения камеры используется следующая конструкция:
Camera.release();
Для активности, работающей с камерой, имеет смысл сразу задать расположение экрана следующим образом
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
в противном случае, приходится, например, в методе surfaceCreated() проверять расположение экрана и поворачивать окно предварительного просмотра, что не очень удобно, так как поворот экрана занимает некоторое время.
Выполним настройку окна предварительного просмотра:
preview = (SurfaceView) findViewById(R.id.surfaceCamera); surfaceHolder = preview.getHolder(); surfaceHolder.addCallback(new MyCallback());
метод addCallback() используется для отслеживания изменений окна предпросмотра. Параметром этого метода служит экземпляр класса реализующего интерфейс SurfaceHolder.Callback, в нашем случае для реализации этого интерфейса создан внутренний класс активности MyCallback.
В этом классе необходимо реализовать методы:
public void surfaceCreated(SurfaceHolder holder); public void surfaceChanged(SurfaceHolder holder, int format, int width, int height); public void surfaceDestroyed(SurfaceHolder holder);
Мы реализуем метод surfaceCreated(), оставшиеся два метода запишем с пустой реализацией.
В методе surfaceCreated() зададим окно предварительного просмотра:
camera.setPreviewDisplay(holder);
Выполним необходимые настройки окна предпросмотра (см. Листинг 12.1).
Запустим отображение окна предварительного просмотра:
camera.startPreview();
Пришло время обсудить и реализовать выполнение фотосъемки. Для того, чтобы сделать снимок необходимо вызвать метод takePicture(). Вызов этого метода можно выполнить из метода-обработчика события нажатия кнопки, тогда при нажатии на кнопку сразу будет получена фотография, а можно "растянуть удовольствие" и воспользоваться предварительной автофокусировкой.
Сначала инициализируем кнопку и добавим слушателя события нажатия в методе onCreate() активности:
shotBtn = findViewById(R.id.bCameraShot); shotBtn.setOnClickListener(new MyViewListener());
В данном случае слушателем является экземпляр внутреннего класса MyViewListener, который реализует интерфейс View.OnClickListener.
class MyViewListener implements View.OnClickListener{ @Override public void onClick(View v){ if (v == shotBtn){ camera.autoFocus(new MyAutoFocusCallback()); } } }
В методе onClick() вызываем обработчик автофокуса, слушателем события автофокусировки в данном случае является экземпляр внутреннего класса MyAutoFocusCallback, который реализует интерфейс Camera.AutoFocusCallback.
class MyAutoFocusCallback implements Camera.AutoFocusCallback{ @Override public void onAutoFocus(boolean paramBoolean, Camera paramCamera){ if (paramBoolean){ // если удалось сфокусироваться, делаем снимок paramCamera.takePicture(null, null, null, new MyPictureCallback()); } } }
Метод takePicture() имеет четыре параметра:
Camera.ShutterCallback shutter | - вызывается в момент получения изображения с матрицы; |
Camera.PictureCallback raw | - программе передаются для обработки raw данные (если поддерживается аппаратно); |
Camera.PictureCallback postview | - программе передаются полностью обработанные данные (если поддерживается аппаратно); |
Camera.PictureCallback jpg | - программе передается изображение в формате jpg. Здесь может быть организована запись изображения на карту памяти. |
В нашем случае последним параметром является экземпляр класса MyPictureCallback(), который реализует интерфейс Camera.PictureCallback. В этом классе реализован единственный метод (см. Листинг 12.1):
public void onPictureTaken(byte[] paramArrayOfByte, Camera paramCamera){...}
В листинге 12.1 представлен код активности, реализующей работу с камерой и позволяющей выполнять снимки.
Чтобы разрешить приложению работать с камерой и сохранять фотографии на карте памяти, в манифест необходимо добавить следующие разрешения:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />