【发布时间】:2015-02-18 01:47:41
【问题描述】:
所以我的应用程序,因为它必须访问用户驱动器信息,首先提示用户选择一个帐户startActivityForResult(mGoogleAccountCredential.newChooseAccountIntent(), CHOOSE_ACCOUNT_REQUEST_CODE); 从我的应用程序调用的活动中获取结果(帐户名)在单独的线程代码中进行检查如果用户已授予应用访问其信息的权限。正是在这一点上,如果用户没有授予权限,他们将被提示一个对话框,要求用户同意。
在我的手机上,这非常有效,弹出一个选择帐户的对话框,然后很快另一个对话框询问同意打开,我接受,我回到我的应用程序主屏幕。不过,在我的平板电脑上,一旦我同意,要求我选择一个帐户的对话框就会再次弹出。在修补之后,我发现startActivityForResult 行运行了两次(这不是系统提示的事情),第二次在我同意后。
经过一番研究后,我发现这可能与对我的活动生命周期处理不当有关,我注意到在我的手机上,当同意屏幕弹出时,它完全覆盖了它背后的活动,而在我的平板电脑上,它只覆盖了屏幕的一部分。我知道当一个活动被另一个视图部分覆盖时,它的onPause() 方法被调用,但我仍然不明白为什么我的startActivityForResult 被调用了两次。最后一件事,在我意识到在我的平板电脑上第二次运行onCreate() 之后(在接受同意对话框之后),我在一个 if 语句中包围了我对startActivityForResult 的调用,你可以在我的代码中看到,但这没有用并且我的问题是为什么?那段代码不应该只运行一次吗?
总结一下,为什么帐户选择器对话框会弹出两次(onCreate 中的所有代码都运行两次),为什么我的 if 语句不起作用?我错过了什么? 谢谢。
public class PlannerActivity extends ActionBarActivity{
//YIG
ListPlannerFragment mListFragment;
DetailPlannerFragment mDetailFragment;
YIGDataController mController;
//Google
private Drive mDrive;
private SpreadsheetService mSpreadsheetService;
private GoogleAccountCredential mGoogleAccountCredential;
boolean b;
//Scope
private static final String DRIVE_SCOPE = "https://www.googleapis.com/auth/drive";
private static final String SHEETS_SCOPE = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
private static final String MY_APP_SCOPE = DRIVE_SCOPE + " " + SHEETS_SCOPE;
//Request Codes
protected static final int CHOOSE_ACCOUNT_REQUEST_CODE = 1;
protected static final int AUTHORIZE_APP_ACCESS_REQUEST_CODE = 2;
public static final String TAG = "PlannerActivity";
//Life Cycle
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Google
if(!b){//This still gets run second time when user consent dialog is accepted, is the value of b being reset??
b = true;
verifyGoogleAPIUse();
}
setContentView(R.layout.activity_planner);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case CHOOSE_ACCOUNT_REQUEST_CODE:
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();
mSpreadsheetService = new SpreadsheetService("YIG Manager");
AuthorizeAPIUse authroizeAPIUse = new AuthorizeAPIUse(this,mGoogleAccountCredential.getScope(),mGoogleAccountCredential.getSelectedAccountName(),mSpreadsheetService,mGoogleAccountCredential,mDrive);
authroizeAPIUse.execute();
} else {
Log.d(TAG, "CHOOSE_ACCOUNT failure");
finish();
}
break;
case AUTHORIZE_APP_ACCESS_REQUEST_CODE:
if(resultCode == Activity.RESULT_OK){
Log.d(TAG, "AUTHORIZE_APP_ACCESS success");
AuthorizeAPIUse authroizeAPIUsex = new AuthorizeAPIUse(this,mGoogleAccountCredential.getScope(),mGoogleAccountCredential.getSelectedAccountName(),mSpreadsheetService,mGoogleAccountCredential,mDrive);
authroizeAPIUsex.execute();
}
else{
Log.d(TAG, "AUTHORIZE_APP_ACCESS failed");
finish();
}
break;
}
}
//Util
private void verifyGoogleAPIUse(){
mController.mGoogleAccountCredential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(MY_APP_SCOPE));
mGoogleAccountCredential = mController.mGoogleAccountCredential;
startActivityForResult(mGoogleAccountCredential.newChooseAccountIntent(), CHOOSE_ACCOUNT_REQUEST_CODE);
}
public void handleAuthException(UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), AUTHORIZE_APP_ACCESS_REQUEST_CODE);//This gets run second time after user consent dialog is accepeted
}
private class AuthorizeAPIUse extends AsyncTask {
@Override
protected Object doInBackground(Object[] params) {
try {
String token = fetchToken();
if(token != null){
Log.d(PlannerActivity.TAG, "Scope authorized");
mSpreadsheetService.setAuthSubToken(token);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException e) {
mActivity.handleAuthException(e);//This is what starts the dialog that prompts for user consent
} catch (GoogleAuthException e) {
e.printStackTrace();
}
return null;
}
}}
【问题讨论】:
标签: java android google-drive-api google-sheets android-lifecycle