Можно ли прочитать запись с устройства Android, которое не является ее владельцем?

Я разрабатываю приложение, которое должно иметь возможность синхронизировать хранилища данных между несколькими устройствами.

Я не могу понять, почему я не могу прочитать запись с устройства, которое не является владельцем хранилища данных. Принимая во внимание, что устройство-владелец хранилища данных может прочитать эту же запись. Я должен уточнить, что хранилище данных было создано с разрешением РЕДАКТОРА (см. ниже).

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,
    • Затем он создает записи (одна из них содержит поле с названием "титр"),
  • Пользователь B открывает приложение с другого устройства,

    • He connects to the same dropbox API (He's connecting with the same couple of "APP_KEY and APP_SERVICE"),
    • Благодаря слушателю его приложение синхронизируется, чтобы отобразить на его экране новое хранилище данных, созданное пользователем A (я уверен, что прослушиватель выполняет свою работу, потому что я смотрю идентификаторы хранилища данных благодаря 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).

В режиме отладки я вижу, что код пропускает эту часть кода (см. ниже). А ведь есть записи, в одной из которых есть поле "титр"!

while (mRecord.hasNext()){ 
...

Я надеюсь, что мои детали будут яснее, не стесняйтесь спрашивать меня о дополнительной информации. Спасибо, если вы можете мне помочь!

PS: еще одна деталь: пользователи должны подключаться к Dropbox с той же почтой и паролем, чтобы делиться своими хранилищами данных. В противном случае они не могут делиться своими хранилищами данных (тем не менее, это то, что я понял). Я делаю ошибку здесь?


person FrancNovation    schedule 01.11.2014    source источник
comment
В ответ на P.S.: Нет, пользователям не нужно (и не следует) делиться именем пользователя и паролем для совместного использования хранилищ данных. Эта строка: datastoreTitle.setRole(DbxPrincipal.PUBLIC, DbxDatastore.Role.EDITOR); устанавливает разрешения для этого хранилища данных таким образом, что любой пользователь Dropbox, у которого есть идентификатор хранилища данных для этого хранилища данных, может редактировать его. Они могут и должны делать это, используя свои собственные учетные записи, в которые они вошли со своими именами пользователей и паролями.   -  person Greg    schedule 03.11.2014


Ответы (1)


Я не полностью следую тому, что вы пытаетесь здесь сделать, но некоторые предложения:

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

  • Как правило, другому устройству придется подождать определенное время, прежде чем оно появится в вашем списке хранилищ данных; затем вы открываете его, а затем снова должны ждать, пока содержимое не появится.

Использование слушателей — хороший способ следить за этими событиями.

ОБНОВЛЕНИЕ: я думаю, вы почти у цели. Ожидается, что сразу после того, как хранилище данных появится в списке, при его открытии оно будет пустым. Акт его открытия заставляет библиотеку начать загрузку содержимого в фоновом режиме. Когда эта загрузка будет завершена (а иногда и только частично), ваш слушатель будет вызван снова. Таким образом, ваш слушатель должен просто сдаться, если он не находит ожидаемую запись «титров», а более поздний вызов найдет ее.

ТАКЖЕ ОБНОВЛЕНИЕ: если вы хотите, чтобы разные пользователи (использующие разные учетные записи Dropbox) совместно использовали хранилище данных, вам нужно установить общедоступную роль, но вы также должны сделать что-то еще: владелец (создатель) хранилище данных должно каким-то образом передать идентификатор хранилища данных другим пользователям, и (это важная часть!) их экземпляр приложения должен вызвать openDatastore() с этим идентификатором. Пока пользователь не вызовет openDatastore(), это хранилище данных не будет отображаться в списке этого пользователя listDatastores().

Удачи!

person Guido van Rossum    schedule 02.11.2014
comment
Извините, если я не ясен. Я хочу, чтобы разные пользователи могли подключаться к одному приложению, созданному на платформе разработчика Dropbox (на вкладке App Console). Я собираюсь обновить свой вопрос, чтобы прояснить мою проблему (я также обновляю код, потому что на самом деле этот код вызывается слушателем). Спасибо за вашу помощь! - person FrancNovation; 03.11.2014