Android startActivityForResult调用了两次

时间:2015-02-18 01:47:42

标签: java android google-drive-api google-sheets android-lifecycle

所以我的应用程序,因为它必须访问用户驱动器信息,首先提示用户从我的应用程序调用的活动中获取结果(帐户名称)时在单独的线程代码中选择帐户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;
        }

    }}

2 个答案:

答案 0 :(得分:0)

所以看来我在我的开发者选项中没有保留活动'选择的选项。因此,当对话框模糊了我的活动视图时,它将被销毁,因此一旦使用了同意提示,就会调用它onCreate,这导致我的整个onCreate方法被调用,从而导致在对话框中弹出两次。关于为什么我的if语句不起作用的问题,因为当活动被破坏时显然是我的布尔值中的信息。要显示此操作,请先执行以下代码,而不要“保持活动”。启动应用程序,按主页,然后再次打开应用程序。日志将显示结果。

public class LifeCycleActivity extends ActionBarActivity {

private static final String TAG = "lifecycle";
boolean b;


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

    Log.d(TAG,"onCreate");
}

@Override
protected void onStart() {
    super.onStart();
    b = !b;
    Log.d(TAG,"onStart: b = " + b);
}

@Override
protected void onResume() {
    super.onResume();
    Log.d(TAG,"onResume: b = " + b);
}

@Override
protected void onPause() {
    super.onPause();
    Log.d(TAG,"onPause: b = " + b);
}

@Override
protected void onStop() {
    super.onStop();
    Log.d(TAG,"onStop");
}

@Override
protected void onRestart() {
    super.onRestart();
    Log.d(TAG,"onRestart");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.d(TAG,"onDestroy");
}

}

答案 1 :(得分:-3)

更改

    boolean b;

    volatile boolean b;