2015-12-07 5 views
2

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

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, у которого уже есть данные, хранящиеся в собственной базе данных. , например. How to use DataItem of Android Wear или Android Wear How Long do DataMap entries Stay Valid

Но когда я хочу, чтобы извлечь ранее синхронизированные данные в методе позже, я получаю только один элемент из 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, я всегда получаю только последний пункт. ..

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

UPDATE: Я заметил, что это имеет значение, если я использую разные 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 Как представляется неэффективным использованием сотен или тысяч путей, это вопрос о том, что DataItems может даже заменить SQLite БД или нет ...

Или есть способ иметь несколько DataItems под одним URI?

ответ

1

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

+0

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