ebook img

Google Android. это несложно. Сборник уроков. Часть III PDF

397 Pages·7.301 MB·Russian
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview Google Android. это несложно. Сборник уроков. Часть III

Урок 133. Камера. Делаем снимок и пишем видео Материалы по смежным темам  Урок 51. SimpleAdapter, добавление и удаление записей  Урок 52. SimpleCursorAdapter, пример использования  Видеоуроки Android  Урок 129. Медиа. Запись звука с помощью MediaRecorder  Урок 131. Камера. Используем системное приложение  Вебинары  Урок 132. Камера. Вывод изображения на экран. Размер preview. Обработка поворота устройства  Урок 134. Камера. Настройки  Урок 139. Google maps. Создание и настройка проекта. Карта, камера, события Создано 14.10.2013 10:26 Автор: damager82 В этом уроке: - делаем снимок - пишем видео - видеоверсия урока На прошлом уроке мы очень подробно рассмотрели как правильно выводить изображение с камеры на экран. Теперь узнаем, как это изображение можно сохранить и как фото и как видео. Фото делается совсем просто, одним методом. А записать видео нам поможет MediaRecorder. Напомню, что MediaRecorder мы подробно рассмотрели в Уроке 129. Чтобы не усложнять урок и пример я не буду здесь заморачиваться с размерами превью и экрана, с поворотами и с описанием работы с камерой. Если нужны подробности – загляните в Урок 132. Создадим проект: Project name: P1331_CameraRecord Build Target: Android 2.3.3 Application name: CameraRecord Package name: ru.startandroid.develop.p1331camerarecord Create Activity: MainActivity В strings.xml добавим строки: 362 <string name="take_picture">Picture</string> <string name="start_record">Start</string> <string name="stop_record">Stop</string> Экран main.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="200dp" android:layout_height="150dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true"> </SurfaceView> <Button android:id="@+id/btnTakePicture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@id/surfaceView" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:onClick="onClickPicture" android:text="@string/take_picture"> </Button> <Button android:id="@+id/btnStartRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/btnTakePicture" android:layout_toRightOf="@id/btnTakePicture" android:onClick="onClickStartRecord" android:text="@string/start_record"> </Button> <Button android:id="@+id/btnStopRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/btnStartRecord" android:layout_toRightOf="@id/btnStartRecord" android:onClick="onClickStopRecord" android:text="@string/stop_record"> </Button> </RelativeLayout> На экране у нас SurfaceView и три кнопки: сделать фото, начать запись, остановить запись. 363 В манифест пропишем разрешения: <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Это работа с камерой, запись звука и запись на sd-карту. MainActivity.java: package ru.startandroid.develop.p1331camerarecord; import java.io.File; import java.io.FileOutputStream; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.media.CamcorderProfile; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; public class MainActivity extends Activity { 364 SurfaceView surfaceView; Camera camera; MediaRecorder mediaRecorder; File photoFile; File videoFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); File pictures = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); photoFile = new File(pictures, "myphoto.jpg"); videoFile = new File(pictures, "myvideo.3gp"); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); SurfaceHolder holder = surfaceView.getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); camera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); } @Override protected void onResume() { super.onResume(); camera = Camera.open(); } @Override protected void onPause() { super.onPause(); releaseMediaRecorder(); if (camera != null) camera.release(); camera = null; } public void onClickPicture(View view) { camera.takePicture(null, null, new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { 365 try { FileOutputStream fos = new FileOutputStream(photoFile); fos.write(data); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }); } public void onClickStartRecord(View view) { if (prepareVideoRecorder()) { mediaRecorder.start(); } else { releaseMediaRecorder(); } } public void onClickStopRecord(View view) { if (mediaRecorder != null) { mediaRecorder.stop(); releaseMediaRecorder(); } } private boolean prepareVideoRecorder() { camera.unlock(); mediaRecorder = new MediaRecorder(); mediaRecorder.setCamera(camera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setProfile(CamcorderProfile .get(CamcorderProfile.QUALITY_HIGH)); mediaRecorder.setOutputFile(videoFile.getAbsolutePath()); mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); try { mediaRecorder.prepare(); } catch (Exception e) { e.printStackTrace(); releaseMediaRecorder(); return false; } return true; } private void releaseMediaRecorder() { if (mediaRecorder != null) { mediaRecorder.reset(); mediaRecorder.release(); mediaRecorder = null; camera.lock(); } } } 366 Смотрим код В onCreate мы создаем пути для фото и видео файлов, в которые будет сохраняться результат. Далее определяем SurfaceView, Holder и callback к нему. В onResume получаем доступ к камере. В onPause освобождаем ресурсы MediaRecorder и камеры. onClickPicture – это обработчик нажатия на кнопку Picture. Здесь будем делать снимок. Для этого нам необходимо вызвать метод takePicture. Этот метод асинхронный, для получения результата используются callback-и. Их три. Первый, ShutterCallback, сработает сразу после того, как камера сделает снимок. Сюда можно повесить звук затвора, например. Я его не использую, передаю null. Второй, PictureCallback, вернет нам сырую raw картинку. Я его также не использую, передаю null. Третий, PictureCallback, вернет нам готовую сжатую jpeg картинку. Это нам и надо. Создаем callback и в его методе onPictureTaken будем получать byte-массив. Это и есть готовое фото, которое мы пишем в файл. onClickStartRecord – обработчик нажатия на кнопку Start. Здесь будем включать запись видео с камеры. Для этого подготавливаем MediaRecorder в методе prepareVideoRecorder. Метод вернет нам значение Boolean, по которому мы поймем удалось ли подготовить объект. Если он готов, стартуем запись методом start. Если при подготовке возникли проблемы, то освобождаем ресурсы. onClickStopRecord – обработчик кнопки Stop. Здесь останавливаем запись видео методом stop и освобождаем ресурсы. Кстати, в хелпе к методу stop написано, что он может выдавать RuntimeException, если что-то не так с аудио/видео, которое дали MediaRecorder- у на вход. Имеет смысл эту ошибку ловить и удалять в таком случае записываемый файл, т.к. там будут некорректные данные. prepareVideoRecorder – метод подготовки MediaRecorder к записи. Сначала методом unlock снимаем монопольный доступ с камеры, чтобы MediaRecorder мог ее использовать. Затем создаем объект MediaRecorder. Далее идут 6 методов его настройки: setCamera – предоставляем камеру, которая будет использована для записи setAudioSource: указываем источник звука – CAMCORDER setVideoSource: указываем источник видео – CAMERA setProfile: указываем профиль записи. В профиле содержаться такие данные как: тип контейнера, аудио/видео кодек, битрейт и пр. Чтобы нам руками не задавать все эти 367 характеристики, используем профили. Список профилей можно посмотреть в хелпе к объекту CamcorderProfile. Мы используем высокое качество - QUALITY_HIGH. setOutputFile: указываем путь к файлу, куда будет записано видео setPreviewDisplay: указываем surface для показа превью в процессе записи. Если ранее вы для камеры уже указали surface в ее методе setPreviewDisplay, то этот метод вызывать необязательно. Хелп очень рекомендует вызывать эти 6 методов именно в таком порядке, иначе грозит ошибками и неудачей при записи. Когда все параметры указали, вызываем prepare и если все ок, то получаем MediaRecorder готовый к записи. В методе releaseMediaRecorder освобождаем ресурсы MediaRecorder и снова монополизируем камеру методом lock. Можно все сохранить и запускать. По нажатию на кнопку Picture будет сохраняться фото, а по кнопкам Start и Stop – стартовать и останавливаться запись видео. Полученные фото и видео будут сохранены в папке Pictures под именами myphoto.jpg и myvideo.3gp На следующем уроке: - меняем настройки камеры 368 Урок 134. Камера. Настройки Материалы по смежным темам  Урок 111. Android 3. Fragments. PreferenceFragment - настройки. Headers  Урок 131. Камера. Используем системное приложение  Урок 132. Камера. Вывод изображения на экран. Размер preview. Обработка поворота устройства  Урок 133. Камера. Делаем снимок и пишем видео  Урок 139. Google maps. Создание и настройка проекта. Карта, камера, события Создано 29.10.2013 09:09 Автор: damager82 В этом уроке: - меняем настройки камеры По работе с камерой нам осталась одна тема – настройки камеры. Т.е. это разрешения, эффекты, фокусы, качество, вспышка и пр. Полный список настроек можно посмотреть в хелпе (обращайте внимание на минимальную версию API). Для работы с настройками используется объект Camera.Parameters. Он содержит кучу методов, которые можно разделить на несколько групп. Методы is<…>Supported позволяют узнать поддерживается ли данная опция/настройка камерой. Методы get<…>Supported и getMax<…> предоставят вам набор поддерживаемых значений или максимальное значение опции/настройки. Методы get<…> вернут текущее значение настройки. Методы set<…> установят текущее значение настройки. В этом уроке рассмотрим на практике работу с парой настроек: цветовые эффекты и режимы вспышки. А также я опишу работу с настройками, которые выбиваются из общего алгоритма. Напомню, что в Уроке 132 мы разбирались с тем, как совместить размеры экрана и превью камеры, и учесть поворот устройства. А в Уроке 133 – как сохранить фото или видео. В этом уроке я не буду это использовать, чтобы не повторяться и не усложнять материал. Создадим проект: 369 Project name: P1341_CameraFeatures Build Target: Android 2.3.3 Application name: CameraFeatures Package name: ru.startandroid.develop.p1341camerafeatures Create Activity: MainActivity В strings.xml добавим строки: <string name="color_effect">Color Effect</string> <string name="flash_mode">Flash Mode</string> main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="400dp" android:layout_height="300dp" android:layout_marginBottom="10dp"> </SurfaceView> <TableLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/color_effect"> </TextView> <Spinner android:id="@+id/spEffect" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Spinner> </TableRow> <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/flash_mode"> </TextView> <Spinner android:id="@+id/spFlash" 370 android:layout_width="wrap_content" android:layout_height="wrap_content"> </Spinner> </TableRow> </TableLayout> </LinearLayout> На экране у нас SurfaceView для вывода изображения и два спиннера настроек. Первый будет предоставлять выбор цветовых эффектов, а второй – режимы работы вспышки. Про спиннеры я рассказывал в Уроке 56. В манифесте добавляем права на работу с камерой <uses-permission android:name="android.permission.CAMERA"/> MainActivity.java: package ru.startandroid.develop.p1341camerafeatures; import java.util.List; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Spinner; public class MainActivity extends Activity { SurfaceView surfaceView; Camera camera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); SurfaceHolder holder = surfaceView.getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); camera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } 371

See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.