Для удобства создания приложений на Android было разработано множество различных сервисов, позволяющих автоматизировать различные процессы или упростить их выполнение. Как правило, большая часть этих сервисов создана Google и входит в Google Mobile Services (GMS), который предоставляет широкий ассортимент инструментов для работы. И хотя они работают на большинстве устройств с Android, существуют устройства, по той или иной причине не поддерживающие эти сервисы, и в этом случае приходится искать альтернативы.
Например, одними из таких устройств являются смартфоны и планшеты Huawei. В связи с тем, что на новых устройствах Huawei более нет поддержки GMS, компания перезапустила и обновила свой собственный аналог под названием Huawei Mobile Services (HMS). Его задачей является создание удобной экосистемы, позволяющей создавать приложения быстро и качественно, и предоставление как необходимых для работы приложения сервисов (карты, облачные хранилища, платежи, аутентификация), так и дополнительных, расширяющих возможности приложения. Специально для разработчиков в HMS есть компонент HMS Core, который предоставляет все необходимые API и SDK для работы с сервисами. Кроме того, как заверяют Huawei, HMS Core написан таким образом, чтобы разработчикам было легко переписать свои приложения, работающие на GMS, под HMS.
Рассмотрим работу HMS Core на примере сервиса для генерации и сканирования QR-кодов. В одном из наших приложений, “Менеджер паролей от Wi-Fi сетей“, используется генерация Huawei, содержащих данные сохранённой сети, которыми затем можно поделиться с другими людьми. Однако в приложении нет возможности сканировать этот код и прочитать его содержимое. Добавим эту возможность.
Сам HMS Core не является монолитным, он разделяется на ряд отдельных компонентов, каждый из которых работает с определённым сервисом. В нашем случае, для добавления сканера QR-кодов нам понадобится инструмент под названием Scan Kit.
Scan Kit позволяет сканировать и считывать все основные 1D и 2D штрихкоды (к которым также относится и QR-код), а также генерировать свои собственные. Он автоматически обнаруживает, увеличивает и распознаёт штрихкоды, что позволяет ему считывать даже самые маленькие штрихкоды без проблем. Кроме того, Scan Kit может работать даже при плохой освещённости или в случае, если штрихкод замаран либо отражает, что позволяет эффективно сканировать в любых условиях. Сервис может работать как на Android, так и на iOS, но в данном случае нас интересует только Android.
Scan Kit умеет распознавать 13 основных форматов штрихкодов:
- 1D штрихкоды: EAN-8, EAN-13, UPC-A, UPC-E, Codabar, Code 39, Code 93, Code 128 и ITF;
- 2D штрихкоды: QR код, Data Matrix, PDF417 и Aztec.
Также важной особенностью Scan Kit является то, что библиотека может работать в разных режимах:
- Default View – с использованием вьюхи и активности по умолчанию;
- Customized View – с использованием собственной вьюхи;
- Bitmap – позволяет лучше настраивать процесс сканирования;
- MultiProcessor – использует ML Kit для распознавания нескольких объектов одновременно.
Как можно понять, Default View является самым простым вариантом, когда не нужно создавать свой интерфейс для сканирования и достаточно просто получить результат, что избавляет от написания лишнего кода. Customized View отличается от предыдущего лишь тем, что интерфейс и дизайн создаётся уже разработчиком. Bitmap в свою очередь определяет, далеко ли находится сканируемый штрихкод, и если да – возвращает величину, на которую следует увеличить изображение. И наконец MultiProcessor использует средства машинного обучения, чтобы ещё эффективнее сканировать штрихкоды.
Для нашего приложения воспользуемся Default View, поскольку нет необходимости создавать отдельный интерфейс, а автоматической работы сканера будет вполне достаточно для результата.
Приступим к встраиванию этой библиотеки в приложение.
Важно! Для того, чтобы работать с HMS, нужно предварительно зарегистрировать аккаунт разработчика в HUAWEI Developer, после чего пройти верификацию и создать проект приложения в консоли Huawei.
Перед добавлением библиотеки нам понадобится скачать файл конфигурации и добавить его в проект. Для этого зайдём в консоль AppGallery Connect и откроем настройки приложения, для которого мы встраиваем Scan Kit. Нужный файл конфигурации называется agconnect-services.json.
Затем этот файл закинем в папку app проекта приложения.
Теперь добавим репозиторий Huawei и плагин AppGallery Connect. Для этого откроем build.gradle проекта и добавим в него следующие строки:
buildscript { repositories { mavenLocal() jcenter() google() maven {url 'https://developer.huawei.com/repo/'} } dependencies { ... classpath 'com.huawei.agconnect:agcp:1.3.1.300' } } apply plugin: 'nebula.lint' gradleLint.rules = ['all-dependency'] allprojects { repositories { google() jcenter() mavenCentral() maven { url "https://jitpack.io" } maven { url "https://maven.google.com" } maven {url 'https://developer.huawei.com/repo/'} } }
После этого перейдём в build.gradle модуля приложения и добавим в него зависимость с библиотекой Scan Kit и плагин AppGallery Connect.
dependencies { ... implementation 'com.huawei.hms:scanplus:1.2.1.300' } apply plugin: 'project-report' apply plugin: 'com.huawei.agconnect'
Стоит отметить, что Scan Kit предоставляет два варианта SDK: Scan Kit SDK и Scan Kit SDK Plus. Оба варианта одинаковы по функционалу, однако различаются по качеству распознавания на устройствах не от Huawei. Scan Kit SDK использует на таких устройствах общие средства распознавания, которые работают несколько хуже, чем те, которые используются на устройствах Huawei. Scan Kit SDK Plus в свою очередь использует улучшенное распознавание, что позволяет одинаково эффективно работать со шрихкодами как на устройствах Huawei, так и на любых других. Поэтому если прибавка к размеру APK в ~2 MB не критична, лучше всего использовать вариант Plus.
Примечание: HMS Core добавляет в приложение все поддерживаемые языки, что может добавить лишний размер к APK. Чтобы ограничиться только списком тех языков, которые нужны, откроем build.gradle модуля приложения и добавим нужные языки в defaultConfig:
defaultConfig { ... resConfigs "en", "zh-rCN", "zh-rTW", "de", "el", "es-rES", "es-rUS", "fa", "fi", "fr", "hi", "it", "ja", "ko", "pt-rBR", "pt-rPT", "ru" }
Чтобы библиотека корректно работала в релизной версии приложения, добавим следующие исключения в proguard-rules.txt:
-ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;}
Теперь, когда библиотека добавлена и подготовлена, можно приступить непосредственно к коду. Так как сканирование будет производиться с использованием камеры, в манифест нужно добавить разрешение CAMERA, которое затем будет запрашиваться у пользователя перед началом сканирования. Для этого добавим в AndroidManifest.xml следующую строку:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.rusdelphi.wifipassword"> ... <uses-permission android:name="android.permission.CAMERA"/> ...
Когда пользователь захочет сканировать QR-код, нужно проверить, имеет ли приложение разрешение на использование камеры, и если нет – запросить его. Если же разрешение есть – вызываем метод takeBarcodePicture(), в котором будет производиться инициализация сканирования.
if (mainView != null) { if (Tools.hasSelfPermission(mainView.getActivity(), Manifest.permission.CAMERA)) { takeBarcodePicture(); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mainView.getActivity() .requestPermissions( new String[] { Manifest.permission.CAMERA }, REQUEST_PERMISSION_TAKE_PHOTO); } } }
Результат запроса приходит в метод onRequestPermissionResult() активности, где мы проверяем, согласился ли пользователь предоставить права приложению или нет.
if (Tools.verifyAllPermissions(grantResults)) { takeBarcodePicture(); } else { mainView.onShowToast(R.string.permission_denied); }
Когда разрешение на камеру есть, в методе takeBarcodePicture() определяем параметры для сканирования и вызываем метод библиотеки startScan() с заданными параметрами.
private void takeBarcodePicture() { if (mainView == null) return; HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.QRCODE_SCAN_TYPE, HmsScan.DATAMATRIX_SCAN_TYPE).create(); ScanUtil.startScan(mainView.getActivity(), REQUEST_CAMERA, options); }
Как уже упоминалось выше, мы воспользовались вариантом сканирования по умолчанию, поэтому нам нужно добавить активность библиотеки в свой AndroidManifest.xml:
<activity android:name="com.huawei.hms.hmsscankit.ScanKitActivity" />
Результат выполнения сканирования возвращается в метод onActivityResult() активности и имеет код, который был присвоен в startScan(), т.е. REQUEST_CAMERA.
case REQUEST_CAMERA: { if (resultCode == Activity.RESULT_OK) { HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT); if (obj != null) { if (BuildConfig.DEBUG) Log.d("HmsScan", obj.getOriginalValue()); if (obj.getScanTypeForm() == HmsScan.WIFI_CONNECT_INFO_FORM) { HmsScan.WiFiConnectionInfo wifiConnectionInfo = obj.getWiFiConnectionInfo(); String password = wifiConnectionInfo.getPassword(); String ssidNumber = wifiConnectionInfo.getSsidNumber(); int cipherMode = wifiConnectionInfo.getCipherMode(); showAddButtonDialog(ssidNumber, password, cipherMode); } } } break; }
Если активность библиотеки вернула результат RESULT_OK, то получаем объект HmsScan, содержащий результат сканирования QR-кода. В зависимости от того, какие данные были зашифрованы в QR-код, у объекта HmsScan следует вызывать разные методы для получения этих данных. Поскольку QR-код может нести в себе самую разную информацию, следует перед началом работы проверить, какие данные в нём находятся. Чтобы убедиться, что отсканированный QR-код содержит именно данные о Wi-Fi сети, вызовем метод getScanTypeForm(). Так как мы генерировали QR-код с данными Wi-Fi сети, то нам нужно узнать SSID сети, пароль и тип шифрования. Таким образом, нам следует вызывать методы getSsidNumber(), getPassword() и getCipherMode() соответственно.
После этого мы передаём эти параметры в showAddButtonDialog(), где показываем им пользователю.
Таким образом, используя возможности HMS Core можно легко работать с QR-кодами, причём нет привязки к конкретно устройствам Huawei, сканирование работает одинаково хорошо и на других устройствах. Scan Kit предоставляет богатый инструментарий и для просто внедрения, и для точной настройки, что делает его хорошей заменой аналогичных сервисов Google.