Разработвам приложение, което трябва да може да синхронизира хранилища за данни между няколко устройства.
Не мога да разбера защо не мога да прочета запис от устройство, което не е собственик на хранилището за данни. Докато устройството на собственика на хранилището за данни може да чете същия този запис. Трябва да уточня, че хранилището за данни е създадено с разрешение EDITOR (вижте по-долу).
try {
datastoreTitle = mDatastoreManager.createDatastore();
datastoreTitle.setRole(DbxPrincipal.PUBLIC, DbxDatastore.Role.EDITOR);
} catch (DbxException e) {
e.printStackTrace();
}
Някой сблъсквал ли се е със същия проблем? Кодът, повдигащ този проблем, е по-долу:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**
* Opening of the database
*/
db = new SQliteHelper( this ) ;
/**
* Connection to dropbox API
*/
mAccountManager = DbxAccountManager.getInstance(getApplicationContext(), APP_KEY, APP_SECRET);
// Set up the datastore manager
if (mAccountManager.hasLinkedAccount()) {
try {
// Use Dropbox datastores
mDatastoreManager = DbxDatastoreManager.forAccount(mAccountManager.getLinkedAccount());
} catch (DbxException.Unauthorized e) {
System.out.println("Account was unlinked remotely");
}
}
if (mDatastoreManager == null) {
// Account isn't linked yet, use local datastores
mDatastoreManager = DbxDatastoreManager.localManager(mAccountManager);
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Connection à Dropbox");
alert.setMessage("L'initialisation de l'application sert à vous synchroniser avec l'espace de données partagées.\r\n"
+ "Souhaitez-vous synchroniser votre application?");
alert.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mAccountManager.startLink((Activity)MainActivity.this, REQUEST_LINK_TO_DBX);
}
});
alert.setNegativeButton("Non", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Intent returnIntent = new Intent();
setResult(RESULT_CANCELED, returnIntent);
finish();
}
});
alert.show();
}
/**
* Listener
*/
mDatastoreManager.addListListener(new DbxDatastoreManager.ListListener() {
@Override
public void onDatastoreListChange(DbxDatastoreManager dbxDatastoreManager) {
List<TitleList> listInBDD = db.getTitleSQliteHelper();
Set<DbxDatastoreInfo> datastorePresent = null;
try {
datastorePresent = mDatastoreManager.listDatastores();
} catch (DbxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Iterator<DbxDatastoreInfo> mdbxDatastoreInfoIterator = datastorePresent.iterator() ;
while (mdbxDatastoreInfoIterator.hasNext()){
DbxDatastoreInfo mdbxDatastoreInfo = mdbxDatastoreInfoIterator.next();
boolean find = false ;
Log.d("Test 1 - delete Datastore => mdbxDatastoreInfo.id :" , mdbxDatastoreInfo.id ) ;
for (TitleList titleFound : listInBDD){
if (titleFound.idDbx.equals(mdbxDatastoreInfo.id)){
Log.d("Test 2 - delete Datastore => TitleList :" , titleFound.nom.toString() ) ;
find = true ;
}
}
/**
* Problem comes below
*/
if ( !find ){
Log.d("Delete absent datastore inside of the BDD : " , mdbxDatastoreInfo.id ) ;
try {
DbxDatastore dbxStore = mDatastoreManager.openDatastore(mdbxDatastoreInfo.id);
// Toast to check that the datastores have been found
Toast.makeText(MainActivity.this, dbxStore.getId(), Toast.LENGTH_LONG).show();
DbxTable tab = dbxStore.getTable("table_de_courses"); // All is fine up to here, "tab" seems empty for a device which is not the owner of the database
QueryResult mResults = tab.query();
Iterator<DbxRecord> mRecord = mResults.iterator();
// When the device is not the owner of the database, the code stops at this while condition
while (mRecord.hasNext()){
DbxRecord tmpRecord = mRecord.next();
Set<String> fieldList = tmpRecord.fieldNames();
Iterator<String> fieldNameList = fieldList.iterator();
while (fieldNameList.hasNext()){
String str = fieldNameList.next();
if ( str.equalsIgnoreCase("titre") ){
TitleList tit = new TitleList(tab.get("titre").getString("titre"));
tit.setConnectDropbox();
tit.setIdDbx(mdbxDatastoreInfo.id);
db.addLists(tit);
}
}
}
} catch (DbxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
АКТУАЛИЗАЦИЯ
Искам да дам допълнително обяснение по моя проблем. Взимам практичен случай, за да опиша как трябва да работи приложението ми:
- A user opens the app from his device
- He connects to the dropbox API (He's connecting with an "APP_KEY and APP_SERVICE"),
- Той създава хранилище за данни вътре в приложението dropbox,
- И след това той създава записи (като един от тях съдържа поле, наречено "titre"),
Потребител B отваря приложението от друго устройство,
- He connects to the same dropbox API (He's connecting with the same couple of "APP_KEY and APP_SERVICE"),
Благодарение на слушателя приложението му се синхронизира, за да покаже на екрана му новото хранилище за данни, създадено от Потребител (сигурен съм, че слушателят върши работата си, защото гледам идентификаторите на хранилището благодарение на Toast [вижте кода]),
- Problem: the datastore will never be displayed because the field called "titre" is not found out inside of the listener (see the code content).
В режим на отстраняване на грешки виждам как кодът пропуска тази част от кода (вижте по-долу). Докато има записи, като един от тях съдържа полето "titre"!
while (mRecord.hasNext()){
...
Надявам се данните ми да са по-ясни, не се колебайте да ме попитате за допълнителна информация. Благодаря ако можете да ми помогнете!
PS: още една подробност, потребителите трябва да се свържат с dropbox с една и съща поща и парола, за да споделят своите хранилища за данни. В противен случай те не могат да споделят своите хранилища за данни (въпреки това е, което разбрах). Правя ли грешка тук?