
Щороку наше життя та повсякденність стають дедалі більше пов'язаними з мобільними телефонами. Сучасне життя є надзвичайно динамічним, і саме тому мобільні додатки повинні відповідати активності користувачів. Awareness API існує саме для цієї мети.
Що таке API у розробці додатків і як це може допомогти?
Google Awareness API дозволяє нам моніторити активність користувача, це можливо як в певний момент, так і під час роботи додатка.
API дозволяє отримувати дані про:
- Стан навушників (підключені/відключені);
- Місцезнаходження;
- Активність (стоїть, їде, біжить, йде);
- Час (місцевий час користувача для встановлення певних рамок);
- Реакцію на маяки.
Існує безліч ситуацій, в яких ці функції можуть бути використані. Якщо це спортивний додаток для бігу, наприклад, можна дізнатися, коли користувач розпочав своє тренування, а якщо це ресторанний додаток, є можливість сповістити користувача про спеціальні пропозиції або запросити його відвідати ресторан, коли він буде неподалік.
Awareness API поділяється на дві частини, а саме:
- Snapshot API — дозволяє отримувати актуальну інформацію в певний момент
- Fence API — реєструє один або кілька тригерів, які повідомляють нам, чи активний користувач зараз чи ні.
Щоб краще зрозуміти це, будь ласка, знайдіть приклад коду додатку тут: https://github.com/stfalcon-studio/GoogleAwarenessDemo.
Для початку нам потрібно отримати API-ключ, ось чудовий посібник від Google - https://developers.google.com/awareness/android-api/get-a-key.
Як тільки ми отримали ключ, ми повинні додати його до файлу маніфесту вашого проекту. Це виглядає так:
<application><meta-data android:name="com.google.android.awareness.API_KEY" android:value="YOUR_API_KEY"></meta-data></application>
Тепер вам лише потрібно додати залежність до gradle:
implementation 'com.google.android.gms:play-services-awareness:{last_version}'
Не забудьте про дозволи, ви повинні додати наступні до маніфесту для цієї мети:
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"></uses-permission><uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"></uses-permission>
*Не забудьте також про перевірку дозволів у додатку.
Ось і все, тепер ви можете повною мірою використовувати можливості Awareness API.
Snapshot API
Як вже згадувалося, Snapshot API інформує про актуальний статус.
Спочатку потрібно ініціалізувати SnapshotClient.
al snapshotClient = Awareness.getSnapshotClient(this)
Тепер ми можемо отримати дані про активність користувача в даний момент.
Навушники
За допомогою Snapshot API ми можемо дізнатися про поточний стан навушників, підключені вони чи ні. Це буде корисно для розробки спортивних додатків, наприклад, щоб сповістити користувача про досягнення його цілей, якщо навушники підключені.
Щоб дізнатися стан навушників, потрібно просто викликати функцію `getHeadphoneState()`, а для отримання результату додати `addOnSuccessListener`, який поверне нам `HeadphoneStateResponse` з `headphoneState`. Далі `getState` поверне нам «1» або «2», що відповідає статусу `PLUGGED_IN` або `UNPLUGGED`.
Також доцільно додати `addOnFailureListener`, який поверне `Exception`, якщо щось піде не так.
Приклад:
private fun snapshotCheckHeadphones(){ snapshotClient.headphoneState .addOnSuccessListener { snapshotHeadphonesContainer.text = it.headphoneState.toString(this)}.addOnFailureListener { handleSnapshotError(snapshotHeadphonesContainer, it)}}
`toString` - це розширювальна функція для спрощення коду.
fun HeadphoneState.toString(context: Context): String {return context.getString( R.string.headphones_state,if(state == HeadphoneState.PLUGGED_IN){ context.getString(R.string.headphones_state_connect)}else{ context.getString( R.string.headphones_state_disconnected )})}
Локація
За допомогою Snapshot API ми також можемо дізнатися про поточну локацію користувача.
Прикладів використання безліч, наприклад, якщо додаток має список певних місць, ми можемо запропонувати користувачу відвідати те чи інше місце, якщо його це цікавить і він знаходиться неподалік.
Щоб отримати локацію, потрібно викликати `getLocation()`, в `OnSuccess` ми отримаємо `LocationResponse`, який містить інформацію про місцезнаходження користувача. Ми можемо отримати інформацію з `getLocation()`, яка містить широту, довготу, висоту тощо.
Приклад:
private fun snapshotGetLocation(){ snapshotClient.location .addOnSuccessListener { with(it.location){ snapshotLocationContainer.text = getString( R.string.user_location, latitude, longitude, altitude, accuracy )}}.addOnFailureListener { handleSnapshotError(snapshotLocationContainer, it)}}
`Location` - це стандартний клас Android SDK, тому ви можете ознайомитися з документацією для детального опису всіх доступних функцій.
Примітка: не забувайте додати `android permission ACCESS_FINE_LOCATION` до маніфесту, а також дозволи для перевірки.
Активність користувача
Як вже згадувалося, Awareness API також дозволяє перевіряти поточну активність користувача. Це може бути надзвичайно корисно в розробці фітнес-додатків або деяких додатків з новинами. Коли користувач не рухається, йому можна запропонувати прочитати якусь статтю.
Підхід до реалізації залишається тим самим: нам потрібно викликати функцію `getDetectedActivity`, яка у випадку успіху поверне нам `DetectedActivityResponse`. З неї ми можемо отримати дані про активність користувача. У нас є такі доступні функції: `getMostProbableActivity`, яка повертає найбільш ймовірну активність, та `getProbableActivities`, яка повертає список можливих активностей, відсортований за найбільш ймовірною.
Активність має два параметри, а саме:
- Тип активності — ми використовуємо `getType()`, щоб отримати тип активності, приклад буде нижче.
- Ймовірність активності — яка отримується за допомогою функції `getConfidence()` — вона поверне ціле значення від 0 до 100.
Приклад:
snapshotClient.detectedActivity .addOnSuccessListener { with(it.activityRecognitionResult){ snapshotActivityContainer.text = getString( R.string.user_activity, mostProbableActivity.stateString(), mostProbableActivity.confidence )}}.addOnFailureListener { handleSnapshotError(snapshotActivityContainer, it)}
`stateString` - це функція розширення, яка повертає текстове значення типу активності.
fun DetectedActivity.stateString(): String {return when (type){0->"IN_VEHICLE"1->"ON_BICYCLE"2->"ON_FOOT"3->"STILL"4->"UNKNOWN"5->"TILTING"6,9,10,11,12,13,14,15-> type.toString()7->"WALKING"8->"RUNNING"16->"IN_ROAD_VEHICLE"17->"IN_RAIL_VEHICLE"18->"IN_TWO_WHEELER_VEHICLE"19->"IN_FOUR_WHEELER_VEHICLE"else-> type.toString()}}
Fence API
Awareness API дозволяє встановлювати певні умови та «слухати», коли активність користувачів збігається з ними.
Ми можемо перевіряти:
- Локацію користувача та перевіряти, чи ввійшов він у певну зону.
- Активність користувача, коли він або вона, наприклад, почав/продовжує/зупинився йти, бігти, їхати тощо.
- Стан навушників, коли їх підключено або відключено.
- Коли користувач увійшов у зону роботи маяків.
- Часові рамки, коли користувач перебуває в певному часовому проміжку певного дня тижня.
Ми також можемо комбінувати кілька функцій, використовуючи оператори AND, OR або NOT. Наприклад, ми можемо перевіряти наступне:
- Користувач бігає з підключеними навушниками.
- Користувач їде і ввійшов у певну зону.
- Навушники підключені ввечері, без активності (отже, користувач, ймовірно, у ліжку).
Як почати використовувати Fence.
По-перше, щоб отримати інформацію про зміну стану fence, ми повинні створити свій власний BroadcastReceiver.
Ось так, наприклад:
inner class FenceReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent){ val fenceState = FenceState.extract(intent)if(fenceState.fenceKey == FENCE_KEY){ when (fenceState.currentState){ FenceState.TRUE->{// Ми увійшли в зону} FenceState.FALSE->{// Ми не в зоні} FenceState.UNKNOWN ->{// Щось пішло не так}}}}}
Він отримуватиме всі зміни, що стосуються наших зареєстрованих зон. Наприклад, ми чекаємо, поки користувач підключить навушники:
- Перевіряємо, чи збігається FENCE_KEY, який надійшов, з тим, що ми зареєстрували (що це таке і звідки воно, ми побачимо нижче).
- Потім перевіряємо стан: якщо TRUE, то навушники підключені; якщо FALSE, то навпаки, а стан UNKNOWN означає, що сталася помилка, і система не може зрозуміти статус навушників.
Примітка: не забувайте зареєструвати FenceReceiver в `onCreate`
registerReceiver(fenceReceiver, IntentFilter(FENCE_RECEIVER_ACTION))
І відключити його в `onDestroy`:
unregisterReceiver(fenceReceiver)
Щоб система надсилала нам зміни, ми повинні створити PendingIntent.
val intent = Intent(FENCE_RECEIVER_ACTION) val mPendingIntent = PendingIntent.getBroadcast(this,0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
Тепер ми повинні визначити, яка активність нас цікавить. Візьмемо, наприклад, підключені навушники та активність "біг".
val fence = AwarenessFence.and(HeadphoneFence.during(HeadphoneState.PLUGGED_IN), DetectedActivityFence.during(DetectedActivityFence.RUNNING))
Тепер ми збираємо все разом і реєструємо.
fenceClient.updateFences( FenceUpdateRequest.Builder().addFence( FENCE_KEY, fence, mPendingIntent ).build()).addOnSuccessListener {// Зону створено}.addOnFailureListener {// Помилка під час створення}
FENCE_KEY необхідний для того, щоб розрізняти різні зареєстровані зони.
Вам також не слід забувати про видалення зони, коли ви закінчили з нею працювати. Для цього ми використовуємо `removeFence()`, де необхідний FENCE_KEY передається як параметр.
fenceClient.updateFences( FenceUpdateRequest.Builder().removeFence(FENCE_KEY).build())
*якщо потрібно, ви також можете додати successListener і failureListener для видалення.
Тепер, знаючи, як створювати та видаляти зону, ми можемо розглянути, які типи зон існують.
Зона навушників
З навушниками все аналогічно, і ми маємо наступні зони:
- AwarenessFence headphonesPluggedInFence = HeadphoneFence.during(HeadphoneState.PLUGGED_IN;
- AwarenessFence headphonesUnpluggedFence = HeadphoneFence.during(HeadphoneState.UNPLUGGED;
Зона місцезнаходження
Ми можемо створювати так звані «локації», і щойно користувач їх введе, ми дізнаємося про це. Ми можемо перевірити, чи він увійшов/вийшов з певної зони або перебуває в ній.
Вам потрібно вказати дані про широту, довготу та радіус локації (для перевірки, чи користувач перебуває в зоні, також слід вказати, скільки мілісекунд користувач має залишатися в ній).
AwarenessFence inLocationFence = LocationFence.in( latitude, longitude, radius, timeInMillis); AwarenessFence exitingLocationFence = LocationFence.exiting( latitude, longitude, radius); AwarenessFence enteringLocationFence = LocationFence.entering( latitude, longitude, radius);
Активність Fence
Ми також можемо дізнатися, коли користувач почав, продовжує або закінчив певну активність. Клас `DetectedActivityFence` використовується для цієї мети, він має функції `starting`, `during` та `stopping`. Тип активності додається до цих функцій як параметр. Давайте, наприклад, створимо фences для всіх станів бігу:
AwarenessFence running = DetectedActivityFence.during(DetectedActivity.RUNNING); AwarenessFence startRunning = DetectedActivityFence.starting(DetectedActivity.RUNNING); AwarenessFence stopRunning = DetectedActivityFence.stopping(DetectedActivity.RUNNING);
Час Fence
Ми можемо створити fence для певного проміжку часу або певного дня.
AwarenessFence workingHoursFence = TimeFence.inInterval(startTime, endTime); AwarenessFence fridayFence = TimeFence.inFridayInterval( timeZone, startTime, endTime);
Це все.
Ми ознайомилися з тим, що таке API та як використовувати Fences і Snapshots. Завдяки їм ми можемо створювати більш гнучкі застосунки, які полегшують користування додатком.