Благодаря официальному мобильному приложению Pebble отлично справляются с информированием о состоянии вашего смартфона — показывают входящие сообщения, информацию о вызовах и прочие уведомления. Но что делать, если такая нужная «мелочь», как например состояние батареи смартфона, количество непрочитанных SMS и e-mail, недоступна для использования в своих приложениях на часах? Вариант, реализовать это самому.
И так, о том как использовать PebbleKit Android для интеграции Pebble и Android-приложения на примере уведомления о количестве пропущенных вызовов: немного кода, перевод выдержек из документации [1] и совсем мало картинок.
Тезисно, как работает взаимодействие мобильного приложения и watchappp:
Для решения поставленной задачи, вывода уведомления на часах о количестве пропущенных вызовов, необходимо:
В Pebble-приложении, точно так же как и в случае с PebbleKit JS, используется механизм AppMessage API [3].
Так как наше приложении само не инициирует сеанс связи, а только ждет сообщение со стороны смартфона, я буду использовать Synchronizing App UI [4] — вспомогательный слой поверх AppMessage, который упрощает синхронизацию значений между watchapp и мобильным устройством. Используется только два обратных вызова, один из которых в случае когда изменяется предопределенное значение, и другой, если происходит ошибка.
Определяем ключ, AppSync и буфер для синхронизации кортежа:
Инициализацию механизама синхронизации и начального значения кортежа вынесем в отдельную функцию:
Определяем обратные вызовы:
N.B. В данном случае, ключ используемый для обмена значением не требует регистрации в appinfo.json.
Если сейчас запустить наше простое приложение, то на экране будет одинокий индикатор (0 пропущенных вызовов):
Получить количество пропущенных вызовов в Android можно разными способами, в данном примере я буду брать её из «шторки» с уведомлениями — Notification Area.
Само приложение состоит из двух классов: MainActivity для ввода UUID watchapp'а которое будет принимать данные и сервиса NotificationListener, который отслеживает уведомления.
N.B. Доступ к Notification Area через NotificationListenerService появился в Android 4.3. Так как используются дополнительные метаданные Notification.extras, пример будет гарантировано работать только на Android 4.4+.
Для Android Studio добавление PebbleKit осуществляется через gradle-файл.
Добавляем в app/build.gradle:
После синхронизации PebbleKit можно использовать в своем проекте.
Для доступа к уведомлениям использую класс NotificationListener, унаследованный от NotificationListenerService с переопределенными методами onNotificationPosted() и onNotificationRemoved():
При добавлении или удалении уведомления, просматриваются все активные и если присутствует информация о пропущенных вызовах, количество их посылается в приложение на часах:
Для отправки данных на часы определяем ключ, UUID, формируем словарь и используем метод sendDataToPebble:
Для предоставления приложению прав доступа к уведомлениям необходимо добавить в манифест:
Замечание, после установки приложения необходимо разрешить сервис, без авторизаци работать не будет. Настройка находится по пути «Settings» -> «Security» -> «Notification access». В русской локали у меня «Настройки» -> «Конфиденциальность» -> «Доступ к уведомлениям».
Запускаем android-приложение, указываем в нем UUID Pebble-приложения, звоним и не отвечаем, смотрим как меняется уведомление на часах:
Исходники:
notice watchapp — pbw
PebbleNotify (проект Android Studio) — apk
1. Pebble Developers // Mobile App Developer Guide
2. Pebble Developers // Dictionary
3. Pebble Developers // App Communication
4. Pebble Developers // Synchronizing App UI
И так, о том как использовать PebbleKit Android для интеграции Pebble и Android-приложения на примере уведомления о количестве пропущенных вызовов: немного кода, перевод выдержек из документации [1] и совсем мало картинок.
Тезисно, как работает взаимодействие мобильного приложения и watchappp:
- приложение-компаньон распознает, соединяется и обменивается информацией с Pebble через библиотеку PebbleKit;
- watchapp (watchface) и мобильное приложение обмениваются сообщениями в двустороннем режиме, идентификация канала с обоих сторон осуществляется по UUID приложения Pebble;
- обмен между Pebble-приложением и мобильным приложением осуществляется объектами Dictionary [2].
Для решения поставленной задачи, вывода уведомления на часах о количестве пропущенных вызовов, необходимо:
- Pebble-приложение, которое умеет получать, обрабатывать и отображать информацию из приложения-компаньона;
- Android-приложение, которое отслеживает вызовы и отсылает количество неотвеченных в наше приложение на часах.
Watchapp
В Pebble-приложении, точно так же как и в случае с PebbleKit JS, используется механизм AppMessage API [3].
Так как наше приложении само не инициирует сеанс связи, а только ждет сообщение со стороны смартфона, я буду использовать Synchronizing App UI [4] — вспомогательный слой поверх AppMessage, который упрощает синхронизацию значений между watchapp и мобильным устройством. Используется только два обратных вызова, один из которых в случае когда изменяется предопределенное значение, и другой, если происходит ошибка.
Определяем ключ, AppSync и буфер для синхронизации кортежа:
#define KEY_CALLS_COUNT 41
static AppSync s_sync;
static uint8_t s_sync_buffer[32];
Инициализацию механизама синхронизации и начального значения кортежа вынесем в отдельную функцию:
/* ... */
static void start_sync() {
app_message_open(app_message_inbox_size_maximum(),
app_message_outbox_size_maximum());
// Начальная инициализация кортежа (0 неотвеченных)
Tuplet initial_values[] = {
TupletInteger(KEY_CALLS_COUNT, 0),
};
app_sync_init(&s_sync, s_sync_buffer, sizeof(s_sync_buffer),
initial_values, ARRAY_LENGTH(initial_values),
sync_changed_handler, sync_error_handler, NULL);
}
static void init(void) {
/* ... */
start_sync();
}
Определяем обратные вызовы:
/* ... */
static char s_count_buffer[4];
/* ... */
static void sync_changed_handler(const uint32_t key, const Tuple *new_tuple,
const Tuple *old_tuple, void *context) {
// Преобразовываем полученное значение в строку
snprintf(s_count_buffer, sizeof(s_count_buffer),
"%d", (int)new_tuple->value->int32);
// Помечаем слой с индикатором для перерисовки
layer_mark_dirty(layer);
}
static void sync_error_handler(DictionaryResult dict_error,
AppMessageResult app_message_error,
void *context) {
APP_LOG(APP_LOG_LEVEL_ERROR, "sync error!");
}
/* ... */
N.B. В данном случае, ключ используемый для обмена значением не требует регистрации в appinfo.json.
Если сейчас запустить наше простое приложение, то на экране будет одинокий индикатор (0 пропущенных вызовов):
Android-приложение
Получить количество пропущенных вызовов в Android можно разными способами, в данном примере я буду брать её из «шторки» с уведомлениями — Notification Area.
Само приложение состоит из двух классов: MainActivity для ввода UUID watchapp'а которое будет принимать данные и сервиса NotificationListener, который отслеживает уведомления.
N.B. Доступ к Notification Area через NotificationListenerService появился в Android 4.3. Так как используются дополнительные метаданные Notification.extras, пример будет гарантировано работать только на Android 4.4+.
Для Android Studio добавление PebbleKit осуществляется через gradle-файл.
Добавляем в app/build.gradle:
dependencies {
compile 'com.getpebble:pebblekit:2.6.0'
}
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/groups/public/" }
}
После синхронизации PebbleKit можно использовать в своем проекте.
Для доступа к уведомлениям использую класс NotificationListener, унаследованный от NotificationListenerService с переопределенными методами onNotificationPosted() и onNotificationRemoved():
public class NotificationListener extends
NotificationListenerService {
@Override
public void onNotificationPosted(
StatusBarNotification sbn) {
this.getMissedCalls();
}
@Override
public void onNotificationRemoved(
StatusBarNotification sbn) {
this.getMissedCalls();
}
}
При добавлении или удалении уведомления, просматриваются все активные и если присутствует информация о пропущенных вызовах, количество их посылается в приложение на часах:
public class NotificationListener extends
NotificationListenerService {
// Счетчик пропущенных вызовов
int missedCallsCount = 0;
/*...*/
void getMissedCalls() {
int tCount = 0;
for (StatusBarNotification notif :
this.getActiveNotifications()) {
if (notif.getPackageName().equals("com.android.phone")) {
String extras_text = notif.getNotification().extras.getString(Notification.EXTRA_TEXT);
if (extras_text.indexOf("Пропущенных вызовов:") != -1) {
tCount = Integer.parseInt(extras_text.split(":")[1].trim());
}
}
}
if (tCount != missedCallsCount) {
missedCallsCount = tCount;
this.sendMissedCalls(missedCallsCount);
}
}
}
Для отправки данных на часы определяем ключ, UUID, формируем словарь и используем метод sendDataToPebble:
public class NotificationListener extends
NotificationListenerService {
UUID APPS_UUID;
private static final int CALLS_KEY = 41;
/*...*/
public void sendMissedCalls(int missedCalls) {
APPS_UUID = UUID.fromString(this.getUUID());
PebbleDictionary data = new PebbleDictionary();
data.addUint32(CALLS_KEY, missedCalls);
PebbleKit.sendDataToPebble(getApplicationContext(), APPS_UUID, data);
}
/*...*/
}
Для предоставления приложению прав доступа к уведомлениям необходимо добавить в манифест:
<service android:name=".NotificationListener"
android:label="@string/app_name"
android:permission=
"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name=
"android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Замечание, после установки приложения необходимо разрешить сервис, без авторизаци работать не будет. Настройка находится по пути «Settings» -> «Security» -> «Notification access». В русской локали у меня «Настройки» -> «Конфиденциальность» -> «Доступ к уведомлениям».
Запускаем android-приложение, указываем в нем UUID Pebble-приложения, звоним и не отвечаем, смотрим как меняется уведомление на часах:
Исходники:
notice watchapp — pbw
PebbleNotify (проект Android Studio) — apk
1. Pebble Developers // Mobile App Developer Guide
2. Pebble Developers // Dictionary
3. Pebble Developers // App Communication
4. Pebble Developers // Synchronizing App UI