Это моя вторая статья про разработку своего проекта. Тем, кто не читал предыдущая статейку: она про то, как из одного места (гугл таблицы) автоматически экспортировать данные в другое (ноушн).
Сегодня я расскажу, как я писал (и проектировал) библиотеку для того, чтобы сторонние приложения могли получать данные, отправляемые моим приложением. Всех заинтересовавшихся прошу под кат.
Часть 1. Проблема
Вкратце про проект. Есть устройство, которое подключается к смартфону. Есть мое приложение, внутри которого нейросеть распознает данные от устройства и выдает результат. И есть другие приложения, которые хотят получить этот самый результат.
Результат бывает нескольких видов: голые данные с устройства, обработанные данные с устройства, информация о состоянии устройства, информация о правах доступа приложения к данным (например, что пользователь отозвал права доступа к данным устройства). Нужно как-то передавать этот самый результат в другие приложения.
Если вдруг я что-то неправильно поясню по своему коду — вот тут документация к моей библиотеке.
Часть 2. Планируем решение
Есть замечательный механизм — Broadcast’ы. Если вкратце — это сообщение от одного приложения другим приложениям. Можно отправить сразу всем, а можно — какому-то определенному.
Чтобы это дело отправлять и принимать, нужно:
- Как-то сделать из передаваемого объекта JSON
- Отправить Broadcast
- Принять Broadcast в другом приложении
- Восстановить передаваемый объект из JSON
Вообще делать из объекта JSON — это не всегда корректно. Можно отправлять через Broadcast штуку, называемую Parcelable, а можно — Serializable. Serializable — это стандартная вещица из Java, Parcelable — аналогичная штука, но оптимизированная для мобильных устройств.
У меня объекты достаточно маленькие. Кроме того, зачастую надо получить именно JSON: я сам написал стороннее приложение, чтобы оно отправляло на сервер сырые данные. Поэтому я выбрал именно «сделать из передаваемого объекта JSON». Возможно, потом я передумаю.
Часть 3. Пилим решение
Пункт 1 и пункт 4. В JSON, а потом обратно
Тут все просто. Есть библиотека Gson, которая чудесно подходит для наших нужд.
Чтобы сделать все круто, переопределим метод toString(). Ну и сделать fromString(), чтобы получить обратно наш объект.
class SecureData(val eeg1: Double?, val eeg2: Double?, date: Date) { override fun toString(): String { val gson = Gson() return gson.toJson(this) } companion object { fun fromString(model: String): SecureData { val gson = Gson() return gson.fromJson(model, SecureData::class.java) } } }
Пункт 2. Посылаем объект
Вот пример такого кода:
val intent = Intent() intent.action = BroadcastUtils.BROADCAST_GESTURE intent.putExtra(BroadcastUtils.EXTRA_GESTRE, it.toString()) sendBroadcast(intent)
Тут мы создаем intent, задаем его действие, кладем объект и отправляем как broadcast.
BroadcastUtils.BROADCAST_GESTURE — это штучка, по которой мы будем фильтровать поступающие broadcast’ы в другом приложении (нужно ли обрабатывать это или не нужно).
Чтобы отправить сообщение конкретному приложению, нужно еще дополнительно задать следующее:
intent.component = ComponentName( PermissionsFetcher.REFACE_APP, "${PermissionsFetcher.REFACE_APP}.receivers.ActionsReceiver" )
PermissionsFetcher.REFACE_APP — это APPLICATION_ID моего приложения, а ${PermissionsFetcher.REFACE_APP}.receivers.ActionsReceiver — путь до ресивера.
Пункт 3. Получаем объекты
Вот так мы регистрируем ресивер. Если вы регистрируете его, используя контекст приложения — он будет получать broadcast’ы, пока приложение не закрыто. Если используете контекст активити — пока она не закроется.
registerReceiver(GesturesReceiver(), IntentFilter(BroadcastUtils.BROADCAST_GESTURE))
А вот GesutesReceiver:
class GesturesReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Timber.i("Received gesture") val action = BroadcastUtils.reparseGestureIntent(intent) MainApp.actionSubject.onNext(action) } }
Тут я, как видите, получил интент, переделал его обратно в объект и отправил куда-то-там с помощью RxJava.
Часть 4. Заключение
Вы прочитали статью по проектированию приложений, которые должны взаимодействовать с другими приложениями. Надеюсь, этот опыт вам чем-то поможет.
Для пущего эффекта можно посмотреть исходники моей библиотеки и пример работы с ней и поставить звездочку на случай, если вам когда-нибудь это пригодится: github.com/reface-tech/CodeSpecialApp
ссылка на оригинал статьи https://habr.com/ru/post/467205/
Добавить комментарий