Android синхронизирует базу данных с носимыми устройствами — DataMapItems перезаписываются

Я пытаюсь синхронизировать данные из базы данных SQLite на портативном устройстве с носимым устройством. Поэтому я использую Data API со следующим кодом на КПК:

cursor.moveToFirst();
while (!cursor.isAfterLast()) {
    final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE");
    putRequest.setUrgent();
    final DataMap map = putRequest.getDataMap();
    int i = 0;
    for (String columnName: cursor.getColumnNames()) {
        map.putString(columnName,cursor.getString(i));
        i++;
    }
    Wearable.DataApi.putDataItem(googleApiClient, putRequest
            .asPutDataRequest()).setResultCallback(new ResultCallback() {
                @Override
                public void onResult(Result result) {
                    if (!result.getStatus().isSuccess()) {
                        Log.v("MainActivity", "data could not be sent");
                    } else {
                        Log.v("MainActivity", "data sent");
                    }
                }
    });
    cursor.moveToNext();
}
cursor.close();

Затем на носимых устройствах у меня есть DataApi.DataListener для поиска изменений:

@Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
    for (DataEvent event : dataEventBuffer) {
        String data = null;
        try {
            data = new String(event.getDataItem().getData(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Log.v(TAG, "onDataChanged data: "+ data);

        if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/SAMPLE")) {

            DataMapItem item = DataMapItem.fromDataItem(event.getDataItem());
            String column1_value = item.getDataMap().getString(column1);

            Log.v(TAG, "onDataChanged column1: "+ column1_value);
        }
    }
}

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

Теперь я прочитал, что нет необходимости копировать данные в новую базу данных SQLite на носимом устройстве, а вместо этого использовать непосредственно DataItembuffer, данные которого уже хранятся в собственной базе данных. например Как использовать DataItem из Android Wear или Android Wear Как долго записи DataMap остаются в силе

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

public void getDataItems(){
    final PendingResult<DataItemBuffer> results = Wearable.DataApi.getDataItems(googleApiClient);

    Runnable r = new Runnable() {
        @Override
        public void run() {
            DataItemBuffer dataItems = results.await();
            for (int i = 0; i < dataItems.getCount(); i++) {
                DataMapItem item = DataMapItem.fromDataItem(dataItems.get(i));

                String column1_value = item.getDataMap().getString(column1);
                Log.v(TAG, "getDataItems column1: "+ column1_value);
            }
        }
    };
    Thread thread = new Thread(r);
    thread.start();

    /*
    results.setResultCallback(new ResultCallback<DataItemBuffer>() {
        @Override
        public void onResult(DataItemBuffer dataItems) {
            Log.v(TAG, "dataItems length: "+ dataItems.getCount());
            for (int i = 0; i < dataItems.getCount(); i++) {

                DataMapItem item = DataMapItem.fromDataItem(dataItems.get(i));
                String column1_value = item.getDataMap().getString(column1);
                Log.v(TAG, "getDataItems column1: "+ column1_value);
            }
            dataItems.release();
        }
    });*/
}

Очевидно, нет никакой разницы между использованием await() и ResultCallback, я всегда получаю только последний элемент...

Что я здесь делаю неправильно?

ОБНОВЛЕНИЕ: я заметил, что это имеет значение, если я использую разные URI. Если я использую

final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE1");

и

final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE2");

затем я получаю в методе getDataItems как минимум два элемента, но все же только последний для каждого URI. В соответствии с Документами каждый DataItem идентифицируется одним URI, состоящим обычно из идентификатора узла и пути. https://developers.google.com/android/reference/com/google/android/gms/wearable/DataItem Поскольку использование сотен или тысяч путей кажется неэффективным, возникает вопрос, могут ли DataItem даже заменить базу данных SQLite или нет...

Или есть способ иметь несколько элементов данных под одним URI?


person Chris    schedule 07.12.2015    source источник


Ответы (1)


Если вы используете один и тот же «путь» для нескольких элементов данных, вы эффективно обновляете данные каждый раз, когда добавляете новый с этими путями, что объясняет, почему вы получаете только «последнее» обновление; если вы хотите иметь доступ и извлекать все по отдельности, вам нужно использовать разные пути или использовать разные структуры данных (скажем, массив) для каждого пути. Несмотря на это, использование хранилища данных, предоставляемого DataApi, в качестве замены базы данных sqlite не рекомендуется; хранилище DataLayer разработано с учетом другого набора целей, поэтому, если вы действительно хотите хранить данные на другом конце для выполнения запросов и т. д., вам лучше извлечь их из хранилища данных и поместить в свое собственное sqlite для той цели, которую вы имеете в виду (и удаляйте элементы из хранилища данных по мере их обработки).

person Ali Naddaf    schedule 07.12.2015
comment
Спасибо за ответ. Что ж, мне не нужно задавать вопросы о носимых устройствах, так как это уже произошло на портативных устройствах. Данные нужно просто хранить и сохранять на носимых устройствах, поэтому, возможно, было бы интересно избежать там SQLite. Но вы, безусловно, правы, использование для каждого элемента собственного пути кажется громоздким способом, и тогда, вероятно, лучше подходит db. Я подумаю об использовании массива в DataItem. Я где-то читал, что это может быть до 100 КБ, что на самом деле было бы не так уж плохо ... - person Chris; 07.12.2015