来自SherlockFragmentActivity操作栏的Google Drive Api实施

时间:2014-12-24 17:18:04

标签: android android-fragments actionbarsherlock android-fragmentactivity google-drive-android-api

我的应用程序中有以下场景 -

SherlockFragmentActivity托管包含3个单独片段的ViewPager。顶部有一个sherlockactionbar,有备份和恢复选项,基本上应该将应用数据备份到谷歌驱动器帐户(连接到用户)。

现在,一切正常,通过打开Goog​​le Api客户端连接和上传/下载文件,也可以进行备份恢复,但是一旦设备旋转,活动就会从头开始重新启动,并且google api客户端实例创建和实例化的ealier(可能上传/下载仍在进行中)变为孤儿。

我收到 IllegalStateException (由于活动重启,而实例仍需要原始活动才能绑定)。

知道片段本身可以在活动重启时保留,我可以将驱动器api实现放在片段中,但是顶部有一个共同的操作栏图标,这不是重复只是放置驱动器所有3个片段的实现??

此外,当发生ViewPager滑动时,片段将被更改,因此我不会再次遇到相同的问题,其中原始驱动器api客户端实例创建者片段不再在范围内。?

实施这样的事情的好方法是什么?任何想法都会帮助我按照指定的方向进行研究。

1 个答案:

答案 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()。