在 Android 上授权驱动器和工作表 API

Authorizing Drive and Sheets API on Android

好的,所以我的 Android 应用需要访问用户 Google 驱动器帐户并在该帐户上编辑电子表格。我正在使用 Google Sheets API 3.0 版来编辑电子表格和 Drive API Client Library for Java 以访问驱动器。
现在我知道了用户需要允许我的应用程序访问他们的信息。现在请纠正我,但我是这样理解的。

  1. 开始activity供用户选择账户
  2. onActivityResult 方法上检查结果以查看用户是否授予权限。


现在,因为我使用两个 API(驱动器和电子表格),用户必须对两者都给予许可,所以我下面的代码执行以下操作。

  1. 开始activity供用户选择账户
  2. onActivityResult 方法中选择 accountName,并将其设置为将要使用的帐户。
  3. onActivityResult 方法中,在我设置要使用的 accountName 之后,我在一个单独的线程(Asyn Task)上进行调用,该线程将抛出 UserRecoverableAuthIOException,然后使用此异常提示用户获得驱动器 API.
  4. 的权限
  5. 在响应用户授予权限的 onActivityResult 方法中,我在一个单独的线程上进行了另一个调用,类似于上一个,这将抛出一个 UserRecoverableAuthException 来授权工作表 API .
    基本上,用户选择他们想要使用的帐户,然后授予 Drive API 权限,然后授予 Sheets API 权限。 我的问题:授予权限应该这样吗?他们是一种在一个提示中同时授予驱动器和表格 API 权限的方法吗?

public class PlannerActivity 扩展了 ActionBarActivity {

ListPlannerFragment mListFragment;
DetailPlannerFragment mDetailFragment;
YIGDataController mController;

private Drive mDrive;
private SpreadsheetService mSpreadsheetService;
private GoogleAccountCredential mGoogleAccountCredential;

private static final String TAG = "PlannerActivity";
protected static final int CHOOSE_ACCOUNT_REQUEST_CODE = 1;
protected static final int AUTHORIZE_DRIVE_ACCESS_REQUEST_CODE = 2;
protected static final int AUTHORIZE_SHEETS_ACCESS_REQUEST_CODE = 3;


//Life Cycle
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Google
    verifyGoogleAPIUse();

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG,"onActivity result called: result code-" + resultCode + ", resultCode-" + resultCode);
    switch(requestCode) {
        case CHOOSE_ACCOUNT_REQUEST_CODE:

            Log.d(TAG,"Result of CHOOSE_ACCOUNT:");
            if(resultCode == Activity.RESULT_OK) {
                Log.d(TAG, "CHOOSE_ACCOUNT successful:");
                String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
                mGoogleAccountCredential.setSelectedAccountName(accountName);
                mDrive = new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(), mGoogleAccountCredential).setApplicationName("YIG Manager").build();
                AuthTryDrive authTryDrive = new AuthTryDrive();
                authTryDrive.execute();
            } else {
                Log.d(TAG, "CHOOSE_ACCOUNT failure:");
                finish();
            }

            break;
        case AUTHORIZE_DRIVE_ACCESS_REQUEST_CODE:

            Log.d(TAG,"Result of AUTHORIZE_DRIVE:");
            if(resultCode == Activity.RESULT_OK) {
                Log.d(TAG, "AUTHORIZE_DRIVE_ACCESS success:");
                AuthTrySheets authTrySheets = new AuthTrySheets();
                authTrySheets.execute();
            } else {
                Log.d(TAG, "AUTHORIZE_DRIVE_ACCESS failed, asking to choose new account:");
                finish();
            }

            break;
        case AUTHORIZE_SHEETS_ACCESS_REQUEST_CODE:

            Log.d(TAG,"Result of AUTHORIZE_SHEETS:");
            if(resultCode == Activity.RESULT_OK) {
                Log.d(TAG, "AUTHORIZE_SHEETS_ACCESS success:");
            } else {
                Log.d(TAG, "AUTHORIZE_SHEETS_ACCESS failed, asking to choose new account:");
                finish();
            }

            break;
    }
}

//Util
private void verifyGoogleAPIUse(){
    mGoogleAccountCredential =GoogleAccountCredential.usingOAuth2(this, Collections.singleton(DriveScopes.DRIVE));
    Log.d(TAG,"Starting activity to choose account.");
    startActivityForResult(mGoogleAccountCredential.newChooseAccountIntent(),CHOOSE_ACCOUNT_REQUEST_CODE);

}

private class AuthTryDrive extends AsyncTask<Void,Void,Void>{

    @Override
    protected Void doInBackground(Void... params) {
        //Drive

        try {
            Log.d(TAG, "In try statement of authorizing drive access");
            FileList f = mDrive.files().list().execute();
            f.toString();
        } catch (UserRecoverableAuthIOException e) {
            Log.d(TAG, "Drive user recoverable error");
            startActivityForResult(e.getIntent(),AUTHORIZE_DRIVE_ACCESS_REQUEST_CODE);
        } catch (IOException e) {
            Log.d(TAG,"io excpetion in drive");
        }
        return null;
    }
}

private class AuthTrySheets extends AsyncTask<Void,Void,Void>{

    @Override
    protected Void doInBackground(Void... params) {
        //SpreadSheets
        try {
            Log.d(TAG,"In try statement of authorizing sheets access");
            mSpreadsheetService = new SpreadsheetService("YIG Manager");
            mSpreadsheetService.setAuthSubToken(GoogleAuthUtil.getToken(PlannerActivity.this, mGoogleAccountCredential.getSelectedAccountName(), "oauth2:https://spreadsheets.google.com/feeds https://docs.google.com/feeds"));
            URL SPREADSHEET_FEED_URL = new URL(
                    "https://spreadsheets.google.com/feeds/spreadsheets/private/full");

            SpreadsheetFeed spreadsheetFeed = mSpreadsheetService.getFeed(SPREADSHEET_FEED_URL,SpreadsheetFeed.class);
            List<SpreadsheetEntry> spreadsheetEntries = spreadsheetFeed.getEntries();
        } catch (UserRecoverableAuthException e) {
            Log.d(TAG,"Sheets user recoverable error");
            startActivityForResult(e.getIntent(),AUTHORIZE_SHEETS_ACCESS_REQUEST_CODE);
        } catch (GoogleAuthException e) {
            Log.d(TAG,"GoogleAuthException");
        } catch (IOException e) {
            Log.d(TAG,"IOException");
        } catch (ServiceException e) {
            Log.d(TAG,"ServiceException" + e.toString());
        }
        return null;
    }
}

}

当您调用 GoogleAuthUtil.getToken 时,您可以提供一个 space 分隔列表,其中包含您要授权的所有范围。只需包括驱动器和工作表范围。其他一些地方在技术上可能仍然能够抛出 auth 异常,但如果你先这样做,它不应该导致提示。