Вступление
QR-коды стали вездесущими в последние годы. Я уверен, что вы видели один в газетной рекламе или на рекламном щите. С точки зрения непрофессионала, QR-коды, как и все другие штрих-коды, являются изображениями, которые предназначены для чтения на машинах. Обычно они представляют собой небольшую строку, например сокращенный URL-адрес или номер телефона. Вот пример QR-кода, который содержит URL домашней страницы Tuts +:

В отличие от традиционных штрих-кодов, для которых требуется специальное оборудование, QR-коды могут быть точно прочитаны любым смартфоном с приличной камерой.
Последний выпуск SDK для сервисов Google Play включает в себя API для мобильных устройств, который, помимо прочего, позволяет разработчикам Android легко создавать приложения, способные обнаруживать и считывать QR-коды в режиме реального времени. В этом уроке я собираюсь помочь вам начать работу с ним.
Предпосылки
Чтобы следовать этому уроку, вам понадобится:
- последняя версия Android Studio
- Android-устройство с камерой
1. Установка Google Play Services SDK
Прежде чем использовать API мобильного видения в своем приложении, вы должны добавить SDK 7.8 сервисов Google Play в качестве зависимости compile в build.gradle модуля вашего приложения .
groovy compile 'com.google.android.gms:play-services:7.8.0'
Когда вы нажмете кнопку « Синхронизировать сейчас» , вы увидите ошибку, которая выглядит следующим образом:

Нажмите на ссылку Установить репозиторий и синхронизировать проект, чтобы установить SDK.
2. Редактирование манифеста приложения
Добавьте следующую строку в AndroidManifest.xml вашего приложения, чтобы автоматически установить библиотеки обнаружения штрих-кода на устройства, которые пытаются запустить ваше приложение:
« `XML
« `
Кроме того, поскольку вы будете использовать камеру устройства для захвата QR-кодов, вам следует запросить разрешение android.permission.CAMERA .
« `XML
« `
3. Чтение QR-кода с фотографии
Давайте теперь напишем некоторый код, который может считывать QR-код из фотографии, хранящейся в папке ресурсов вашего приложения. Я собираюсь назвать фото myqrcode.jpg . Если у вас нет фотографий, содержащих QR-коды, вы можете получить их у Flickr .
Шаг 1: преобразовать фотографию в Bitmap
Поскольку API для мобильного видения требует в качестве входных данных Bitmap , сначала необходимо преобразовать фотографию в Bitmap . Для этого откройте фотографию, используя метод AssetManager класса AssetManager и передайте InputStream возвращенный методу BitmapFactory . Для простоты, сделайте это внутри метода onCreate вашей Activity .
java Bitmap myQRCode = BitmapFactory.decodeStream( getAssets().open("myqrcode.jpg") );
Шаг 2. Создание детектора штрих-кода
Чтобы обнаружить QR-коды (и другие типы штрих-кодов), вы должны использовать экземпляр класса BarcodeDetector . Следующий код показывает, как создать его с помощью BarcodeDetector.Builder :
java BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this) .setBarcodeFormats(Barcode.QR_CODE) .build();
Обратите внимание, что детектор по умолчанию будет обнаруживать штрих-коды всех поддерживаемых форматов. Я использовал метод setBarcodeFormats чтобы явно указать, что детектор должен обнаруживать только QR-коды.
Шаг 3: Прочитайте QR-код
Используйте Frame.Builder чтобы создать Frame с использованием Bitmap , созданного ранее.
java Frame myFrame = new Frame.Builder() .setBitmap(myQRCode) .build();
Вызовите метод detect BarcodeDetector чтобы сгенерировать SparseArray содержащий все QR-коды, которые BarcodeDetector обнаружил на вашей фотографии.
java SparseArray<Barcode> barcodes = barcodeDetector.detect(myFrame);
Каждый элемент SparseArray содержит объект Barcode . Чтобы получить необработанное содержимое QR-кода, вы можете использовать поле rawValue объекта rawValue . Тем не менее, я предлагаю вам использовать более displayValue для чтения поле displayValue . Вот некоторый код, который печатает содержимое первого QR-кода, обнаруженного API:
« `java // Проверить, был ли обнаружен хотя бы один штрих-код if (barcodes.size ()! = 0) {
// Распечатать сообщение QR-кода Log.d («Данные моего QR-кода», barcodes.valueAt (0) .displayValue ); } `` `
Если вы запустите свою Activity сейчас, вы сможете увидеть сообщение, содержащееся в QR-коде вашей фотографии.
4. Чтение QR-кода с помощью камеры
API мобильного видения также позволяет вам в реальном времени обнаруживать и считывать штрих-коды с помощью камеры вашего устройства. Давайте создадим новую Activity которая делает именно это.
Шаг 1: Определите макет
Создайте новый XML-файл макета с именем activity_main.xml . Макет должен иметь SurfaceView для отображения кадров предварительного просмотра, снятых камерой. Если вы хотите, вы также можете добавить TextView для отображения содержимого QR-кодов, которые обнаруживает API.
После использования RelativeLayout для позиционирования обоих виджетов XML-файл макета должен выглядеть примерно так:
« `XML
« `
Шаг 2. Создайте Activity
Создайте новый класс Java с именем MainActivity.java . Сделайте его подклассом Activity и переопределите его метод onCreate . Внутри метода onCreate вызовите setContentView чтобы применить макет, созданный на предыдущем шаге. Затем используйте findViewById чтобы получить ссылки на виджеты, определенные в макете.
« `java setContentView (R.layout.activity_main);
cameraView = (SurfaceView) findViewById (R.id.camera_view); barcodeInfo = (TextView) findViewById (R.id.code_info); « `
Чтобы получить поток изображений с камеры устройства и отобразить их в SurfaceView , создайте новый экземпляр класса CameraSource.Builder с помощью CameraSource.Builder . Поскольку для CameraSource требуется BarcodeDetector , создайте его с BarcodeDetector.Builder класса BarcodeDetector.Builder . При желании вы можете настроить размеры предварительного просмотра камеры с setRequestedPreviewSize метода setRequestedPreviewSize .
« `java barcodeDetector = new BarcodeDetector.Builder (this) .setBarcodeFormats (Barcode.QR_CODE) .build ();
cameraSource = new CameraSource .Builder (this, barcodeDetector) .setRequestedPreviewSize (640, 480) .build (); « `
Затем добавьте обратный вызов в SurfaceHolder SurfaceView чтобы вы знали, когда можно начать рисовать кадры предварительного просмотра. Обратный вызов должен реализовывать интерфейс SurfaceHolder.Callback .
« `java cameraView.getHolder (). addCallback (new SurfaceHolder.Callback () {@Override public void surfaceCreated (SurfaceHolder holder) {}
@Override public void surfaceChanged (держатель SurfaceHolder, формат int, ширина int, высота int) { } @Override public void surfaceDestroyed (держатель SurfaceHolder) { }}); `` `
Внутри метода surfaceCreated метод start объекта CameraSource чтобы начать рисовать кадры предварительного просмотра. Поскольку метод start ожидает, что вы обработаете IOException , вы должны вызывать его из блока try...catch .
java try { cameraSource.start(cameraView.getHolder()); } catch (IOException ie) { Log.e("CAMERA SOURCE", ie.getMessage()); }
Аналогично, внутри метода surfaceDestroyed метод stop объекта CameraSource чтобы прекратить рисование рамок предварительного просмотра.
java cameraSource.stop();
Ваша Activity почти готова. Однако вам все равно нужно сообщить BarcodeDetector что он должен делать при обнаружении QR-кода. Создайте экземпляр класса, который реализует интерфейс Detector.Processor и передайте его методу setProcessor объекта BarcodeDetector . Android Studio автоматически сгенерирует заглушки для методов интерфейса.
« `java barcodeDetector.setProcessor (новый Detector.Processor
@Override public void receiveDetections (Detector.Detections <штрих-код> обнаружения) { }}); `` `
Внутри метода receiveDetections получите SparseArray объектов Barcode , вызвав метод getDetectedItems класса Detector.Detections . Теперь вы можете написать код, чтобы сделать что-то с обнаруженными QR-кодами, потому что я уже показал вам, как работать с объектами SpareArray ранее в этом руководстве.
Вот как вы можете отобразить displayValue QR-кода в TextView :
« `java final SparseArray
if (barcodes.size ()! = 0) {barcodeInfo.post (new Runnable () {// Использовать метод post публичного void runView TextView run () {barcodeInfo.setText (// Обновление TextView barcodes.valueAt (0) ) .displayValue);}}); } « `
Обратите внимание, что вы должны встроить вызов метода setText в вызов метода post из TextView , так как receiveDetections не выполняется в потоке пользовательского интерфейса. Несоблюдение этого требования приведет к ошибке во время выполнения.
Теперь вы можете скомпилировать и запустить ваше приложение. Направьте камеру вашего устройства на QR-код, и вы сможете сразу увидеть его содержимое.

Вывод
В этом руководстве вы узнали, как использовать API мобильного видения для считывания QR-кодов со статических изображений, а также из потоков с камер в реальном времени. Хотя в этом руководстве мы работали только с QR-кодами, вы также можете использовать API для чтения других популярных форматов штрих-кодов, таких как UPC-A и EAN-13.
Чтобы узнать больше об API мобильного видения, я рекомендую посетить документацию API.