是否可以从不是它的所有者的Android设备读取记录?

时间:2014-11-01 18:15:23

标签: java android dropbox-api

我正在开发一款应该能够在多个设备之间同步数据存储的应用。

我无法弄清楚为什么我无法从不是数据存储区所有者的设备读取记录。而数据存储区的所有者设备可以读取同一记录。我必须确切地说,数据存储区是使用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();
        }
    }
}

更新

我想对我的问题进一步解释。我采用一个实际案例来描述我的应用程序应该如何工作:

  • 用户从他的设备中打开应用
    • 他连接到Dropbox API(他用&#34; APP_KEY和APP_SERVICE&#34连接;),
    • 他在Dropbox应用程序中创建了一个数据存储区,
    • 然后他创建记录(其中一个包含字段,名为&#34; titre&#34; ),
  • B用户从其他设备打开应用

    • 他连接到相同的Dropbox API(他用同一对&#34; APP_KEY和APP_SERVICE&#34连接;),
    • 感谢收听者,他的应用程序正在同步在屏幕上显示 A用户创建的新数据存储区(我确定听众的工作是因为我通过Toast [参见代码])观看数据存储区的ID,

      • 问题: 数据存储区永远不会显示,因为该字段名为&#34; titre&#34;在侦听器内部未找到(请参阅代码内容)。

在调试模式下,我可以看到代码跳过此部分代码(见下文)。有记录,其中一个包含&#34; titre&#34;字段!

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

我希望我的详细信息会更加清晰,不要犹豫,向我提供更多信息。谢谢你能帮助我!

PS:还有一个细节,用户必须使用相同的邮件和密码连接到Dropbox才能共享其数据存储。否则他们无法共享他们的数据存储(尽管如此,这是我所理解的)。我在这里犯了错误吗?。

1 个答案:

答案 0 :(得分:5)

我没有完全遵循你在这里尝试做的事情,但有些建议:

  • 如果同一用户登录到这两个设备,则无需设置该角色。您是每台设备的所有者。只需给网络同步时间。

  • 一般情况下,另一台设备必须等待一段时间才能在数据存储列表中显示;然后你打开它,然后你必须再次等待,直到内容出现。

使用听众是观察这些事件的好方法。

更新:我认为你几乎就在那里。它预计在数据存储区出现在列表中之后,当您打开它时,它是空的。打开它的行为使图书馆开始在后台下载内容。下载完成后(有时仅部分完成)将再次调用您的监听器。因此,如果听众没有找到预期的&#34;滴度&#34;那么你的听众应该放弃。记录和以后的电话会找到它。

更新太多:如果您希望不同的用户(使用不同的Dropbox帐户)共享数据存储区,则必须设置公共角色,但您还必须执行其他操作:所有者(数据存储区的创建者必须以某种方式将数据存储区的数据存储区ID传输给其他用户,并且(这是重要的部分!)他们的应用程序实例必须使用该ID调用openDatastore()。在用户调用openDatastore()之前,数据存储区不会在该用户的listDatastores()中显示。

祝你好运!