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