我的应用程序中有以下场景 -
SherlockFragmentActivity托管包含3个单独片段的ViewPager。顶部有一个sherlockactionbar,有备份和恢复选项,基本上应该将应用数据备份到谷歌驱动器帐户(连接到用户)。
现在,一切正常,通过打开Google Api客户端连接和上传/下载文件,也可以进行备份恢复,但是一旦设备旋转,活动就会从头开始重新启动,并且google api客户端实例创建和实例化的ealier(可能上传/下载仍在进行中)变为孤儿。
我收到 IllegalStateException (由于活动重启,而实例仍需要原始活动才能绑定)。
知道片段本身可以在活动重启时保留,我可以将驱动器api实现放在片段中,但是顶部有一个共同的操作栏图标,这不是重复只是放置驱动器所有3个片段的实现??
此外,当发生ViewPager滑动时,片段将被更改,因此我不会再次遇到相同的问题,其中原始驱动器api客户端实例创建者片段不再在范围内。?
实施这样的事情的好方法是什么?任何想法都会帮助我按照指定的方向进行研究。
答案 0 :(得分:0)
我有一个viewpager和几个片段,就像你的情况一样。我让我的活动类从Google-drive-exapmle扩展BaseDriveActivity,但让它扩展FragmentActivity而不是Activity。
旋转没有任何问题,即使在旋转期间调用onResume,也要检查mGoogleApiClient是否为空:
@Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API).addScope(Drive.SCOPE_FILE)
.addScope(Drive.SCOPE_APPFOLDER)
// required for App Folder sample
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
}
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting())
mGoogleApiClient.connect();
}
还有一些错误处理的逻辑。你可以按原样使用它。
创建文件夹,在foldet中创建文件夹等操作我添加到我的主类中,如下所示:
protected void createFolder(String folderName){
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(folderName).build();
Drive.DriveApi.getRootFolder(getGoogleApiClient()).createFolder(
getGoogleApiClient(), changeSet).setResultCallback(createFolderCallback);
}
final ResultCallback<DriveFolderResult> createFolderCallback = new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the folder");
return;
}
showMessage("Created a folder: " + result.getDriveFolder().getDriveId());
}
};
private String folderName;
protected void createFolderInFolder(String exsistingDriveId, String folderName){
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), exsistingDriveId).setResultCallback(idCallback);
this.folderName=folderName;
}
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
@Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveFolder folder = Drive.DriveApi
.getFolder(getGoogleApiClient(), result.getDriveId());
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(folderName).build();
folder.createFolder(getGoogleApiClient(), changeSet)
.setResultCallback(createFolderCallback);
}
};
private DriveId mFolderDriveId;
protected void createFileInFolder(String exsistingDriveId, String folderName){
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), exsistingDriveId).setResultCallback(fileIdCallback);
this.folderName=folderName;
}
final private ResultCallback<DriveIdResult> fileIdCallback = new ResultCallback<DriveIdResult>() {
@Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
mFolderDriveId = result.getDriveId();
Drive.DriveApi.newDriveContents(getGoogleApiClient())
.setResultCallback(driveContentsCallback);
}
};
final private ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
@Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(), mFolderDriveId);
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(folderName)
.setMimeType("text/plain")
.setStarred(true).build();
folder.createFile(getGoogleApiClient(), changeSet, result.getDriveContents())
.setResultCallback(fileCallback);
}
};
final private ResultCallback<DriveFileResult> fileCallback =
new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the file");
return;
}
showMessage("Created a file: " + result.getDriveFile().getDriveId());
}
};
编辑: 我发现了以下内容: 如果调用createFolderInFolder(或任何其他api-funcions),就在使用intent调用活动之前,在调用的activity活动运行时不会调用result-callback。当主活动正在接收控制时,将调用onResume,并提供异常,因为再次调用connect。然后从不调用结果回调。
这意味着api-call和result-callback必须能够在不运行任何其他调用的情况下运行。
新编辑: 第1步:您需要在Fragment中使用回调函数
private Callbacks mCallbacks;
interface Callbacks {
public void onSaveToDrive(byte[] filecontent);
}
步骤2:主要活动必须实现片段回调方法
步骤3:调用api-function,并在result-callback中添加fragment-update调用
如果您想存储driveid,您应该使用DriveId.encodeFromString(exsistingDriveId)和DriveId.decodeFromString(exsistingDriveId),这样您就可以存储现有的DriveId,并在以后安全地再次引用它,即使驱动器已断开连接并重新连接。
请记住,必须在不调用其他类的情况下完成一个api调用,因为这可能会导致调用onResume()。