ChooseAccountTypeActivity.java revision 1121bb5e6ff20a2c694225300507ed486e04fea2
11121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana/* 21121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Copyright (C) 2011 The Android Open Source Project 31121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * 41121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 51121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * you may not use this file except in compliance with the License. 61121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * You may obtain a copy of the License at 71121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * 81121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * http://www.apache.org/licenses/LICENSE-2.0 91121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * 101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Unless required by applicable law or agreed to in writing, software 111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * See the License for the specific language governing permissions and 141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * limitations under the License. 151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana */ 161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanapackage android.accounts; 171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.app.Activity; 191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.Context; 201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.Intent; 211121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.pm.PackageManager; 221121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.res.Resources; 231121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.graphics.drawable.Drawable; 241121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.os.Bundle; 251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.util.Log; 261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.LayoutInflater; 271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.View; 281121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.ViewGroup; 291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.AdapterView; 301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ArrayAdapter; 311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ImageView; 321121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ListView; 331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.TextView; 341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport com.android.internal.R; 351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.io.IOException; 371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.ArrayList; 381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashMap; 391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashSet; 401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Map; 411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Set; 421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana/** 441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * @hide 451121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana */ 461121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanapublic class ChooseAccountTypeActivity extends Activity implements AccountManagerCallback<Bundle> { 471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private static final String TAG = "AccountManager"; 481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>(); 501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay; 511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana @Override 531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana public void onCreate(Bundle savedInstanceState) { 541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana super.onCreate(savedInstanceState); 551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setContentView(R.layout.choose_account); 561121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 571121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes 581121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Set<String> setOfAllowableAccountTypes = null; 591121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ArrayList<String> validAccountTypes = getIntent().getStringArrayListExtra( 601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_ARRAYLIST); 611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (validAccountTypes != null) { 621121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.size()); 631121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana for (String type : validAccountTypes) { 641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setOfAllowableAccountTypes.add(type); 651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // create a map of account authenticators 691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana buildTypeToAuthDescriptionMap(); 701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Create a list of authenticators that are allowable. Filter out those that 721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // don't match the allowable account types, if provided. 731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size()); 741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) { 751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final String type = entry.getKey(); 761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final AuthInfo info = entry.getValue(); 771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (setOfAllowableAccountTypes != null 781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana && !setOfAllowableAccountTypes.contains(type)) { 791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana continue; 801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana mAuthenticatorInfosToDisplay.add(info); 821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (mAuthenticatorInfosToDisplay.isEmpty()) { 851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Bundle bundle = new Bundle(); 861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types"); 871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana finish(); 891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana return; 901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (mAuthenticatorInfosToDisplay.size() == 1) { 931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(0)); 941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana return; 951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 961121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Setup the list 981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ListView list = (ListView) findViewById(android.R.id.list); 991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Use an existing ListAdapter that will map an array of strings to TextViews 1001121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana list.setAdapter(new AccountArrayAdapter(this, 1011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay)); 1021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana list.setChoiceMode(ListView.CHOICE_MODE_NONE); 1031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana list.setTextFilterEnabled(false); 1041121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 1051121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 1061121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(position)); 1071121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1081121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana }); 1091121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private void buildTypeToAuthDescriptionMap() { 1121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) { 1131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana String name = null; 1141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Drawable icon = null; 1151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana try { 1161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Context authContext = createPackageContext(desc.packageName, 0); 1171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana icon = authContext.getResources().getDrawable(desc.iconId); 1181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final CharSequence sequence = authContext.getResources().getText(desc.labelId); 1191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (sequence != null) { 1201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana name = sequence.toString(); 1211121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1221121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana name = sequence.toString(); 1231121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } catch (PackageManager.NameNotFoundException e) { 1241121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Nothing we can do much here, just log 1251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (Log.isLoggable(TAG, Log.WARN)) { 1261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Log.w(TAG, "No icon name for account type " + desc.type); 1271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1281121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } catch (Resources.NotFoundException e) { 1291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana // Nothing we can do much here, just log 1301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (Log.isLoggable(TAG, Log.WARN)) { 1311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Log.w(TAG, "No icon resource for account type " + desc.type); 1321121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana AuthInfo authInfo = new AuthInfo(desc, name, icon); 1351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana mTypeToAuthenticatorInfo.put(desc.type, authInfo); 1361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana protected void runAddAccountForAuthenticator(AuthInfo authInfo) { 1401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Log.d(TAG, "selected account type " + authInfo.name); 1411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Bundle options = getIntent().getBundleExtra( 1421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE); 1431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana AccountManager.get(this).addAccount(authInfo.desc.type, null, null, options, 1441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana this, this, null); 1451121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1461121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana public void run(final AccountManagerFuture<Bundle> accountManagerFuture) { 1481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana try { 1491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Bundle accountManagerResult = accountManagerFuture.getResult(); 1501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Bundle bundle = new Bundle(); 1511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana bundle.putString(AccountManager.KEY_ACCOUNT_NAME, 1521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME)); 1531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, 1541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE)); 1551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 1561121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana finish(); 1571121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana return; 1581121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } catch (OperationCanceledException e) { 1591121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setResult(Activity.RESULT_CANCELED); 1601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana finish(); 1611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana return; 1621121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } catch (IOException e) { 1631121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } catch (AuthenticatorException e) { 1641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Bundle bundle = new Bundle(); 1661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "error communicating with server"); 1671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana setResult(Activity.RESULT_OK, new Intent().putExtras(bundle)); 1681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana finish(); 1691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private static class AuthInfo { 1721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final AuthenticatorDescription desc; 1731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final String name; 1741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana final Drawable drawable; 1751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) { 1771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana this.desc = desc; 1781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana this.name = name; 1791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana this.drawable = drawable; 1801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private static class ViewHolder { 1841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ImageView icon; 1851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana TextView text; 1861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> { 1891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private LayoutInflater mLayoutInflater; 1901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana private ArrayList<AuthInfo> mInfos; 1911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 1921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana public AccountArrayAdapter(Context context, int textViewResourceId, 1931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ArrayList<AuthInfo> infos) { 1941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana super(context, textViewResourceId, infos); 1951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana mInfos = infos; 1961121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana mLayoutInflater = (LayoutInflater) context.getSystemService( 1971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana Context.LAYOUT_INFLATER_SERVICE); 1981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 1991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 2001121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana @Override 2011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana public View getView(int position, View convertView, ViewGroup parent) { 2021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana ViewHolder holder; 2031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 2041121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana if (convertView == null) { 2051121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null); 2061121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder = new ViewHolder(); 2071121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder.text = (TextView) convertView.findViewById(R.id.account_row_text); 2081121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon); 2091121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana convertView.setTag(holder); 2101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } else { 2111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder = (ViewHolder) convertView.getTag(); 2121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 2131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 2141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder.text.setText(mInfos.get(position).name); 2151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana holder.icon.setImageDrawable(mInfos.get(position).drawable); 2161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana 2171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana return convertView; 2181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 2191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana } 2201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana} 221