问题是在新创建的文件(“DriveFolder.createFile(GAC,meta,cont)”的产品)上,“DriveId.getResourceId()”中的“resourceID”不可用(返回NULL)。如果通过常规列表或查询过程检索到文件,则“resourceID”正确。
我怀疑这是时间/延迟问题,但尚不清楚是否存在会强制刷新的应用程序操作。 “Drive.DriveApi.requestSync(GAC)”似乎无效。
最佳答案
更新(07/22/2015)
感谢Steven Bazyl的迅速响应(请参阅下面的评论),我终于有了使用Completion Events的令人满意的解决方案。这是两个缩小的代码段,它们将新创建的文件传播到驱动器后立即将ResourceId传递给应用程序:
创建文件,添加更改订阅:
public class CreateEmptyFileActivity extends BaseDemoActivity {
private static final String TAG = "_X_";
@Override
public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint);
MetadataChangeSet meta = new MetadataChangeSet.Builder()
.setTitle("EmptyFile.txt").setMimeType("text/plain")
.build();
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), meta, null,
new ExecutionOptions.Builder()
.setNotifyOnCompletion(true)
.build()
)
.setResultCallback(new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (result.getStatus().isSuccess()) {
DriveId driveId = result.getDriveFile().getDriveId();
Log.d(TAG, "Created a empty file: " + driveId);
DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), driveId);
file.addChangeSubscription(getGoogleApiClient());
}
}
});
}
}
事件服务,完成:
public class ChngeSvc extends DriveEventService {
private static final String TAG = "_X_";
@Override
public void onCompletion(CompletionEvent event) { super.onCompletion(event);
DriveId driveId = event.getDriveId();
Log.d(TAG, "onComplete: " + driveId.getResourceId());
switch (event.getStatus()) {
case CompletionEvent.STATUS_CONFLICT: Log.d(TAG, "STATUS_CONFLICT"); event.dismiss(); break;
case CompletionEvent.STATUS_FAILURE: Log.d(TAG, "STATUS_FAILURE"); event.dismiss(); break;
case CompletionEvent.STATUS_SUCCESS: Log.d(TAG, "STATUS_SUCCESS "); event.dismiss(); break;
}
}
}
在正常情况下(wifi),我几乎立即获得ResourceId。
20:40:53.247﹕Created a empty file: DriveId:CAESABiiAiDGsfO61VMoAA==
20:40:54.305: onComplete, ResourceId: 0BxOS7mTBMR_bMHZRUjJ5NU1ZOWs
...现在完成。
已弃用原始帖子,请留在此处以供引用。
我让这个答案坐了一年,希望GDAA将开发出一种可行的解决方案。我na的原因很简单。如果我的应用程序创建了文件,则它需要使用有意义的ID(即ResourceId)向其伙伴(例如其他设备)广播此事实。这是REST Api下的一项琐碎任务,一旦成功创建文件,ResourceId就会返回。
需要说的是,我了解GDAA保护应用程序免受网络原语,缓存,批处理等侵害的哲学。但是很明显,在这种情况下,ResourceID在交付给应用程序之前就已经很早就可用了。
最初,我实现了Cheryl Simon的建议,并在一个新创建的文件上添加了一个ChangeListener,希望在传播文件时获得ResourceID。使用android-demos中的经典CreateEmptyFileActivity,我将以下测试代码打包在一起:
public class CreateEmptyFileActivity extends BaseDemoActivity {
private static final String TAG = "CreateEmptyFileActivity";
final private ChangeListener mChgeLstnr = new ChangeListener() {
@Override
public void onChange(ChangeEvent event) {
Log.d(TAG, "event: " + event + " resId: " + event.getDriveId().getResourceId());
}
};
@Override
public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint);
MetadataChangeSet meta = new MetadataChangeSet.Builder()
.setTitle("EmptyFile.txt").setMimeType("text/plain")
.build();
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), meta, null)
.setResultCallback(new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (result.getStatus().isSuccess()) {
DriveId driveId = result.getDriveFile().getDriveId();
Log.d(TAG, "Created a empty file: " + driveId);
Drive.DriveApi.getFile(getGoogleApiClient(), driveId).addChangeListener(getGoogleApiClient(), mChgeLstnr);
}
}
});
}
}
...并且正在等待某些事情发生。文件在几秒钟内愉快地上传到了Drive,但是没有onChange()事件。 10分钟,20分钟……我找不到任何方法使ChangeListener唤醒。
因此,我唯一能想到的解决方案就是轻推GDAA。因此,我实现了一个简单的处理程序扑克,该程序处理元数据直到发生某些事情:
public class CreateEmptyFileActivity extends BaseDemoActivity {
private static final String TAG = "CreateEmptyFileActivity";
final private ChangeListener mChgeLstnr = new ChangeListener() {
@Override
public void onChange(ChangeEvent event) {
Log.d(TAG, "event: " + event + " resId: " + event.getDriveId().getResourceId());
}
};
static DriveId driveId;
private static final int ENOUGH = 4; // nudge 4x, 1+2+3+4 = 10seconds
private static int mWait = 1000;
private int mCnt;
private Handler mPoker;
private final Runnable mPoke = new Runnable() { public void run() {
if (mPoker != null && driveId != null && driveId.getResourceId() == null && (mCnt++ < ENOUGH)) {
MetadataChangeSet meta = new MetadataChangeSet.Builder().build();
Drive.DriveApi.getFile(getGoogleApiClient(), driveId).updateMetadata(getGoogleApiClient(), meta).setResultCallback(
new ResultCallback<DriveResource.MetadataResult>() {
@Override
public void onResult(DriveResource.MetadataResult result) {
if (result.getStatus().isSuccess() && result.getMetadata().getDriveId().getResourceId() != null)
Log.d(TAG, "resId COOL " + result.getMetadata().getDriveId().getResourceId());
else
mPoker.postDelayed(mPoke, mWait *= 2);
}
}
);
} else {
mPoker = null;
}
}};
@Override
public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint);
MetadataChangeSet meta = new MetadataChangeSet.Builder()
.setTitle("EmptyFile.txt").setMimeType("text/plain")
.build();
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), meta, null)
.setResultCallback(new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (result.getStatus().isSuccess()) {
driveId = result.getDriveFile().getDriveId();
Log.d(TAG, "Created a empty file: " + driveId);
Drive.DriveApi.getFile(getGoogleApiClient(), driveId).addChangeListener(getGoogleApiClient(), mChgeLstnr);
mCnt = 0;
mPoker = new Handler();
mPoker.postDelayed(mPoke, mWait);
}
}
});
}
}
瞧,在4秒钟后(给定或花费),ChangeListener会提供一个新的 Shiny ResourceId。当然,ChangeListener变得过时了,因为扑克例程也获得了ResourceId。
因此,这就是那些无法等待ResourceId的人的答案。这就提出了后续问题:
当我清楚地看到文件已经传播很久并且GDAA具有可用的ResourceId时,为什么我必须去掉元数据(或重新提交内容),很可能创建不必要的网络流量,以获得onChange()事件?
关于google-drive-android-api - Google Drive Android API中DriveId.getResourceId()的意外结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22874657/