Курсовая работа: Разработка мобильного приложения для наблюдения за состоянием здоровья

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

· onConnectionStateChange(…) - вызывается при изменении состояния подключения

В данной работе наиболее важным сервисом является «Heart Rate Monitor».

У этого сервиса имеется набор характеристик:

· Heart Rate Measurement

· Heart Rate Measurement Client Characteristic

· Body Sensor Location

· Heart Rate Control Point

Таким образом, изменяя значение характеристики «Heart Rate Control Point», можно остановить или начать измерять пульс.

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

new byte[] {0x15, 0x01, 0x00}

А для включения

new byte[] {0x15, 0x01, 0x01}

Данная информация не предоставляется производителями фитнес-браслетов, следует отметить, что подобной информации нету в официальной документации. Понять какую именно последовательность байт необходимо отправить помог анализ Bluetooth логов при взаимодействии приложения разработанного производителем и самим браслетом. Анализ проводился с помощью программного обеспечения Wireshark.

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

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

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

Было решено объединить запросы в пределах одной операции и назвать Transaction. Для формирования транзакции используется паттерн проектирования, известный как Builder (Строитель).

Пример составления транзакции, описанной выше:

stopHRmanual = new byte[] {0x15, 0x02, 0x00};

stopHRcontinuous = new byte[] {0x15, 0x01, 0x00};

startHRcontinuous = new byte[] {0x15, 0x01, 0x01};

TransactionBuilder builder = new TransactionBuilder(); builder.write (getCharacteristic(UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHRmanual); builder.write (getCharacteristic(UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHRcontinuous); builder.write (getCharacteristic(UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), startHRcontinuous);

builder.queue(mQueue);

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

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

Когда сработает один из методов BluetoothGattCallback, который относится к изменению / чтению характеристик, происходит проверка, совпадает ли характеристика из callback'а с той, что находится в режиме ожидания и успешно ли она была изменена / прочитана. Если да, то объект, задерживающий поток выполнения очереди, «просыпается» с помощью вызова метода countDown(), и переходит к следующему запросу или транзакции если запрос был последним. Если же статус выполнения какого-либо запроса возвращается с ошибкой или же соединение с устройством было потеряно, то транзакция прерывается.

3.3 Работа с базой данных

В качестве хранилища данных используется БД ObjectBox.

Так как это NoSql база данных, то как таковой схемы нету.

Разработчики ObjectBox предоставляют библиотеку для работы с ней. Чтобы сохранить объект в БД достаточно обозначить ключевые аннотации в классе, экземпляром которого является данный объект:

· @Entity - объявляет класс сущностью, предоставляет возможность сохранять объекты в базе данных

· @Id - обозначает какое поле будет являться уникальным идентификатором объекта

Подобная концепция называется ORM (object-relational mapping), когда между кодом приложения и базой данных существует ещё один уровень в виде сущностей, которые могут быть использованы, как и самим приложением, так и драйвером БД.

Соответственно в коде класс User выглядит следующим образом:

@Entity

public class User {

@Id

private long id;

private String name;

private Integer age;

private Double weight;

private Double height;

 // getters

 // setters

}

Все поля класса User являются «простыми», то есть драйвер БД ObjectBox может самостоятельно работать с таким типом данных. Ситуация обстоит по-другому с сущностью Activity, некоторые поля которой являются не простые типы:

@Convert (converter = Converters. LocalTimeConverter.class, dbType = String.class)

private LocalTime time;

@Convert (converter = Converters. PolylineConverter.class, dbType = String.class)

private List<LatLng> polyline;

@Convert (converter = Converters. ListIntegerConverter.class, dbType = String.class)

private List<Integer> heartRate;

Таким образом для подобных типов необходимо реализовывать конвертеры в тот тип данных, с которым БД драйвер умеет работать. Конвертер для листа точек с координатами в класс String и наоборот:

public static class PolylineConverter implements PropertyConverter<List<LatLng>, String> {

@Override

public List<LatLng> convertToEntityProperty (String databaseValue) {

if (StringUtils.isEmpty(databaseValue))

return Collections.emptyList();

String preResult = StringUtils.deleteWhitespace (databaseValue.substring (1, databaseValue.length() - 1));

return Stream.of (preResult.split(»)»))

filter (StringUtils:isNotEmpty)

map (s -> s.substring(1))

map (s -> {

String[] pair = s.split(»,»);

return new LatLng (Float.valueOf (pair[0]), Float.valueOf (pair[1]));

})

collect (Collectors.toList());

}

@Override

public String convertToDatabaseValue (List<LatLng> entityProperty) {

return entityProperty.stream()

map (latLng -> «[» + String.valueOf (latLng.latitude) +»,» + String.valueOf (latLng.longitude) +»]»)

collect (Collectors.toList())

toString();

}

}

Работа с базой данных сводится к простым и понятным операциям, таким как

User user = new User («User Name»);

user.setAge(30);

long id = box.put(user); // Сохранить в БД

User user = box.get(id); // Прочитать

box.remove(user); // Удалить

3.4 Работа с GPS

Весь оставшийся функционал, а именно:

· измерение скорости;

· измерение пройденной дистанции;

· определение маршрута;

· определение высоты над уровнем моря;

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

Так же реализован слушатель сообщений от GPS модуля по стандарту NMEA 0183. Получение подобных сообщений способствует обработке новой информации. Таким образом, в соответствии со стандартом[7], можно получить высоту над уровнем моря.

3.5 Обработка измерений

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

ЧСС можно разделить на пять диапазонов[5], границы которых зависят от максимальной ЧСС.

ЧССмакс = 220 - возраст

Выделяют следующие диапазоны:

Интенсивность

Процент от ЧССмакс

Примерная продолжительность (мин)

Очень низкая

50 - 60%

20 - 40

Низкая

60 - 70%

40 - 80

Средняя

70 - 80%

10 - 40

Выше среднего

80 - 90%

2 - 10

Максимум

90 - 100%

< 5

На основании приведенной таблицы, реализована обработка ЧСС.

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

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

3.6 Разработка интерфейса

Google maps

Фрагмент для мониторинга активности представляет из себя Scroll View, для просмотра все информации на одной страницы, включая фрагмент Google Maps для отображения маршрута. Для корректной навигации по карте (при перемещении по карте вверх Scroll View не должен проматываться), необходимо переопределить методы фрагмента SupportMapFragment. Для этого создан класс CustomMapFragment extends SupportMapFragment и переопределен метод, отвечающий за отправку действия при прикосновении к экрану. В данном методе у родителя (Scroll View) отменяется перехват обработки Touch event, то есть при прикосновении к карте будет вызывать обработчик карты, а не Scroll View как это реализовано по умолчанию.

Дизайн приложения

Дизайн приложения разрабатывался с учетом Material Design. На сайте[7] представлено множество обучающих статей как для отдельных элементов на экране, так и для целого макета страницы. В данной работе используются такие компоненты как:

· TextInputEditText (Рис. 8)

Настройки пользователя

ListView (Рис. 9-10)

Список устройств

История заездов

TableLayout (Рис. 11)

Мониторинг активности

Для отображения частоты сердечных сокращений используется график, реализованный с помощью библиотеки MPAndroidChart[8] (Рис. 12). Который изменяется в режиме реального времени во время мониторинга.

График сердечного пульса

Помимо описанных компонентов, Material Design так же предусматривает использование специальных иконок. Для облегчения поиска и добавления иконок в проект использовался плагин для Android Studio под названием Android Material Design Icon Generator (Рис. 13).

Android Material Design Icon Generator

С помощью которого можно сгенерировать Material icons (Рис. 14).

Material Icons

Логотип приложения сгенерирован с помощью онлайн ресурса cooltext.com[9] (Рис. 15)

Логотип приложения

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

Заключение

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

На основе анализа существующий решений и анализа архитектуры операционной системы Android и технологии Bluetooth Low Energy, были выявлены и в дальнейшем реализованы основные функциональные требования к приложению:

· Отслеживание активности катания на лыжах:

o максимальную и среднюю скорость;

o пройденную дистанцию;

o затраченное время;

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

o измерение пульса.

· Поддержка фитнес-браслетов разных производителей.

· Предоставление пользователю рекомендаций по выполнению физических упражнений (катание на лыжах).

Приложение разработано в интегрированной среде Android Studio на языке Java. Для хранилища данных используется NoSQL база данных ObjectBox. Взаимодействие с устройствами реализовано с помощью стандартных сервисов для работы с Bluetooth устройствами. Интерфейс приложения спроектирован с учетом Material Design.

Приложение реализовано в соответствии с формированными функциональными требованиями.

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

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

Список использованных источников

приложение интерфейс мобильный

1. ObjectBox: ObjectBox for mobile. Available at: https://objectbox.io/mobile

2. Bluetooth. Available at: https://www.bluetooth.com

3. Android Developers: Bluetooth low energy overview. Available at: https://developer.android.com/guide/topics/connectivity/bluetooth-le#java

4. Statista (2018) Global market share held by the leading smartphone operating systems in sales to end users from 1st quarter 2009 to 2nd quarter 2018. Available at: https://www.statista.com/statistics/266136/global-market-share-held-by-smartphone-operating-systems/