Burcu Dogan编写了一些示例代码,展示了如何将本地首选项文件同步到用户的google drive appfolder,可在此处找到:https://github.com/googledrive/appdatapreferences-android
我已将此示例转换为使用当前的drive sdk,现在随google play服务一起提供。
如果我用设备1更新云驱动器文件,然后在设备2上运行以下代码,我将从元数据中获取过时的“修改”时间戳。我假设这是因为结果来自驱动器文件的本地缓存:
第一步。使用查询按名称查找首选项文件:

    /**
     * Retrieves the preferences file from the appdata folder.
     * @return Retrieved preferences file or {@code null}.
     * @throws IOException
     */
    public DriveFile getPreferencesFile() throws IOException
    {
        if (mDriveFile != null)
            return mDriveFile;

        GoogleApiClient googleApiClient = getGoogleApiClient();

        if (!googleApiClient.isConnected())
            LOGW(TAG, "getPreferencesFile -- Google API not connected");
        else
            LOGD(TAG, "getPreferencesFile -- Google API CONNECTED");

        Query query = new Query.Builder()
                .addFilter(Filters.contains(SearchableField.TITLE, FILE_NAME))
                .build();

        DriveApi.MetadataBufferResult metadataBufferResult =
                Drive.DriveApi.query(getGoogleApiClient(), query).await();

        if (!metadataBufferResult.getStatus().isSuccess()) {
            LOGE(TAG, "Problem while retrieving files");
            return null;
        }

        MetadataBuffer buffer = metadataBufferResult.getMetadataBuffer();

        LOGD(TAG, "Preference files found on Drive: " +
                buffer.getCount());

        if (buffer.getCount() == 0)
        {
            // return null to indicate the preference file doesn't exist
            mDriveFile = null;

            // create a new preferences file
//            mDriveFile = insertPreferencesFile("{}");
        }
        else
            mDriveFile = Drive.DriveApi.getFile(
                    getGoogleApiClient(),
                    buffer.get(0).getDriveId());

        // Release the metadata buffer
        buffer.release();

        return mDriveFile;
    }

第二步。获取文件的元数据:
// Get the metadata
DriveFile file;
DriveResource.MetadataResult result = file.getMetadata(getGoogleApiClient()).await();
Metadata metadata = result.getMetadata();
// Get the modified dates
metadata.getModifiedDate();

更奇怪的是,在运行下面的代码(只列出appdatafolder文件及其内容)之后,上面获取的元数据修改日期就变得正确了!!为什么???
/**
 *
 * Simple debug activity that lists all files currently in Drive AppFolder and their contents
 *
 */
public class ActivityViewFilesInAppFolder extends BaseActivity {

    private static final String TAG = "ActivityViewFilesInAppFolder";

    private TextView mLogArea;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Add a text view to the window
        ScrollView layout = new ScrollView(this);
        setContentView(layout);

        mLogArea = new TextView(this);

        layout.addView(mLogArea);

        ApiClientAsyncTask<Void, Void, String> task = new ApiClientAsyncTask<Void, Void, String>(this) {
            @Override
            protected String doInBackgroundConnected(Void[] params) {
                StringBuffer result = new StringBuffer();

                MetadataBuffer buffer = Drive.DriveApi.getAppFolder(getGoogleApiClient())
                        .listChildren(getGoogleApiClient()).await().getMetadataBuffer();

                result.append("found " + buffer.getCount() + " files:\n");

                for (Metadata m: buffer) {
                    DriveId id = m.getDriveId();
                    DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), id);

                    DriveContents contents = file.open( getGoogleApiClient(),
                            DriveFile.MODE_READ_ONLY, null).await().getDriveContents();

                    FileInputStream is = new FileInputStream(contents.getParcelFileDescriptor()
                            .getFileDescriptor());
                    try {
                        BufferedReader bf = new BufferedReader(new InputStreamReader(is, Charsets.UTF_8));
                        String line=null; StringBuffer sb=new StringBuffer();
                        while ((line=bf.readLine()) != null ) {
                            sb.append(line);
                        }
                        contents.discard(getGoogleApiClient());
                        result.append("*** " + m.getTitle() + "/" + id + "/"
                                + m.getFileSize() + "B:\n   [" + sb.toString() + "]\n\n");
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
                buffer.release();
                return result.toString();
            }

            @Override
            protected void onPostExecute(String s) {
                if (mLogArea != null) {
                    mLogArea.append(s);

                    Map<String, ?> values = PreferenceManager
                            .getDefaultSharedPreferences(ActivityViewFilesInAppFolder.this).getAll();
                    String localJson = new GsonBuilder().create().toJson(values);

                    LOGD(TAG, "Local: " + localJson);
                    LOGD(TAG, "File:  " + s);
                }
            }
        };
        task.execute();
    }
}

元数据是从缓存的本地副本读取的吗,除非有什么东西踢它?
有人知道如何强制这些api总是从远程驱动器文件中提取结果吗?

最佳答案

我有你问题的答案。很好的回答,我相信你不会满意的。
在切换到RESTful API之前,我在我的应用程序中使用了GDAA。在我做了之后,我意识到gdaa,另一个我无法控制的延迟层,在一个试图保持多个android设备同步的应用程序中造成了问题。请参阅so22980497223820992251502823073474和grep以获取“请求同步”。
我希望gdaa实现某种gcm逻辑来同步“幕后”。尤其是当“addChangeListener()”方法似乎是为此而设计的时候。看起来并非如此(至少在2014年9月左右)。因此,我放弃了使用restful api与google drive对话的真实且经过测试的方案,该方案背后有dataprovider和syncadapter逻辑(非常像UDACITY Class here中所示)。
我不高兴的是,gdaa的文档有点模棱两可,使用了诸如“synchronize”之类的术语,但没有告诉我们它是否是“network”同步的“local”。不回答像上面提到的SO 23073474这样的问题。
看起来(我不是谷歌内部人士),gdaa是为那些不能在设备之间立即同步的应用而设计的。不幸的是,这并没有被提及,herehere - see 1:59,耗费了我很多时间和挫败感。
现在的问题是:我(我们)应该等到我们从gdaa获得“实时”同步,还是继续在restful dataprovider syncadapter之上开发基于gcm的本地同步?
好吧,我个人将开始研究gcm同步,并将维护一个易于使用的迷你应用程序,随着新版google play服务的推出,它将测试gdaa的行为。我会在github中准备好“测试迷你应用程序”后立即更新此答案。对不起,我没有帮你解决这个问题。

08-26 21:08