4747 */
4848public class ChooseTypeAndAccountActivity extends Activity
4949 implements AccountManagerCallback <Bundle > {
50- private static final String TAG = "AccountManager " ;
50+ private static final String TAG = "AccountChooser " ;
5151
5252 /**
5353 * A Parcelable ArrayList of Account objects that limits the choosable accounts to those
@@ -100,13 +100,39 @@ public class ChooseTypeAndAccountActivity extends Activity
100100 public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE =
101101 "descriptionTextOverride" ;
102102
103+ public static final int REQUEST_NULL = 0 ;
104+ public static final int REQUEST_CHOOSE_TYPE = 1 ;
105+ public static final int REQUEST_ADD_ACCOUNT = 2 ;
106+
107+ private static final String KEY_INSTANCE_STATE_PENDING_REQUEST = "pendingRequest" ;
108+ private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts" ;
109+
103110 private ArrayList <AccountInfo > mAccountInfos ;
111+ private int mPendingRequest = REQUEST_NULL ;
112+ private Parcelable [] mExistingAccounts = null ;
113+ private Parcelable [] mSavedAccounts = null ;
104114
105115 @ Override
106116 public void onCreate (Bundle savedInstanceState ) {
107117 super .onCreate (savedInstanceState );
118+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
119+ Log .v (TAG , "ChooseTypeAndAccountActivity.onCreate(savedInstanceState="
120+ + savedInstanceState + ")" );
121+ }
122+
108123 setContentView (R .layout .choose_type_and_account );
109124
125+ if (savedInstanceState != null ) {
126+ mPendingRequest = savedInstanceState .getInt (KEY_INSTANCE_STATE_PENDING_REQUEST );
127+ mSavedAccounts =
128+ savedInstanceState .getParcelableArray (KEY_INSTANCE_STATE_EXISTING_ACCOUNTS );
129+ mExistingAccounts = null ;
130+ } else {
131+ mPendingRequest = REQUEST_NULL ;
132+ mSavedAccounts = null ;
133+ mExistingAccounts = null ;
134+ }
135+
110136 // save some items we use frequently
111137 final AccountManager accountManager = AccountManager .get (this );
112138 final Intent intent = getIntent ();
@@ -171,20 +197,6 @@ public void onCreate(Bundle savedInstanceState) {
171197 account .equals (selectedAccount )));
172198 }
173199
174- // If there are no allowable accounts go directly to add account
175- if (mAccountInfos .isEmpty ()) {
176- startChooseAccountTypeActivity ();
177- return ;
178- }
179-
180- // if there is only one allowable account return it
181- if (!intent .getBooleanExtra (EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT , false )
182- && mAccountInfos .size () == 1 ) {
183- Account account = mAccountInfos .get (0 ).account ;
184- setResultAndFinish (account .name , account .type );
185- return ;
186- }
187-
188200 // there is more than one allowable account. initialize the list adapter to allow
189201 // the user to select an account.
190202 ListView list = (ListView ) findViewById (android .R .id .list );
@@ -204,6 +216,37 @@ public void onClick(final View v) {
204216 startChooseAccountTypeActivity ();
205217 }
206218 });
219+
220+ if (mPendingRequest == REQUEST_NULL ) {
221+ // If there are no allowable accounts go directly to add account
222+ if (mAccountInfos .isEmpty ()) {
223+ startChooseAccountTypeActivity ();
224+ return ;
225+ }
226+
227+ // if there is only one allowable account return it
228+ if (!intent .getBooleanExtra (EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT , false )
229+ && mAccountInfos .size () == 1 ) {
230+ Account account = mAccountInfos .get (0 ).account ;
231+ setResultAndFinish (account .name , account .type );
232+ return ;
233+ }
234+ }
235+ }
236+
237+ @ Override
238+ protected void onDestroy () {
239+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
240+ Log .v (TAG , "ChooseTypeAndAccountActivity.onDestroy()" );
241+ }
242+ super .onDestroy ();
243+ }
244+
245+ @ Override
246+ protected void onSaveInstanceState (final Bundle outState ) {
247+ super .onSaveInstanceState (outState );
248+ outState .putInt (KEY_INSTANCE_STATE_PENDING_REQUEST , mPendingRequest );
249+ outState .putParcelableArray (KEY_INSTANCE_STATE_EXISTING_ACCOUNTS , mExistingAccounts );
207250 }
208251
209252 // Called when the choose account type activity (for adding an account) returns.
@@ -212,41 +255,95 @@ public void onClick(final View v) {
212255 @ Override
213256 protected void onActivityResult (final int requestCode , final int resultCode ,
214257 final Intent data ) {
215- if (resultCode == RESULT_OK && data != null ) {
216- String accountType = data .getStringExtra (AccountManager .KEY_ACCOUNT_TYPE );
217- if (accountType != null ) {
218- runAddAccountForAuthenticator (accountType );
219- return ;
258+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
259+ if (data != null && data .getExtras () != null ) data .getExtras ().keySet ();
260+ Bundle extras = data != null ? data .getExtras () : null ;
261+ Log .v (TAG , "ChooseTypeAndAccountActivity.onActivityResult(reqCode=" + requestCode
262+ + ", resCode=" + resultCode + ", extras=" + extras + ")" );
263+ }
264+
265+ // we got our result, so clear the fact that we had a pending request
266+ mPendingRequest = REQUEST_NULL ;
267+ mExistingAccounts = null ;
268+
269+ if (resultCode == RESULT_CANCELED ) {
270+ return ;
271+ }
272+
273+ if (resultCode == RESULT_OK ) {
274+ if (requestCode == REQUEST_CHOOSE_TYPE ) {
275+ if (data != null ) {
276+ String accountType = data .getStringExtra (AccountManager .KEY_ACCOUNT_TYPE );
277+ if (accountType != null ) {
278+ runAddAccountForAuthenticator (accountType );
279+ return ;
280+ }
281+ }
282+ Log .d (TAG , "ChooseTypeAndAccountActivity.onActivityResult: unable to find account "
283+ + "type, pretending the request was canceled" );
284+ } else if (requestCode == REQUEST_ADD_ACCOUNT ) {
285+ String accountName = null ;
286+ String accountType = null ;
287+
288+ if (data != null ) {
289+ accountName = data .getStringExtra (AccountManager .KEY_ACCOUNT_NAME );
290+ accountType = data .getStringExtra (AccountManager .KEY_ACCOUNT_TYPE );
291+ }
292+
293+ if (accountName == null || accountType == null ) {
294+ Account [] currentAccounts = AccountManager .get (this ).getAccounts ();
295+ Set <Account > preExistingAccounts = new HashSet <Account >();
296+ for (Parcelable accountParcel : mSavedAccounts ) {
297+ preExistingAccounts .add ((Account ) accountParcel );
298+ }
299+ for (Account account : currentAccounts ) {
300+ if (!preExistingAccounts .contains (account )) {
301+ accountName = account .name ;
302+ accountType = account .type ;
303+ break ;
304+ }
305+ }
306+ }
307+
308+ if (accountName != null || accountType != null ) {
309+ setResultAndFinish (accountName , accountType );
310+ return ;
311+ }
220312 }
313+ Log .d (TAG , "ChooseTypeAndAccountActivity.onActivityResult: unable to find added "
314+ + "account, pretending the request was canceled" );
315+ }
316+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
317+ Log .v (TAG , "ChooseTypeAndAccountActivity.onActivityResult: canceled" );
221318 }
222- Log .d (TAG , "ChooseTypeAndAccountActivity.onActivityResult: canceled" );
223319 setResult (Activity .RESULT_CANCELED );
224320 finish ();
225321 }
226322
227323 protected void runAddAccountForAuthenticator (String type ) {
228- Log .d (TAG , "selected account type " + type );
324+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
325+ Log .v (TAG , "runAddAccountForAuthenticator: " + type );
326+ }
229327 final Bundle options = getIntent ().getBundleExtra (
230328 ChooseTypeAndAccountActivity .EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE );
231329 final String [] requiredFeatures = getIntent ().getStringArrayExtra (
232330 ChooseTypeAndAccountActivity .EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY );
233331 final String authTokenType = getIntent ().getStringExtra (
234332 ChooseTypeAndAccountActivity .EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING );
235333 AccountManager .get (this ).addAccount (type , authTokenType , requiredFeatures ,
236- options , this , this , null /* Handler */ );
334+ options , null /* activity */ , this /* callback */ , null /* Handler */ );
237335 }
238336
239337 public void run (final AccountManagerFuture <Bundle > accountManagerFuture ) {
240338 try {
241339 final Bundle accountManagerResult = accountManagerFuture .getResult ();
242- final String name = accountManagerResult .getString (AccountManager .KEY_ACCOUNT_NAME );
243- final String type = accountManagerResult .getString (AccountManager .KEY_ACCOUNT_TYPE );
244- if (name != null && type != null ) {
245- final Bundle bundle = new Bundle ();
246- bundle .putString (AccountManager .KEY_ACCOUNT_NAME , name );
247- bundle .putString (AccountManager .KEY_ACCOUNT_TYPE , type );
248- setResult (Activity .RESULT_OK , new Intent ().putExtras (bundle ));
249- finish ();
340+ final Intent intent = (Intent )accountManagerResult .getParcelable (
341+ AccountManager .KEY_INTENT );
342+ if (intent != null ) {
343+ mPendingRequest = REQUEST_ADD_ACCOUNT ;
344+ mExistingAccounts = AccountManager .get (this ).getAccounts ();
345+ intent .setFlags (intent .getFlags () & ~Intent .FLAG_ACTIVITY_NEW_TASK );
346+ startActivityForResult (intent , REQUEST_ADD_ACCOUNT );
250347 return ;
251348 }
252349 } catch (OperationCanceledException e ) {
@@ -297,12 +394,17 @@ private void setResultAndFinish(final String accountName, final String accountTy
297394 bundle .putString (AccountManager .KEY_ACCOUNT_NAME , accountName );
298395 bundle .putString (AccountManager .KEY_ACCOUNT_TYPE , accountType );
299396 setResult (Activity .RESULT_OK , new Intent ().putExtras (bundle ));
300- Log .d (TAG , "ChooseTypeAndAccountActivity.setResultAndFinish: "
301- + "selected account " + accountName + ", " + accountType );
397+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
398+ Log .v (TAG , "ChooseTypeAndAccountActivity.setResultAndFinish: "
399+ + "selected account " + accountName + ", " + accountType );
400+ }
302401 finish ();
303402 }
304403
305404 private void startChooseAccountTypeActivity () {
405+ if (Log .isLoggable (TAG , Log .VERBOSE )) {
406+ Log .v (TAG , "ChooseAccountTypeActivity.startChooseAccountTypeActivity()" );
407+ }
306408 final Intent intent = new Intent (this , ChooseAccountTypeActivity .class );
307409 intent .setFlags (Intent .FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET );
308410 intent .putExtra (EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY ,
@@ -313,7 +415,8 @@ private void startChooseAccountTypeActivity() {
313415 getIntent ().getStringArrayExtra (EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY ));
314416 intent .putExtra (EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING ,
315417 getIntent ().getStringExtra (EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING ));
316- startActivityForResult (intent , 0 );
418+ startActivityForResult (intent , REQUEST_CHOOSE_TYPE );
419+ mPendingRequest = REQUEST_CHOOSE_TYPE ;
317420 }
318421
319422 private static class AccountInfo {
0 commit comments