ChooseAccountTypeActivity.java revision a77253a417e885f87280901a3519412262758412
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.accounts; 17 18import android.app.Activity; 19import android.content.Context; 20import android.content.Intent; 21import android.content.pm.PackageManager; 22import android.content.res.Resources; 23import android.graphics.drawable.Drawable; 24import android.os.Bundle; 25import android.util.Log; 26import android.view.LayoutInflater; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.AdapterView; 30import android.widget.ArrayAdapter; 31import android.widget.ImageView; 32import android.widget.ListView; 33import android.widget.TextView; 34import com.android.internal.R; 35 36import java.io.IOException; 37import java.util.ArrayList; 38import java.util.HashMap; 39import java.util.HashSet; 40import java.util.Map; 41import java.util.Set; 42 43/** 44 * @hide 45 */ 46public class ChooseAccountTypeActivity extends Activity implements AccountManagerCallback<Bundle> { 47 private static final String TAG = "AccountManager"; 48 49 private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>(); 50 private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay; 51 52 @Override 53 public void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 setContentView(R.layout.choose_account_type); 56 57 // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes 58 Set<String> setOfAllowableAccountTypes = null; 59 String[] validAccountTypes = getIntent().getStringArrayExtra( 60 ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY); 61 if (validAccountTypes != null) { 62 setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.length); 63 for (String type : validAccountTypes) { 64 setOfAllowableAccountTypes.add(type); 65 } 66 } 67 68 // create a map of account authenticators 69 buildTypeToAuthDescriptionMap(); 70 71 // Create a list of authenticators that are allowable. Filter out those that 72 // don't match the allowable account types, if provided. 73 mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size()); 74 for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) { 75 final String type = entry.getKey(); 76 final AuthInfo info = entry.getValue(); 77 if (setOfAllowableAccountTypes != null 78 && !setOfAllowableAccountTypes.contains(type)) { 79 continue; 80 } 81 mAuthenticatorInfosToDisplay.add(info); 82 } 83 84 if (mAuthenticatorInfosToDisplay.isEmpty()) { 85 Bundle bundle = new Bundle(); 86 bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types"); 87 setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 88 finish(); 89 return; 90 } 91 92 if (mAuthenticatorInfosToDisplay.size() == 1) { 93 runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(0)); 94 return; 95 } 96 97 // Setup the list 98 ListView list = (ListView) findViewById(android.R.id.list); 99 // Use an existing ListAdapter that will map an array of strings to TextViews 100 list.setAdapter(new AccountArrayAdapter(this, 101 android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay)); 102 list.setChoiceMode(ListView.CHOICE_MODE_NONE); 103 list.setTextFilterEnabled(false); 104 list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 105 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 106 runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(position)); 107 } 108 }); 109 } 110 111 private void buildTypeToAuthDescriptionMap() { 112 for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) { 113 String name = null; 114 Drawable icon = null; 115 try { 116 Context authContext = createPackageContext(desc.packageName, 0); 117 icon = authContext.getResources().getDrawable(desc.iconId); 118 final CharSequence sequence = authContext.getResources().getText(desc.labelId); 119 if (sequence != null) { 120 name = sequence.toString(); 121 } 122 name = sequence.toString(); 123 } catch (PackageManager.NameNotFoundException e) { 124 // Nothing we can do much here, just log 125 if (Log.isLoggable(TAG, Log.WARN)) { 126 Log.w(TAG, "No icon name for account type " + desc.type); 127 } 128 } catch (Resources.NotFoundException e) { 129 // Nothing we can do much here, just log 130 if (Log.isLoggable(TAG, Log.WARN)) { 131 Log.w(TAG, "No icon resource for account type " + desc.type); 132 } 133 } 134 AuthInfo authInfo = new AuthInfo(desc, name, icon); 135 mTypeToAuthenticatorInfo.put(desc.type, authInfo); 136 } 137 } 138 139 protected void runAddAccountForAuthenticator(AuthInfo authInfo) { 140 Log.d(TAG, "selected account type " + authInfo.name); 141 final Bundle options = getIntent().getBundleExtra( 142 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE); 143 final String[] requiredFeatures = getIntent().getStringArrayExtra( 144 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY); 145 final String authTokenType = getIntent().getStringExtra( 146 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING); 147 AccountManager.get(this).addAccount(authInfo.desc.type, authTokenType, requiredFeatures, 148 options, this, this, null /* Handler */); 149 } 150 151 public void run(final AccountManagerFuture<Bundle> accountManagerFuture) { 152 try { 153 Bundle accountManagerResult = accountManagerFuture.getResult(); 154 Bundle bundle = new Bundle(); 155 bundle.putString(AccountManager.KEY_ACCOUNT_NAME, 156 accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME)); 157 bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, 158 accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE)); 159 setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 160 finish(); 161 return; 162 } catch (OperationCanceledException e) { 163 setResult(Activity.RESULT_CANCELED); 164 finish(); 165 return; 166 } catch (IOException e) { 167 } catch (AuthenticatorException e) { 168 } 169 Bundle bundle = new Bundle(); 170 bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "error communicating with server"); 171 setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 172 finish(); 173 } 174 175 private static class AuthInfo { 176 final AuthenticatorDescription desc; 177 final String name; 178 final Drawable drawable; 179 180 AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) { 181 this.desc = desc; 182 this.name = name; 183 this.drawable = drawable; 184 } 185 } 186 187 private static class ViewHolder { 188 ImageView icon; 189 TextView text; 190 } 191 192 private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> { 193 private LayoutInflater mLayoutInflater; 194 private ArrayList<AuthInfo> mInfos; 195 196 public AccountArrayAdapter(Context context, int textViewResourceId, 197 ArrayList<AuthInfo> infos) { 198 super(context, textViewResourceId, infos); 199 mInfos = infos; 200 mLayoutInflater = (LayoutInflater) context.getSystemService( 201 Context.LAYOUT_INFLATER_SERVICE); 202 } 203 204 @Override 205 public View getView(int position, View convertView, ViewGroup parent) { 206 ViewHolder holder; 207 208 if (convertView == null) { 209 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null); 210 holder = new ViewHolder(); 211 holder.text = (TextView) convertView.findViewById(R.id.account_row_text); 212 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon); 213 convertView.setTag(holder); 214 } else { 215 holder = (ViewHolder) convertView.getTag(); 216 } 217 218 holder.text.setText(mInfos.get(position).name); 219 holder.icon.setImageDrawable(mInfos.get(position).drawable); 220 221 return convertView; 222 } 223 } 224} 225