5

我正在使用 Google Drive Android API(作为 Google Play 服务的一部分)将文件上传到云端。

要连接客户端,我使用以下代码(简化):

apiClient = new GoogleApiClient.Builder(context)
            .addApi(Drive.API)
            .setAccountName(preferences.getString("GOOGLE_DRIVE_ACCOUNT", null))
            .build();

ConnectionResult connectionResult = apiClient.blockingConnect(SERVICES_CONNECTION_TIMEOUT_SEC, TimeUnit.SECONDS);
if (!connectionResult.isSuccess()) {
    throw new ApiConnectionException(); //our own exception
}

要上传文件,我使用以下代码(简化):

DriveApi.ContentsResult result = Drive.DriveApi.newContents(apiClient).await();
if (!result.getStatus().isSuccess()) {
    /* ... code for error handling ... */
    return;
}

OutputStream output = result.getContents().getOutputStream();
/* ... writing to output ... */

//create actual file on Google Drive
DriveFolder.DriveFileResult driveFileResult = Drive.DriveApi
            .getFolder(apiClient, folderId)
            .createFile(apiClient, metadataChangeSet, result.getContents())
            .await();

除了一个特定的用户案例外,一切都按预期工作。当用户从“连接的应用程序”(使用 Google 设置应用程序)中删除我们的应用程序时,此代码仍会为所有调用返回成功的结果。虽然文件从未上传到 Google Drive。

与 Google Play 服务的连接也成功。

是 API 的错误还是可以以某种方式检测到用户断开了应用程序?

4

3 回答 3

0

您没有收到 UserRecoverableAuthIOException 吗?因为你应该。任何尝试读取/上传到用户断开应用程序的驱动器都应返回此异常。您可能正在捕获一般异常并错过了这一点。尝试调试以查看您是否没有收到此异常。

如果是,您所要做的就是重新请求

        catch (UserRecoverableAuthIOException e) {
            startActivityForResult(e.getIntent(), COMPLETE_AUTHORIZATION_REQUEST_CODE);
        }

然后像这样处理响应:

case COMPLETE_AUTHORIZATION_REQUEST_CODE:
        if (resultCode == RESULT_OK) {
            // App is authorized, you can go back to sending the API request
        } else {
            // User denied access, show him the account chooser again
        }
        break;
    }
于 2014-06-21T01:42:19.850 回答
0

我不知道内部/外部的 API,但是此页面可能对https://support.google.com/drive/answer/2523073?hl=en有所帮助。我会仔细检查accounts.google.com 页面并确认所有权限都已被删除。这不会解决 api 行为,但至少您可以验证权限。

于 2014-06-12T08:10:07.693 回答
-1

IntentSender要创建文件,请尝试根据发送which

通过将 IntentSender 提供给另一个应用程序,您授予它执行您指定的操作的权利,就好像另一个应用程序是您自己一样(具有相同的权限和身份)。看起来像一个Pending Intent。您可以使用创建文件

ResultCallback<ContentsResult> onContentsCallback =
                    new ResultCallback<ContentsResult>() {
                @Override
                public void onResult(ContentsResult result) {
                    // TODO: error handling in case of failure
                    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                            .setMimeType(MIME_TYPE_TEXT).build();
                    IntentSender createIntentSender = Drive.DriveApi
                            .newCreateFileActivityBuilder()
                            .setInitialMetadata(metadataChangeSet)
                            .setInitialContents(result.getContents())
                            .build(mGoogleApiClient);
                    try {
                        startIntentSenderForResult(createIntentSender, REQUEST_CODE_CREATOR, null,
                                0, 0, 0);
                    } catch (SendIntentException e) {
                        Log.w(TAG, "Unable to send intent", e);
                    }
                }
            };

在这里

`startIntentSenderForResult (IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)`

如果 requestCode >= 0,则onActivityResult()在活动退出时返回此代码。在你的onActivityResult()你可以

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        //REQUEST_CODE_CREATOR == 1
        case REQUEST_CODE_CREATOR:
            if (resultCode == RESULT_OK) {
                DriveId driveId = (DriveId) data.getParcelableExtra(
                        OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
                showMessage("File created with ID: " + driveId);
            }
            finish();
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
            break;
        }
    }

尝试得到apiClient这样的

mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(Drive.API).addScope(Drive.SCOPE_FILE)
                    .setAccountName(mAccountName).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).build();



  /**
     * Called when {@code mGoogleApiClient} is connected.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "GoogleApiClient connected");
    }

     /**
     * Called when {@code mGoogleApiClient} is disconnected.
     */
    @Override
    public void onConnectionSuspended(int cause) {
        Log.i(TAG, "GoogleApiClient connection suspended");
    }

    /**
     * Called when {@code mGoogleApiClient} is trying to connect but failed.
     * Handle {@code result.getResolution()} if there is a resolution is
     * available.
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
        if (!result.hasResolution()) {
            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
            return;
        }
        try {
            result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
        } catch (SendIntentException e) {
            Log.e(TAG, "Exception while starting resolution activity", e);
        }
    }

你可以得到mAccountName这样的:

Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
            if (accounts.length == 0) {
                Log.d(TAG, "Must have a Google account installed");
                return;
            }
            mAccountName = accounts[0].name;

希望这可以帮助。

于 2014-06-12T10:43:03.537 回答