5

ファイルをクラウドにアップロードするために、(Google Play Services の一部として) Google Drive Android API を使用しています。

クライアントを接続するには、次のコードを使用しています(簡略化):

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();

1 つの特定のユーザー ケースを除いて、すべてが期待どおりに機能します。ユーザーが (Google 設定アプリケーションを使用して) 「接続済みアプリ」からアプリを削除しても、このコードはすべての呼び出しに対して成功した結果を返します。ファイルがGoogleドライブにアップロードされることはありませんが。

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

ファイルを作成するには、これに従って which を送信してみIntentSenderください

IntentSender を別のアプリケーションに与えることで、別のアプリケーションが自分自身であるかのように (同じアクセス許可と ID で)、指定した操作を実行する権利をそのアプリケーションに付与します。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 に答える