Синхронизируйте элементы данных с API уровня данных.

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

  • Полезная нагрузка: массив байтов, который вы можете установить с данными, что позволяет вам выполнять собственную сериализацию и десериализацию объектов. Размер полезной нагрузки ограничен 100 КБ.
  • Путь: уникальная строка, которая должна начинаться с косой черты, например "/path/to/data" .

Примечание. API уровня данных может отправлять сообщения и синхронизировать данные только с телефонами Android или часами с ОС Wear. Если ваше устройство Wear OS сопряжено с устройством iOS, API уровня данных не будет работать.

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

Обычно вы не реализуете DataItem напрямую. Вместо этого вы делаете следующее:

  1. Создайте объект PutDataRequest , указав строковый путь для уникальной идентификации элемента.
  2. Вызовите setData() чтобы установить полезную нагрузку.
  3. Если задержка синхронизации может отрицательно повлиять на взаимодействие с пользователем, вызовите setUrgent() .
  4. Используйте метод putDataItem класса DataClient , чтобы запросить систему создать элемент данных.

При запросе элементов данных система возвращает объекты, которые правильно реализуют интерфейс DataItem . Однако вместо работы с необработанными байтами с помощью setData() мы рекомендуем вам использовать карту данных , которая предоставляет элемент данных с интерфейсом, подобным Bundle .

Дополнительные сведения см. в примере приложения DataLayer .

Синхронизировать данные с картой данных

По возможности используйте класс DataMap . Этот подход позволяет вам работать с элементами данных в форме Android Bundle , поэтому система выполняет за вас сериализацию и десериализацию объектов, а вы можете манипулировать данными с помощью пар ключ-значение.

Чтобы использовать карту данных:

  1. Создайте объект PutDataMapRequest , задав путь к элементу данных.

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

  2. Вызовите PutDataMapRequest.getDataMap() , чтобы получить карту данных, для которой вы можете установить значения.
  3. Установите значения для карты данных с помощью методов put...() , таких как putString() .
  4. Если задержка синхронизации может негативно повлиять на взаимодействие с пользователем, вызовите setUrgent() .
  5. Вызовите PutDataMapRequest.asPutDataRequest() чтобы получить объект PutDataRequest .
  6. Используйте метод putDataItem класса DataClient , чтобы запросить систему создать элемент данных.

    Примечание. Если телефонная трубка и носимые устройства отключены, данные помещаются в буфер и синхронизируются при восстановлении соединения.

Метод increaseCounter() в следующем примере показывает, как создать карту данных и поместить в нее данные:

Котлин

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity() {

    private lateinit var dataClient: DataClient
    private var count = 0
    ...
    // Create a data map and put data in it
    private fun increaseCounter() {
        val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run {
            dataMap.putInt(COUNT_KEY, count++)
            asPutDataRequest()
        }
        val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)
    }
    ...
}

Ява

public class MainActivity extends Activity {
    private static final String COUNT_KEY = "com.example.key.count";
    private DataClient dataClient;
    private int count = 0;
    ...
    // Create a data map and put data in it
    private void increaseCounter() {
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
        Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq);
    }
  ...
}

Дополнительную информацию об обработке Tasks смотрите в справочной документации .

Установить приоритет DataItem

API DataClient позволяет выполнять срочные запросы на синхронизацию объектов DataItem . Обычно система задерживает доставку элементов данных в сеть Wear OS, чтобы увеличить время автономной работы пользовательских устройств, но если задержка синхронизации элементов данных отрицательно влияет на работу пользователей, вы можете пометить их как срочные. Например, в приложении удаленного управления, где пользователь ожидает, что его действия будут отражены немедленно, вы можете заставить систему немедленно синхронизировать ваши элементы данных, вызвав setUrgent() .

Если вы не вызовете setUrgent() , система может задержать синхронизацию несрочных элементов данных до 30 минут, хотя обычно вы можете ожидать, что задержка составит всего несколько минут. Срочность по умолчанию не является срочной, поэтому вам необходимо использовать setUrgent() если вам нужно сохранить поведение немедленной синхронизации из предыдущих версий API Wear OS.

Прослушивание событий элемента данных

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

Фрагмент кода в следующем примере уведомляет приложение об изменении значения счетчика, определенного в предыдущем примере:

Котлин

private const val COUNT_KEY = "com.example.key.count"

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    private var count = 0

    override fun onResume() {
        super.onResume()
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        super.onPause()
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            // DataItem changed
            if (event.type == DataEvent.TYPE_CHANGED) {
                event.dataItem.also { item ->
                    if (item.uri.path.compareTo("/count") == 0) {
                        DataMapItem.fromDataItem(item).dataMap.apply {
                            updateCount(getInt(COUNT_KEY))
                        }
                    }
                }
            } else if (event.type == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private fun updateCount(int: Int) { ... }
    ...
}

Ява

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {
    private static final String COUNT_KEY = "com.example.key.count";
    private int count = 0;

    @Override
    protected void onResume() {
        super.onResume();
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // DataItem changed
                DataItem item = event.getDataItem();
                if (item.getUri().getPath().compareTo("/count") == 0) {
                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                    updateCount(dataMap.getInt(COUNT_KEY));
                }
            } else if (event.getType() == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    // Method to update the count
    private void updateCount(int c) { ... }
    ...
}

Это действие реализует интерфейс DataClient.OnDataChangedListener . Действие добавляет себя в качестве прослушивателя событий элемента данных внутри метода onResume() и удаляет прослушиватель в методе onPause() . Чтобы увидеть реализацию с использованием изображений, моделей представлений и сервисов, см. пример приложения DataLayer .

Вы также можете реализовать прослушиватель как сервис. Дополнительные сведения см. в разделе Прослушивание событий уровня данных .