Huawei – Building a Fully Connected, Intelligent World

FB Обзоры

Почему стоит обратить внимание на экосистему huawei

Смартфоны Huawei очень популярны: в 2020 году в России они занимали почти 18% рынка (Рис.1), а в мире — 11% (Рис.2), (

). Huawei заявила, что более 490 млн человек в более чем в 170 странах мира пользуются AppGallery (

). Поскольку аудитория у Huawei-устройств огромная, мы не можем это игнорировать и решили поддержать пользователей нашего приложения. Далее поэтапно рассмотрим, что же нужно сделать.

Huawei - Building a Fully Connected, Intelligent World
Рис.1Huawei - Building a Fully Connected, Intelligent World
Рис.2

Huawei health – huawei global

*Accessibility of some features may vary across regions. Product pictures and display
contents on the foregoing pages are provided for reference only. Actual product features and specifications
(including but not limited to appearance, colour, and size), as well as actual display contents (including
but not limited to backgrounds, UI, and icons) may vary.

**All data in the foregoing pages are theoretical values obtained by HUAWEI internal laboratories through
tests carried out under particular conditions. For more information, refer to the aforementioned product
details. Actual data may vary owing to differences in individual products, software versions, application
conditions, and environmental factors. All data is subject to actual usage.

***Due to real-time changes involving product batches, production and supply factors, in order to provide
accurate product information, specifications, and features, HUAWEI may make real-time adjustments to text
descriptions and images in the foregoing information pages, so that they match the product performance,
specifications, indexes, and components of the actual product. Product information is subject to such
changes and adjustments without notice.

Polyutil. расшифровка с помощью polyline


Теперь нам нужно отображать перемещение курьера. Для этого нам нужно расшифровывать строку, которая приходит с сервера. Для этого воспользуемся тем же алгоритмом от Google, с помощью которого строка кодировалась.

После расшифровки мы получили список координат курьера.

Specs

Автономность и зарядка

По заявлению производителя, гарнитура способна проработать от одного заряда аккумулятора до 4 часов с выключенным активным шумоподавлением, а с включенным — до 2,5 часов. Показатели не самые выдающиеся, но вполне приемлемые для гарнитуры среднего ценового сегмента. Осталось проверить, насколько данные из маркетинговых материалов соответствуют действительности.

Вновь вкратце напомним нашу методику. Безопасным уровнем звукового давления при прослушивании музыки в наушниках считается 75 дБ, но на практике большинство слушателей предпочитает уровень 90-100 дБ. Мы транслируем в наушники белый шум, фиксируя уровень SPL в районе 95 дБ, сразу после старта воспроизведения запускаем запись сигнала с измерительного стенда — по длине получившегося трека легко понять, сколько проработал каждый из наушников.

Разряжаются наушники неравномерно: правый стабильно работает немного меньше левого. Видимо, по умолчанию он является «ведущим» и применяется для связи со смартфоном. Очень малое число слушателей использует наушники в монорежиме, чаще всего отключение одного из них — повод убрать оба в кейс для зарядки. Потому при определении средней автономности ориентироваться мы будем на тот наушник, который проработал меньше.

ТестыЛевый наушникПравый наушник
Шумоподавление выключеноТест 14 часа 2 минуты3 часа 36 минут
Тест 24 часа 6 минут3 часа 28 минут
Итого4 часа 4 минуты3 часа 32 минуты
Шумоподавление включеноТест 12 часа 48 минут2 часа 30 минут
Тест 22 часа 40 минут2 часа 26 минут
Итого2 часа 44 минуты2 часа 28 минут

В целом, полученные данные не слишком отличаются от предлагаемых производителем — если немного понизить громкость, заявленные уровни автономности вполне достижимы. Также в описании наушников указано, что они способны работать 2,5 часа после 15 минут зарядки.

Кейс способен зарядить наушники до 6 раз, то есть даже при их использовании с включенным шумоподавлением потенциально пользователь имеет порядка 15 часов автономности минимум — стоит лишь иногда ненадолго помещать гарнитуру в кейс. Ну а с отключенным «шумодавом» получается и того больше — до 18 часов минимум, на целый день этого точно хватит с запасом, если не слушать музыку во сне.

Некоторые пользователи прошлых версий FreeBuds отмечали, что наушники после помещения в кейс не отключаются полностью и постоянно понемногу потребляют электроэнергию, разряжая тем самым аккумулятор. Потому в ходе тестирования мы внимательно следили за саморазрядом футляра — и действительно, за сутки заряд может снизиться примерно на 3%-5%.

Дизайн и конструкция

Как уже упоминалось выше, гарнитура обзавелась весьма интересным цветовым решением — серебристым с металлическим блеском (silver frost), именно этот вариант был у нас на тестировании. Выглядит очень оригинально и несомненно будет притягивать взгляды окружающих. Также гарнитура доступна в более «классическом» белом исполнении (ceramic white).

Округлый кейс стал чуть-чуть более компактным, чем у прошлой модели. Он отлично лежит в руке и вполне помещается даже в карман брюк, не создавая особого дискомфорта. На заднюю часть с петлей для открытия крышки нанесен логотип производителя. На одной из боковых граней видна кнопка, с помощью которой можно принудительно активировать режим сопряжения.

В нижней части футляра расположен разъем USB Type C, служащий для зарядки. Поверхность корпуса матовая и не склонна к появлению отпечатков от прикосновений.

Крышка хорошо фиксируется как в открытом, так и в закрытом состоянии, доводчик срабатывает примерно на половине пути. Форма кейса не очень рассчитана на то, чтобы открывать его одной рукой, но сделать это можно, причем легко — достаточно зажать корпус между большим и безымянным пальцем, а крышку толкать от себя указательным.

Наушники внутри кейса удерживаются магнитами, тест «на погремушку» они проходят отлично — даже если специально потрясти футляр возле уха, он почти не издает звуков. Вынимаются наушники легко — достаточно немного провернуть их внутри слота, как они «выскакивают» из него, ну а дальше их остается подцепить пальцами.

Внутри слотов видны контакты для зарядки. Расположены они довольно глубоко — почти на дне отверстия для «палочек» наушников, почистить их сложно, но вполне возможно.

На внутренней части крышки расположены углубления под верхнюю часть наушников, внутри которых виднеются логотипы систем сертификации, серийный номер и прочая информация.

На передней панели размещен маленький светодиодный индикатор, демонстрирующий состояние зарядки и сообщающий об активации беспроводного подключения.

Металлический блеск серебристой версии наушников сразу привлекает к себе внимание — это явно не просто устройство для прослушивания музыки, но и весьма заметный аксессуар. Для кого-то это может оказаться плюсом, для кого-то — наоборот. В любом случае, есть еще белая модификация.

Форм-фактор всем нам хорошо знаком — все те же «наушники с палочками». На внешней части удлиненной части корпуса видны отверстия, прикрытые сеточкой. Вероятно, за ними скрываются микрофоны, которые используются для работы системы активного шумоподавления.

Верхняя часть корпуса имеет каплевидную форму. На внутренней стороне два отверстия. Одно можно назвать компенсационным, однако его функция — не только сброс лишнего давления во время работы динамика, но и улучшение передачи НЧ-диапазона. За вторым скрывается инфракрасный датчик ношения.

Сверху на округлой части виднеется еще пара отверстий. Они могут выполнять как функцию компенсационных, так и скрывать микрофоны для работы ANC — тут можно только предполагать, в описании наушников информации об этом нет. При взгляде сверху хорошо заметно, что прилегающая к ушной раковине часть корпуса имеет довольно сложную форму, призванную обеспечить надежную и комфортную посадку.

Снизу на удлиненной части корпуса находятся контакты для зарядки и отверстия микрофонов для голосовой связи.

Округлая часть довольно крупная, но на комфорте и удобстве посадки в ушах это сказывается, скорее, положительным образом — к этому мы еще вернемся ниже. В целом же наушники обладают средним для своего класса размером, да и весят совсем немного — всего лишь 4,1 г.

Отверстие звуковода прикрыто сеткой, которая слегка утоплена внутрь корпуса. Потенциально это может затруднять ее очистку, но часто этим заниматься не придется — так что ничего страшного.

Звучание и измерения ачх

Звучат Huawei FreeBuds 4 довольно неожиданным для «вкладышей» образом — крупный по меркам рассматриваемого форм-фактора динамик диаметром 14,3 мм отрабатывает по полной. Они не только умеют воспроизводить так называемый «глубокий бас», но и делают на нем ощутимый акцент.

Середина не самая ровная, вокал часто звучит не так объемно и интересно, как хотелось бы. Но для гарнитуры, рассчитанной на повседневное использование, это вполне нормально. А если говорить про тренировки и занятия спортом, то хороший плотный бас может оказаться даже более важным, нежели «вкусно» поданный вокал или партии солирующих инструментов.

Традиционные для ВЧ-диапазона проблемы с сибилянтами, «песком» и прочим отсутствуют, но при этом и особых акцентов на высокочастотном диапазоне нет — он звучит максимально ненавязчиво, любители считать каждый удар хай-хэта будут разочарованы. Но тут мы опять возвращаемся к сфере использования наушников: перед разработчиками явно стояла задача обеспечить комфортный звук для повседневного прослушивания в фоновом режиме, который будет по душе широкому кругу слушателей.

Обращаем внимание читателей на то, что графики АЧХ приводятся исключительно в качестве иллюстрации, позволяющей продемонстрировать основные особенности звучания тестируемых наушников. Не стоит делать из них выводов о качестве той или иной модели.

График выше показан на фоне кривой IDF (IEM diffuse field compensation), предоставленной производителем используемого стенда. Ее задача — помочь скомпенсировать резонансные явления в имитированном слуховом канале и особенности используемого оборудования, создав «звуковой профиль», максимально корректно иллюстрирующий то, как звучание наушников воспринимается слушателем.

«Горб» от 30 до 70 Гц по-прежнему обращает на себя внимание, к чему приводит его наличие, мы обсудили выше. Видно, что низкочастотный диапазон в целом основательно подчеркнут — картинка вполне корректно описывает субъективные впечатления от прослушивания гарнитуры.

При этом акцент на басах очень сильно зависит от положения наушников внутри ушной раковины. Сравним два графика — то, что мы уже видели выше и еще один, полученный после того, как мы поместили наушник в «звуковой проход» нашего стенда с чуть большим усилием.

Ну и напоследок посмотрим, как влияет на АЧХ включение системы активного шумоподавления. Влияние есть и довольно очевидное, но в целом ничего сверхстрашного не происходит. Несколько более выраженным становится акцент на НЧ-диапазоне, но тут самое время еще раз взглянуть на иллюстрацию выше… В общем, пользы от ANC явно больше, чем «побочных эффектов».

Как мы уже говорили, Huawei FreeBuds 4 обладает оптимизированным под повседневное прослушивание звуком с выраженным акцентом на низкочастотном диапазоне. Назвать его универсальным сложно, но своих поклонников он совершенно точно найдет.

Использование наушников для выполнения голосовых вызовов и получения сообщений

Функция

Жест управления

Ответ на вызов/завершение вызова

  • FreeBuds LipstickFreeBuds 4, FreeBuds 4i, FreeBuds 3i, FreeBuds 2 Pro, FreeBuds 2, FreeBuds Lite, FreeBuds, FlyPods 3, FlyPods Pro, FlyPods Lite: дважды коснитесь одного из наушников, чтобы ответить на вызов или завершить его
  • FreeBuds 3: дважды коснитесь одного из наушников, чтобы ответить на вызов. Дважды коснитесь правого наушника, чтобы завершить вызов
  • FreeBuds Pro: сожмите ножку одного из наушников, чтобы ответить на вызов или завершить его

Huawei - Building a Fully Connected, Intelligent WorldHuawei - Building a Fully Connected, Intelligent WorldHuawei - Building a Fully Connected, Intelligent World

Отклонение вызова

FreeBuds 4, FreeBuds Lipstick: коснитесь левого или правого наушника и не отпускайте палец

Использование наушников для прослушивания аудио и управления воспроизведением звука

Если на вашем устройстве воспроизводится аудио, при подключении наушников FreeBuds звук будет автоматически воспроизводиться через наушники. При снятии наушников FreeBuds воспроизведение аудио будет приостановлено. Если вы снова наденете наушники FreeBuds в течение 3 минут, воспроизведение аудио автоматически возобновится. Если вы снимете один из наушников, воспроизведение аудио будет приостановлено.

Переключение режима шумоподавления

Управление воспроизведением музыки

Функция

Жест управления

Воспроизведение и приостановка воспроизведения музыки

  • FreeBuds 4, FreeBuds Lipstick, FreeBuds 4i, FreeBuds 3i: дважды коснитесь левого или правого наушника
  • FreeBuds 3, FreeBuds 2, FreeBuds 2 Pro, FreeBuds, FlyPods, FlyPods Pro, FreeBuds Lite, FlyPods Lite: дважды коснитесь правого наушника, чтобы возобновить воспроизведение музыки или перейти к следующей композиции
  • FreeBuds Pro: сожмите ножку наушника один раз, чтобы приостановить или возобновить воспроизведение музыки, два раза, чтобы перейти к следующей композиции, или три раза, чтобы вернуться к предыдущей композиции

Настройка громкости

FreeBuds 4, FreeBuds Lipstick, FreeBuds Pro: проведите по ножке наушника вверх или вниз, чтобы увеличить или уменьшить громкость

Huawei - Building a Fully Connected, Intelligent WorldHuawei - Building a Fully Connected, Intelligent WorldHuawei - Building a Fully Connected, Intelligent World

Подключение

После открытия крышки кейса гарнитура некоторое время пытается подключиться к последнему использовавшемуся источнику, когда не получается — активирует режим сопряжения. Если это по каким-то причинам не произошло, можно воспользоваться кнопкой на боковой поверхности футляра.

Гаджеты с прошивкой EMUI последних версий автоматически «находят» и предлагают подключить FreeBuds 4. Обладателям же андроид-устройств с другими прошивками придется выполнить пару-тройку несложных операций. Естественно, наладить Bluetooth-подключение гарнитуры можно стандартным и привычным способом — через соответствующее меню гаджета.

Но лучше сразу воспользоваться программой Huawei AI Life, о которой мы уже неоднократно писали — она и в дальнейшем очень пригодится. Версия ПО в Google Play по-прежнему не самая новая, устанавливать AI Life лучше с сайта производителя, на страницу загрузки можно перейти с помощью QR-кода в инструкции.

Запустив AI Life, нажимаем на кнопку добавления устройства и проверяем, что крышка кейса открыта — подключение запущено. Далее ПО обнаруживает гарнитуру, отправляет запрос на сопряжение… Весь процесс занимает чуть больше минуты.

После успешного подключения можно изменить имя устройства, далее оно появляется в основном меню программы. После чего сразу происходит проверка наличия обновлений прошивки, если они имеются — приложение сразу предлагает их установить.

Процесс установки занял у нас порядка трех минут, но тут все зависит от скорости интернет-соединения и размеров пакета, конечно. В первый раз что-то пошло немного не так, приложение предложило отключить и подключить гарнитуру. К счастью, это не заняло много времени, а вторая попытка оказалась удачной. После установки обновления приложение предлагает открыть и закрыть чехол, еще раз переподключив тем самым гарнитуру.

Каждый из наушников может использоваться в монорежиме — достаточно убрать другой в кейс. Одновременная работа с несколькими устройствами поддерживается, причем в крайне интересном формате — об этом мы отдельно поговорим чуть ниже. После подключения к ПК мы традиционно получили список поддерживаемых кодеков и их режимов с помощью утилиты Bluetooth Tweaker.

Кодека вновь всего два — базовый SBC, плюс немного более «продвинутый» AAC. С одной стороны, для рассчитанной на повседневное использование гарнитуры этого достаточно. С другой — ну все же наушники явно ориентированы на работу с гаджетами под Android, aptX был бы вот совсем не лишним.

Проблема: «карта не работает»

Huawei - Building a Fully Connected, Intelligent World

Однажды нам сообщили о баге. Пользователь с устройством Huawei, находившийся в центре Москвы (Рис.3), открыл приложение, нажал на кнопку «Переместиться на своё местоположение», и его перенесло в пустоту (Рис.4). Пользователь не видит, ни улиц, ни зданий, и он решил, что карта не работает.

Мы попробовали воспроизвести у себя эту проблему. И действительно попадали в неопределённое пространство. Когда попробовали чуть-чуть уменьшить масштаб карты, то оказалось, что мы попали в пригород Мариуполя (Рис.5). То есть из московских координат (55.819207, 37.493424) перенеслись в мариупольские (47.187447, 37.593137).

Мы были в полном недоумении. Может быть, где-то у нас с числами что-то не то происходит. Возможно, происходят некие вычитания наших координат. Очень долго искали решение этой проблемы или хотя бы причину. Оказалось, что мы заменили импорты из Google-карт, и поэтому всё перестало работать. В конце концов мы добрались до padding’а.

Давайте быстро вспомним, что такое padding у карты. На (Рис.6) показан экран авторизации, карта занимает всю область экрана, даже под плашкой ручного ввода адреса. В таком случае, если мы не добавим padding карте, её центр будет находиться на месте зелёного треугольника, но мы хотим, чтобы он был в центре рабочей области карты.

Padding сужает рабочую область (Рис.7). Не видимую, а именно рабочую. Карта будет по-прежнему занимать весь экран, но размер её рабочей области изменится. И когда вы будете переходить в новую координату, она будет принимать положение новой рабочей карты. Как оказалось, баг был именно из-за этого.

Первое решение: убрать padding. Как вы понимаете, такой вариант нам не подошёл. Мы хотели, чтобы всё отображалось красиво.

Второе решение проблемы: использовать анимированное перемещение, но с масштабированием.

val zoom = map.cameraPosition.zoom
map.animateCamera(CameraUpdateFactory.newLatLngZoom(position, zoom))

При переходе с изменением масштаба карты всё работало правильно. Здорово! Мы подумали, что это нам подходит. На самом деле нет. У нас ещё есть третий экран, на котором нужно увеличивать карту относительно двух маркеров, чтобы

zoom

сам рассчитывался, поэтому мы не можем задать какое-то константное масштабирование. То есть такой вариант нам тоже не подошёл. Начали думать дальше и нашли новое решение.

Третье решение проблемы: вообще отказаться от анимации. Как оказалось, если вместо animateCamera сделать просто move, то перемещение будет происходить правильно. Так мы и сделали. Надеемся, в скором времени Huawei устранит эту проблему.

Реализация поддержки двух карт


Для поддержки нескольких карт необходимо создать обёртку для самих карт и для объекта.

Добавляем общий интерфейс, например, IMapWidget. Не забываем сделать общий класс для LatLng — список координат курьера. У Google он лежит в пакете com.google.android.gms.maps.model.LatLng, а у Huawei в com.huawei.hms.maps.model.LatLng. Кладём список в PolyLineOptions и задаём ширину и цвет линии маршрута.

interface IMapWidget {

    void animateCamera(...);

    void setListener(OnMapEventListener listener);

    void setMapPadding(...);

    MapMarker addMarker(...);

    ...
}

Добавляем Custom Map View реализующего интерфейс

IMapWidget

Добавляем обёртку, которая позволяет нам указать, где мы хотим отрисовывать карту:

class MapWrapper : FrameLayout() {

    fun setupMap(widget: IMapWidget) {
        removeAllViews()
        addView(widget as View)
    }
}


И в нужном месте вызываем метод добавления карты.

override fun onCreateView(...) {
    ...
    val map: IMapWidget = MapFactory.createMap()
    viewMapWrapper.setupMap(map)
    ...
}

Такие обёртки класса нужно создать для всего: объектов, маркеров,

PolyUtilPolyLine

и т.д.

Технические характеристики

Размер динамика∅14,3 мм
ПодключениеBluetooth 5.2, мультипойнт
Поддержка кодековSBC, AAC
Управлениесенсорные панели, датчики ношения
Активное шумоподавлениеесть, два режима
Заявленное время воспроизведениядо 2,5 часов (с шумоподавлением)
до 4 часов (без шумоподавления)
Емкость аккумулятора наушников30 мА·ч
Емкость аккумулятора кейса410 мА·ч
Время зарядки наушников≈1 час
Время зарядки чехла≈1 час
Способы зарядкиUSB Type C
Размеры наушников41,4×16,8×18,5 мм
Размеры кейса∅58 мм, высота 21,2 мм
Масса кейса38 г
Масса одного наушника4,1 г
Защита от воды и пылиIPX4
Рекомендуемая цена12 990 ₽ на момент тестирования

Упаковка и комплектация

Поставляются FreeBuds 4 в белой картонной коробке с традиционным дизайном для наушников Huawei: крупное изображение устройства, золотистые надписи — все на месте.

В комплект поставки входят сами наушники в кейсе для их хранения и переноски, зарядный кабель USB — USB Type C длиной 1 метр, плюс документация. Производитель обещает выпустить силиконовые кейсы разных цветов, которые можно будет докупить отдельно.

Управление и по

Управление гарнитурой осуществляется с помощью сенсорных панелей, расположенных на внешней стороне «ножек». Срабатывают они очень корректно, прекрасно реагируют на прикосновения, в том числе — многократные, а также на свайпы. Плюс воспроизведение ставится на паузу при снятии любого из наушников и возобновляется при его помещении обратно в ухо — ответственные за это инфракрасные датчики мы видели чуть выше.

Пользователи прошлых версий Huawei FreeBuds нередко жаловались, что система управления некорректно взаимодействует со смартфонами других производителей. Мы специально проверили работу тестируемых наушников с тремя различными андроид-устройствами под разными брендами — во всех случаях с управлением не было никаких проблем.

С профилем управления пользователю предлагается ознакомиться после привязки наушников к приложению. Сначала — попробовать поставить музыку на паузу одиночным тапом.

А потом — изменить громкость свайпами и включить шумоподавление долгим прикосновением. В общем, привыкнуть можно быстро, пользоваться удобно — с управлением все отлично.

Мы же вернемся на главный экран приложения. На нем можно посмотреть уровень зарядки каждого из наушников, а также кейса. Ниже находится так называемый «центр подключений», который является одной из самых интересных особенностей FreeBuds 4. В нем собраны все устройства, с которыми у гарнитуры налажено сопряжение, переключаться между ними можно одним нажатием, с двумя гарнитура может работать параллельно.

При этом наушники очень четко и без задержек переносят фокус на нужное устройство. Например, если вы слушаете музыку с ноутбука, а в процессе зазвонил телефон — гарнитура тут же переключится на него. Управлять списком устройств и автоподключением к ним можно на отдельной странице.

Ниже на главном экране находится панель управления звуком, где можно включить или выключить активное шумоподавление, а также выбрать один из двух режимов его работы. В меню «качество звука» также можно включить так называемые HD-вызовы — систему оптимизации голосовых вызовов, потенциально улучшающую качество передачи речи, но немного повышающую энергопотребление.

Часть жестов по сенсорным панелям можно настроить, в частности — обеспечить себе возможность быстрого вызова голосового ассистента. Есть и функция поиска наушников, при активации которой они начинают издавать довольно громкий сигнал — в тихом помещении он действительно может быть полезен. Ну и, наконец, функцию автопаузы при извлечении наушников из ушей при желании можно отключить.

Эксплуатация и шумоподавление

Посадка в ушах у большинства «вкладышей» удобная, но не самая надежная. В плане комфорта Huawei FreeBuds 4 — типичные представители своего класса, а вот их способность держаться в ухе приятно удивила. Конечно, чуда не произошло — хорошие внутриканальные решения имеют ощутимо более надежную посадку.

Однако мы попробовали бегать в FreeBuds 4, прыгать через скакалку, делать скручивания — во время всех этих занятий они оставались на месте. Начали выпадать они лишь при работе с грушей и выполнении активной части разминки, но на этом этапе подобным образом ведет себя большинство наушников.

Заявленный уровень влагозащиты — IPX4, то есть брызг воды устройство не боится. Плавать не стоит, в душ тоже нельзя, но от капель пота и легкого дождя гарнитура защищена. В общем, ее вполне можно рекомендовать не только для повседневного использования, но и для занятий спортом со средней интенсивностью.

За счет сравнительно крупной округлой части и заметно выступающего «носика» звуковода достигается не только надежная посадка, но и на удивление неплохой уровень пассивной звукоизоляции. Хотя тут все, конечно, зависит от выбранного пользователем положения наушников. В любом случае, сочетание активного и пассивного шумоподавления дает весьма ощутимый эффект.

Как и всегда, лучше всего ANC справляется с низкочастотными шумами. Так, например, система прекрасно подавляет гул кондиционера, а вот шелест воздушных потоков — уже хуже. В офисе вы будете избавлены от фонового низкочастотного звука улицы, а вот громкие разговоры коллег придется «перекрикивать» музыкой.

Ну и так далее — все как обычно. Но еще раз отметим, что эффективность «шумодава» оказалась неожиданно высокой для рассматриваемого форм-фактора. Конечно, с лучшими внутриканальными или полноразмерными решениями Huawei FreeBuds 4 сравнивать не стоит, но в своем классе они показали отличный результат.

Однако при длительном использовании гарнитуры с активным шумоподавлением может возникнуть неприятно чувство «давления в голове». И хорошо, что режима работы системы два — можно снизить ее эффективность, но повысить удобство использования. Где-нибудь в кафе, чтобы избавиться от равномерного «гула толпы» достаточно и режима «комфорт», а вот в общественном транспорте есть смысл переключиться на более «агрессивный» вариант.

Автопереключения, как у Freebuds Pro, тут нет, но для «середины линейки» наличие двух режимов – это уже хорошо. А вот чего действительно не хватает, так это функции «звукопроницаемости», позволяющей послушать объявление, пообщаться с кассиром или ответить на вопрос прохожего, не снимая наушников. Но опять-таки, что делать — если хочется получить совсем уж все «фишки», придется смотреть в сторону флагманских моделей.

Гарнитуры «с палочкой» традиционно лучше других полностью беспроводных решений справляются с передачей голоса — расположение микрофонов чуть ближе ко рту пользователя делает свое дело. Качество передачи голоса у гарнитуры FreeBuds 4 оказалось высоким — в ней можно без проблем вести долгие беседы, причем не только в тихом помещении, но и где-нибудь на улице.

Наши «тестовые собеседники» прекрасно все слышали и отмечали естественное звучание голоса даже в те моменты, когда разговор велся в шумной обстановке: возле дороги, в торговом центре или кафе… Режим «HD-вызовов» мы пробовали включать и выключать несколько раз — честно говоря, особой разницы ощутить так и не удалось, качество передачи речи было стабильно высоким вне зависимости от положения переключателя в приложении.

Этап 1: проверка наличия services


Если у вас в приложении при входе есть проверка наличия Google Services, то придётся от этого отказаться, и проверять наличие соответствующих сервисов только по мере необходимости.

Этап 2: карты

В приложении Delivery Club три основные страницы:

На устройствах Huawei все эти карты не работают. Чтобы это исправить, можно просто заменить зависимости: вместо пакета

com.google.android.gms

использовать

com.huawei.hms

Конечно, есть нюансы, но мы уже сделали большу́ю часть работы. Huawei сделала Maps SDK с контрактами, по большей части соответствующий Google Maps SDK. Однако у Google есть deprecated-методы, если вы их используете, то аналогов у Huawei может и не найтись. Например, для получения местоположения пользователя мы используем:

LocationServices.FusedLocationApi.getLastLocation(googleApiClien)

Такой подход считается deprecated, и если мы просто скопируем код для Huawei Maps и заменим зависимости, то работать не будет. Нужно поменять так:

LocationServices.getFusedLocationProviderClient(…)
.getLastLocation()
.addOnSuccessListener(…)

Этап 3: push-сервис

Идём дальше. На Huawei-устройства не приходят уведомления нашего приложения. Дело в том, что мы не можем получить токен. Давайте его получим. В Google мы получаем задачу и извлекаем токены так:

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val token = task.result
    }
}


Наше решение:

class ImplementationHuaweiMessagingService : HmsMessageService() {

    override fun onNewToken(token: String?) {
        val commonApi = getComponentFactory().get(CommonApi::class.java)
        commonApi.settingsManager().setPushToken(token)
    }

    override fun onMessageReceived(message: RemoteMessage?) {
        message?.let {
            val appManagersComponent = getComponentFactory().get(AppManagersApi::class.java)
            appManagersComponent.pushManager().handle(it.dataOfMap)
        }
    }

Выглядит всё так же, как и с реализацией

FirebaseMessagingService()

, даже есть

callbackonNewTokenonMessageReceived

. Однако без нюансов не обойтись. Случается, что на некоторых редких устройствах

onMessageReceived

вызывается в главном потоке, поэтому лучше не использовать здесь долго выполняющиеся задачи.

Получаем токены на Huawei:

val token = HmsInstanceId.getInstance(context)
    .getToken(appId, com.huawei.hms.push.HmsMessaging.DEFAULT_TOKEN_SCOPE)



public static final String DEFAULT_TOKEN_SCOPE = "HCM";

Обратите внимание, что метод выполняется в главном потоке. И для получения токена нужно отдельно реализовать поток. У Google такой подход уже считается устаревшим, возможно, Huawei придёт к тому же.

Мы можем вообще не использовать getToken, а прописать в манифесте автоматическую инициализацию или в коде методом setAutoInitEnabled() и всегда получать token в onNewToken (подробнее). Это решит ещё одну проблему: getToken в версиях EMUI ниже 10 вообще возвращает null.

Этап 4: chrome custom tabs


Наше приложение при запуске регулярно вылетает с ошибкой

ActivityNotFoundException

. Чтобы от этого избавиться, нужно обработать отсутствие Chrome Tabs.

fun Context.openLink(url: String, customTabsSession: CustomTabsSession? = null): Boolean {
    try {
        openLinkInCustomTab(url, customTabsSession)
        return true
    } catch (throwable: Throwable) {
        Timber.tag("Context::openLink").e(throwable, "CustomTabsIntent error on url: $url")
    }

    return openLinkInBrowser(url)
}

@Throws(Throwable::class)
fun Context.openLinkInCustomTab(url: String, customTabsSession: CustomTabsSession? = null) {
    CustomTabsIntent.Builder(customTabsSession)
        .build()
        .launchUrl(this, Uri.parse(url))
}

private fun Context.openLinkInBrowser(url: String): Boolean {
    val intent: Intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
        addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
    }

    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
        return true
    }

    return false
}

Мы просто обернули

openLinkInCustomTab()try catch

и в случае ошибки пытаемся открыть в браузере. Но бывает такого, чтобы на устройстве не было подходящего браузера, способного обработать наш неявный

intent

. Поэтому если метод

openLinkInBrowser()

возвращает

false

, мы открываем страницу в

webview

Этап 5: аналитика


Аналитика у Huawei похожа на Google Analytics. Покажу замену на примере Firebase. Сначала инициализируем:

HiAnalytics.getInstance(context)

. Затем с помощью

HAEventType.STARTCHECKOUT

копируем все наши события из Firebase в отдельный файл

huaweiAnalytics

huaweiAnalytics.onEvent(name, bundle)


Системные параметры:

HAParamType.PRICEHAParamType.CURRNAME

Даже если у вас нет Firebase, добавить аналитику в Huawei очень просто. У них отличная документация, контракт соблюдается. Также у Huawei есть отличные инструменты для исследования аудитории.

Этап 6: crashlytics

Следующий инструмент, который нам тоже стало интересно попробовать, это Crashlytics от Huawei, которая называется

AGConnectCrash

. Она позволяет с минимальными усилиями собирать и анализировать информацию о падении приложения.

Инициализируем crashlytics:

AGConnectCrash.getInstance().enableCrashCollection(true)

Добавляем свои ключи и журналируем нужные события:

Этап 7: покупки в приложении

Если в вашем приложении есть встроенные покупки, вы должны подписать согласие на передачу персональных данных, и отослать письмом в конверте или через курьера в московский офис Huawei. И только через пару дней они вам дадут доступ для реализации этой функциональности.

Всё очень похоже на реализацию Google. При запуске приложения запрашиваем все прошлые покупки пользователя:

fun getOwnedPurchases(
    activity: Activity,
    ownedPurchasesResultOnSuccessListener: OnSuccessListener<OwnedPurchasesResult>,
    failureListener: OnFailureListener
) {
    val ownedPurchasesReq = OwnedPurchasesReq()

    // priceType: 0: consumable; 1: non-consumable; 2: auto-renewable subscription
    ownedPurchasesReq.priceType = IapClient.PriceType.IN_APP_SUBSCRIPTION

    // To get the Activity instance that calls this API.
    val task: Task<OwnedPurchasesResult> = Iap.getIapClient(activity)
        .obtainOwnedPurchases(ownedPurchasesReq)

    task.addOnSuccessListener(ownedPurchasesResultOnSuccessListener)
        .addOnFailureListener(failureListener)
}

Если какой-то товар был куплен, мы разблокируем его функциональность. Потом запрашиваем подробности по товарам, доступным для продажи — цену и описание:

fun loadProduct(
    context: Context,
    productInfoResultOnSuccessListener: OnSuccessListener<ProductInfoResult>,
    onFailureListener: OnFailureListener
) {
    // obtain in-app product details configured in AppGallery Connect, and then show the products
    val iapClient: IapClient = Iap.getIapClient(context)
    val task: Task<ProductInfoResult> = iapClient.obtainProductInfo(createProductInfoReq())
    task.addOnSuccessListener(productInfoResultOnSuccessListener)
        .addOnFailureListener(onFailureListener)
}

private fun createProductInfoReq(): ProductInfoReq {
    val req = ProductInfoReq()
    // 0: consumable ; 1: non-consumable ; 2: auto-renewable subscription
    req.priceType = IapClient.PriceType.IN_APP_SUBSCRIPTION

    val productIds = ArrayList<String>()
    productIds.add("PRODUCT_ID")
    req.productIds = productIds
    return req
}

Когда пользователь кликает на товар, мы открываем страницу с оплатой. Она не такая красивая, как у Google, и не выезжает снизу.

fun gotoPay(activity: Activity, productId: String, type: Int) {
    val client: IapClient = Iap.getIapClient(activity)
    val task: Task<PurchaseIntentResult> = client.createPurchaseIntent(createPurchaseIntentReq(type, productId))
    task.addOnSuccessListener { result ->
        result?.let {
            val status: Status = result.status
            if (status.hasResolution()) {
                try {
                    status.startResolutionForResult(activity, PAY_RESULT_ARG)
                } catch (exception: SendIntentException) {
                    Timber.e(exception)
                }
            } else {
                Timber.d("intent is null")
            }
        }
    }.addOnFailureListener { exception ->
        Timber.e(exception)
    }
}


Так как это Activity, мы передаём ему аргумент, по которому можно отловить

OnActivityResult

и понять, успешно ли прошла оплата и как закончилась транзакция:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == PAY_RESULT_ARG) {
        val purchaseResultInfo: PurchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data)
        when (purchaseResultInfo.returnCode) {
            OrderStatusCode.ORDER_STATE_SUCCESS -> {
                successResult(purchaseResultInfo)
            }

            OrderStatusCode.ORDER_STATE_CANCEL -> {

            }

            OrderStatusCode.ORDER_PRODUCT_OWNED -> {

            }
        }
    }
}

У нас есть специальные статусы:

ORDER_SUCCESSCANCELOWNED

. Первый означает успешную оплату. Второй — пользователь просто закрыл страницу без покупки, тогда мы обрабатываем этот callback и предлагаем скидку, чтобы уговорить на покупку. А третий статус означает, что товар уже куплен пользователем. Если товар разовый или подписочный, то на этом моменте нужно остановиться, в противном случае виртуально доставить покупку.

В случае успешной оплаты доставляем пользователю купленный товар:

private fun successResult(purchaseResultInfo: PurchaseResultInfo) {
    val inAppPurchaseData = InAppPurchaseData(purchaseResultInfo.inAppPurchaseData)
    val req = ConsumeOwnedPurchaseReq()
    req.purchaseToken = inAppPurchaseData.purchaseToken

    val client: IapClient = Iap.getIapClient(this)
    val task: Task<ConsumeOwnedPurchaseResult> =
        client.consumeOwnedPurchase(req)

    task.addOnSuccessListener {
        // Consume success
    }.addOnFailureListener { exception ->
        Timber.e(exception)
    }
}

Если не сделать доставку, то функциональность товара будет у пользователя заблокирована, а деньги возвращены. В Google Play Billing Library до третьей версии этого делать не нужно было, но потом Google тоже это добавил, и если мы не доставим товар, через 48 часов покупка отменится, а деньги вернутся пользователю. То есть в Huawei покупки реализованы как в третьей версии Google Play Billing.

Выводы

На реализацию поддержки Huawei-устройств не уйдёт много времени. Даже без реальных устройств вы сможете проверить работоспособность вашего приложение: у Huawei есть своя тестовая лаборатория с виртуальными устройствами наподобие

. Количество пользователей быстро растёт, и бизнесу может оказаться выгодным вложиться в доработку продуктов, а отличная документация поможет разработчикам всё сделать быстро. Поддержка HMS активно отвечает на любые вопросы, если вы не сможете в документации что-то найти.

Видеозапись доклада с конференции Mobius 2020.

Итоги

Помимо пусть и довольно оригинального, но вполне интересного звука у Huawei FreeBuds 4 еще немало достоинств. Взять хотя бы очень удобно организованное взаимодействие с несколькими источниками — это один из лучших вариантов, что нам доводилось видеть.

Приложение в целом очень удобное, не хватает только полноценного эквалайзера, но можно воспользоваться сторонними решениями. Посадка комфортная и надежная, автономность пусть и не рекордная, но достаточная. В общем, очень добротная гарнитура, не самая дешевая, но все же стоящая ощутимо меньше флагманских моделей.

Оцените статью
Huawei Devices
Добавить комментарий