From 2ae2a12d6b049a4347c0781bd4daa17229bf1340 Mon Sep 17 00:00:00 2001 From: Andrew Stadler Date: Wed, 18 Aug 2010 11:29:46 -0700 Subject: [PATCH] Initial implementation of SettingsXL (checkpoint) * Create AccountSettingsXL * Build headers dynamically based on accounts * Launch account settings per-account * Temporary launch point from menu in AccountFolderList TODO: Fragment flip to incoming/outgoing/checksettings not implemented yet TODO: Use more recent updates to PreferenceActivity TODO: Finish plumbing into account settings fragment TODO: Something more real for app settings Change-Id: I6f4c5bb8cf691f25517c25950ef2049084335ce3 --- AndroidManifest.xml | 7 + res/menu/account_folder_list_option.xml | 5 + res/values/strings.xml | 10 + res/xml/general_preferences.xml | 32 ++ .../email/activity/AccountFolderList.java | 11 +- .../email/activity/setup/AccountSettings.java | 54 ++-- .../setup/AccountSettingsFragment.java | 134 ++++++-- .../activity/setup/AccountSettingsXL.java | 286 ++++++++++++++++++ 8 files changed, 487 insertions(+), 52 deletions(-) create mode 100644 res/xml/general_preferences.xml create mode 100644 src/com/android/email/activity/setup/AccountSettingsXL.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fbd61f47f..809cedec3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -133,6 +133,13 @@ + + + + + + Email Preferences + + Application Preferences + + Fix All Bugs + + Cheaper than beer + Email 2 Pane diff --git a/res/xml/general_preferences.xml b/res/xml/general_preferences.xml new file mode 100644 index 000000000..7e5dbbfe9 --- /dev/null +++ b/res/xml/general_preferences.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + diff --git a/src/com/android/email/activity/AccountFolderList.java b/src/com/android/email/activity/AccountFolderList.java index fcecbaedb..e6128a558 100644 --- a/src/com/android/email/activity/AccountFolderList.java +++ b/src/com/android/email/activity/AccountFolderList.java @@ -21,6 +21,7 @@ import com.android.email.ControllerResultUiThreadWrapper; import com.android.email.Email; import com.android.email.R; import com.android.email.activity.setup.AccountSettings; +import com.android.email.activity.setup.AccountSettingsXL; import com.android.email.activity.setup.AccountSetupBasics; import com.android.email.mail.MessagingException; import com.android.email.provider.EmailContent; @@ -138,7 +139,12 @@ public class AccountFolderList extends Activity implements AccountFolderListFrag /* Implements AccountFolderListFragment.Callback */ public void onEditAccount(long accountId) { - AccountSettings.actionSettings(this, accountId); + // STOPSHIP - retaining entry point to "old" settings until "new" settings is working + if (accountId >= 0) { + AccountSettings.actionSettings(this, accountId); + } else { + AccountSettingsXL.actionSettings(this, -1); + } } /* Implements AccountFolderListFragment.Callback */ @@ -255,6 +261,9 @@ public class AccountFolderList extends Activity implements AccountFolderListFrag case R.id.compose: onCompose(-1); break; + case R.id.account_settings: + onEditAccount(-1); + break; default: return super.onOptionsItemSelected(item); } diff --git a/src/com/android/email/activity/setup/AccountSettings.java b/src/com/android/email/activity/setup/AccountSettings.java index f425d3567..40a71a874 100644 --- a/src/com/android/email/activity/setup/AccountSettings.java +++ b/src/com/android/email/activity/setup/AccountSettings.java @@ -23,14 +23,13 @@ import com.android.email.mail.Sender; import com.android.email.mail.Store; import com.android.email.provider.EmailContent.Account; import com.android.email.provider.EmailContent.AccountColumns; -import com.android.email.provider.EmailContent.HostAuth; import android.app.Activity; +import android.app.Fragment; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.util.Log; -import android.view.KeyEvent; /** * TODO: This implements preferences for a single account. We need to move this to the @@ -39,7 +38,8 @@ import android.view.KeyEvent; * * TODO: Move all "Restore" ops & other queries out of lifecycle methods and out of UI thread */ -public class AccountSettings extends Activity implements AccountSettingsFragment.Callback { +public class AccountSettings extends Activity + implements AccountSettingsFragment.Callback, AccountSettingsFragment.OnAttachListener { // NOTE: This string must match the one in res/xml/account_preferences.xml private static final String ACTION_ACCOUNT_MANAGER_ENTRY = "com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY"; @@ -53,7 +53,6 @@ public class AccountSettings extends Activity implements AccountSettingsFragment // Account data values private long mAccountId = -1; - private Account mAccount; /** * Display (and edit) settings for a specific account @@ -83,25 +82,12 @@ public class AccountSettings extends Activity implements AccountSettingsFragment return; } - mAccount = Account.restoreAccountWithId(this, mAccountId); - // Similarly, if the account has been deleted - if (mAccount == null) { - finish(); - return; - } - mAccount.mHostAuthRecv = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeyRecv); - mAccount.mHostAuthSend = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeySend); - // Or if HostAuth's have been deleted - if (mAccount.mHostAuthRecv == null || mAccount.mHostAuthSend == null) { - finish(); - return; - } - // Now set up the UI and the fragment setContentView(R.layout.account_settings); - mFragment = (AccountSettingsFragment) findFragmentById(R.id.settings_fragment); + mFragment = (AccountSettingsFragment) + getFragmentManager().findFragmentById(R.id.settings_fragment); mFragment.setCallback(this); - mFragment.setAccount(mAccount); + mFragment.startLoadingAccount(mAccountId); } private void setAccountIdFromAccountManagerIntent() { @@ -134,27 +120,19 @@ public class AccountSettings extends Activity implements AccountSettingsFragment } } - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - mFragment.saveSettings(); - } - return super.onKeyDown(keyCode, event); - } - /** * Implements AccountSettingsFragment.Callback */ @Override - public void onIncomingSettings() { + public void onIncomingSettings(Account account) { try { - Store store = Store.getInstance(mAccount.getStoreUri(this), getApplication(), null); + Store store = Store.getInstance(account.getStoreUri(this), getApplication(), null); if (store != null) { Class setting = store.getSettingActivityClass(); if (setting != null) { java.lang.reflect.Method m = setting.getMethod("actionEditIncomingSettings", Activity.class, int.class, Account.class); - m.invoke(null, this, SetupData.FLOW_MODE_EDIT, mAccount); + m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); } } } catch (Exception e) { @@ -166,15 +144,15 @@ public class AccountSettings extends Activity implements AccountSettingsFragment * Implements AccountSettingsFragment.Callback */ @Override - public void onOutgoingSettings() { + public void onOutgoingSettings(Account account) { try { - Sender sender = Sender.getInstance(getApplication(), mAccount.getSenderUri(this)); + Sender sender = Sender.getInstance(getApplication(), account.getSenderUri(this)); if (sender != null) { Class setting = sender.getSettingActivityClass(); if (setting != null) { java.lang.reflect.Method m = setting.getMethod("actionEditOutgoingSettings", Activity.class, int.class, Account.class); - m.invoke(null, this, SetupData.FLOW_MODE_EDIT, mAccount); + m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); } } } catch (Exception e) { @@ -189,4 +167,12 @@ public class AccountSettings extends Activity implements AccountSettingsFragment public void abandonEdit() { finish(); } + + /** + * Implements AccountSettingsFragment.OnAttachListener + * Does nothing (this activity sets up the fragment in onCreate via its layout) + */ + @Override + public void onAttach(Fragment f) { + } } diff --git a/src/com/android/email/activity/setup/AccountSettingsFragment.java b/src/com/android/email/activity/setup/AccountSettingsFragment.java index a417140dd..cc5746645 100644 --- a/src/com/android/email/activity/setup/AccountSettingsFragment.java +++ b/src/com/android/email/activity/setup/AccountSettingsFragment.java @@ -18,6 +18,7 @@ package com.android.email.activity.setup; import com.android.email.Email; import com.android.email.R; +import com.android.email.Utility; import com.android.email.mail.MessagingException; import com.android.email.mail.Sender; import com.android.email.mail.Store; @@ -25,9 +26,11 @@ import com.android.email.provider.EmailContent.Account; import com.android.email.provider.EmailContent.HostAuth; import android.app.Activity; +import android.app.Fragment; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; @@ -45,10 +48,16 @@ import android.util.Log; * fragments for server settings. * * TODO: Move all "Restore" ops & other queries out of lifecycle methods and out of UI thread + * TODO: Can we defer calling addPreferencesFromResource() until after we load the account? This + * could reduce flicker. * * STOPSHIP: Remove fragment lifecycle logging */ public class AccountSettingsFragment extends PreferenceFragment { + + // Keys used for arguments bundle + private static final String BUNDLE_KEY_ACCOUNT_ID = "AccountSettingsFragment.AccountId"; + private static final String PREFERENCE_TOP_CATEGORY = "account_settings"; private static final String PREFERENCE_DESCRIPTION = "account_description"; private static final String PREFERENCE_NAME = "account_name"; @@ -87,23 +96,58 @@ public class AccountSettingsFragment extends PreferenceFragment { private Callback mCallback = EmptyCallback.INSTANCE; private boolean mStarted; private boolean mLoaded; + private boolean mSaveOnExit; + + // Async Tasks + private AsyncTask mLoadAccountTask; /** - * Callback interface that owning activities must implement + * Callback interface that owning activities must provide */ public interface Callback { - public void onIncomingSettings(); - public void onOutgoingSettings(); + public void onIncomingSettings(Account account); + public void onOutgoingSettings(Account account); public void abandonEdit(); } private static class EmptyCallback implements Callback { public static final Callback INSTANCE = new EmptyCallback(); - @Override public void onIncomingSettings() { } - @Override public void onOutgoingSettings() { } + @Override public void onIncomingSettings(Account account) { } + @Override public void onOutgoingSettings(Account account) { } @Override public void abandonEdit() { } } + /** + * Callback interface that owning activities must implement + */ + public interface OnAttachListener { + public void onAttach(Fragment f); + } + + /** + * If launching with an arguments bundle, use this method to build the arguments. + * @param accountId The account being modified + */ + public static Bundle buildArguments(long accountId) { + Bundle b = new Bundle(); + b.putLong(BUNDLE_KEY_ACCOUNT_ID, accountId); + return b; + } + + /** + * Called when a fragment is first attached to its activity. + * {@link #onCreate(Bundle)} will be called after this. + */ + public void onAttach(Activity activity) { + super.onAttach(activity); + + mContext = activity; + + // Notify the activity that we're here. Single-pane preference activities ignore this; + // multi-pane settings uses this as a trigger to attach the account info + ((OnAttachListener)activity).onAttach(this); + } + /** * Called to do initial creation of a fragment. This is called after * {@link #onAttach(Activity)} and before {@link #onActivityCreated(Bundle)}. @@ -117,6 +161,16 @@ public class AccountSettingsFragment extends PreferenceFragment { // Load the preferences from an XML resource addPreferencesFromResource(R.xml.account_settings_preferences); + + // Start loading the account data, if provided in the arguments + // If not, activity must call startLoadingAccount() directly + Bundle b = getArguments(); + if (b != null) { + long accountId = b.getLong(BUNDLE_KEY_ACCOUNT_ID, -1); + if (accountId >= 0 && !mLoaded) { + startLoadingAccount(accountId); + } + } } @Override @@ -139,6 +193,8 @@ public class AccountSettingsFragment extends PreferenceFragment { } super.onStart(); mStarted = true; + + // If the loaded account is ready now, load the UI if (mAccount != null && !mLoaded) { loadSettings(); } @@ -167,6 +223,7 @@ public class AccountSettingsFragment extends PreferenceFragment { Account refreshedAccount = Account.restoreAccountWithId(mContext, mAccount.mId); if (refreshedAccount == null || mAccount.mHostAuthRecv == null || mAccount.mHostAuthSend == null) { + mSaveOnExit = false; mCallback.abandonEdit(); return; } @@ -204,6 +261,15 @@ public class AccountSettingsFragment extends PreferenceFragment { Log.d(Email.LOG_TAG, "MailboxListFragment onDestroy"); } super.onDestroy(); + + Utility.cancelTaskInterrupt(mLoadAccountTask); + mLoadAccountTask = null; + + // If there is good account data and we have not abandoned it, save it now + if (mSaveOnExit) { + saveSettings(); + mSaveOnExit = false; + } } @Override @@ -222,18 +288,46 @@ public class AccountSettingsFragment extends PreferenceFragment { } /** - * Set the account, and start loading if ready to. Note, this is a one-shot, because - * once we mutate the preferences UX to match the account provided, we cannot re-mute - * it (the fragment must be replaced.) + * Start loading a single account in preparation for editing it */ - public void setAccount(Account account) { - if (mAccount != null) { - throw new IllegalStateException(); + public void startLoadingAccount(long accountId) { + Utility.cancelTaskInterrupt(mLoadAccountTask); + mLoadAccountTask = new LoadAccountTask().execute(accountId); + } + + /** + * Async task to load account in order to view/edit it + */ + private class LoadAccountTask extends AsyncTask { + @Override + protected Account doInBackground(Long... params) { + long accountId = params[0]; + Account account = Account.restoreAccountWithId(mContext, accountId); + if (account != null) { + account.mHostAuthRecv = + HostAuth.restoreHostAuthWithId(mContext, account.mHostAuthKeyRecv); + account.mHostAuthSend = + HostAuth.restoreHostAuthWithId(mContext, account.mHostAuthKeySend); + if (account.mHostAuthRecv == null || account.mHostAuthSend == null) { + account = null; + } + } + return account; } - mAccount = account; - mContext = getActivity(); - if (mStarted && !mLoaded) { - loadSettings(); + + @Override + protected void onPostExecute(Account account) { + if (!isCancelled()) { + if (account == null) { + mSaveOnExit = false; + mCallback.abandonEdit(); + } else { + mAccount = account; + if (mStarted && !mLoaded) { + loadSettings(); + } + } + } } } @@ -243,6 +337,8 @@ public class AccountSettingsFragment extends PreferenceFragment { private void loadSettings() { // We can only do this once, so prevent repeat mLoaded = true; + // Once loaded the data is ready to be saved, as well + mSaveOnExit = true; PreferenceCategory topCategory = (PreferenceCategory) findPreference(PREFERENCE_TOP_CATEGORY); @@ -360,7 +456,7 @@ public class AccountSettingsFragment extends PreferenceFragment { new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { mAccountDirty = true; - mCallback.onIncomingSettings(); + mCallback.onIncomingSettings(mAccount); return true; } }); @@ -382,7 +478,7 @@ public class AccountSettingsFragment extends PreferenceFragment { new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { mAccountDirty = true; - mCallback.onOutgoingSettings(); + mCallback.onOutgoingSettings(mAccount); return true; } }); @@ -409,6 +505,10 @@ public class AccountSettingsFragment extends PreferenceFragment { } } + /* + * TODO: Should collect the data in the UI thread, but should spin out a thread to write + * to sync settings, provider, and service enabler. + */ public void saveSettings() { int newFlags = mAccount.getFlags() & ~(Account.FLAGS_NOTIFY_NEW_MAIL | diff --git a/src/com/android/email/activity/setup/AccountSettingsXL.java b/src/com/android/email/activity/setup/AccountSettingsXL.java new file mode 100644 index 000000000..e66bfb162 --- /dev/null +++ b/src/com/android/email/activity/setup/AccountSettingsXL.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.email.activity.setup; + +import com.android.email.Email; +import com.android.email.R; +import com.android.email.Utility; +import com.android.email.mail.Sender; +import com.android.email.mail.Store; +import com.android.email.provider.EmailContent; +import com.android.email.provider.EmailContent.Account; + +import android.app.Activity; +import android.app.Fragment; +import android.content.Intent; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.preference.PreferenceFragment; +import android.util.Log; + +import java.util.List; + +/** + * Handles account preferences using multi-pane arrangement when possible. + * + * TODO: Incorporate entry point & other stuff to support launch from AccountManager + * TODO: In Account settings in Phone UI, change title + * TODO: Action bar? Need to work out the handling of next/back type buttons + */ +public class AccountSettingsXL extends PreferenceActivity + implements AccountSettingsFragment.OnAttachListener { + + private static final String EXTRA_ACCOUNT_ID = "AccountSettingsXL.account_id"; + + private long mAccountId; + private Header[] mAccountListHeaders; + private Header mAppPreferencesHeader; + private int mCurrentHeaderPosition; + private Fragment mCurrentFragment; + + // Async Tasks + private LoadAccountListTask mLoadAccountListTask; + + // Specific callbacks used by settings fragments + private AccountSettingsFragmentCallback mAccountSettingsFragmentCallback + = new AccountSettingsFragmentCallback(); + + /** + * Display (and edit) settings for a specific account, or -1 for any/all accounts + */ + public static void actionSettings(Activity fromActivity, long accountId) { + Intent i = new Intent(fromActivity, AccountSettingsXL.class); + i.putExtra(EXTRA_ACCOUNT_ID, accountId); + fromActivity.startActivity(i); + } + + /** + * Header for general app preferences + */ + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent i = getIntent(); + mAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); + } + + @Override + public void onResume() { + super.onResume(); + updateAccounts(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Utility.cancelTaskInterrupt(mLoadAccountListTask); + mLoadAccountListTask = null; + } + + /** + * Start the async reload of the accounts list (if the headers are being displayed) + */ + private void updateAccounts() { + if (hasHeaders()) { + Utility.cancelTaskInterrupt(mLoadAccountListTask); + mLoadAccountListTask = (LoadAccountListTask) new LoadAccountListTask().execute(); + } + } + + /** + * Write the current header (accounts) array into the one provided by the PreferenceActivity. + */ + @Override + public void onBuildHeaders(List
target) { + // Set up fixed header for general settings + if (mAppPreferencesHeader == null) { + mAppPreferencesHeader = new Header(); + mAppPreferencesHeader.title = getText(R.string.header_label_general_preferences); + mAppPreferencesHeader.summary = null; + mAppPreferencesHeader.iconRes = 0; + mAppPreferencesHeader.icon = null; + mAppPreferencesHeader.fragment = GeneralPreferences.getCanonicalName(); + mAppPreferencesHeader.fragmentArguments = null; + } + target.clear(); + target.add(mAppPreferencesHeader); + if (mAccountListHeaders != null) { + int headerCount = mAccountListHeaders.length; + for (int index = 0; index < headerCount; index++) { + target.add(mAccountListHeaders[index]); + } + } + } + + /** + * This AsyncTask reads the accounts list and generates the headers. When the headers are + * ready, we'll trigger PreferenceActivity to refresh the account list with them. + * + * TODO: Smaller projection + * TODO: Convert to Loader + */ + private class LoadAccountListTask extends AsyncTask { + + @Override + protected Header[] doInBackground(Void... params) { + Header[] result = null; + + Cursor c = getContentResolver().query( + EmailContent.Account.CONTENT_URI, + EmailContent.Account.CONTENT_PROJECTION, null, null, null); + try { + int index = 0; + int headerCount = c.getCount(); + result = new Header[headerCount]; + + while (c.moveToNext()) { + String title = c.getString(Account.CONTENT_DISPLAY_NAME_COLUMN); + String summary = c.getString(Account.CONTENT_EMAIL_ADDRESS_COLUMN); + long accountId = c.getLong(Account.CONTENT_ID_COLUMN); + Header newHeader = new Header(); + newHeader.title = title; + newHeader.summary = summary; + newHeader.fragment = AccountSettingsFragment.class.getCanonicalName(); + newHeader.fragmentArguments = AccountSettingsFragment.buildArguments(accountId); + result[index++] = newHeader; + } + } finally { + if (c != null) { + c.close(); + } + } + return result; + } + + @Override + protected void onPostExecute(Header[] headers) { + mAccountListHeaders = headers; + AccountSettingsXL.this.invalidateHeaders(); + } + } + + /** + * Called when the user selects an item in the header list. Handles save-data cases as needed + * + * @param header The header that was selected. + * @param position The header's position in the list. + */ + @Override + public void onHeaderClick(Header header, int position) { + if (position != mCurrentHeaderPosition) { + // if showing a sub-panel (e.g. server settings) we need to trap & post a dialog + } + super.onHeaderClick(header, position); + } + + /** + * Implements AccountSettingsFragment.OnAttachListener + */ + @Override + public void onAttach(Fragment f) { + mCurrentFragment = f; + // dispatch per-fragment setup + if (f instanceof AccountSettingsFragment) { + AccountSettingsFragment asf = (AccountSettingsFragment) f; + asf.setCallback(mAccountSettingsFragmentCallback); + } else if (f instanceof AccountSetupIncomingFragment) { + // TODO + } else if (f instanceof AccountSetupOutgoingFragment) { + // TODO + } else if (f instanceof AccountSetupExchangeFragment) { + // TODO + } + } + + /** + * Callbacks for AccountSettingsFragment + */ + private class AccountSettingsFragmentCallback implements AccountSettingsFragment.Callback { + public void onIncomingSettings(Account account) { + AccountSettingsXL.this.onIncomingSettings(account); + } + public void onOutgoingSettings(Account account) { + AccountSettingsXL.this.onOutgoingSettings(account); + } + public void abandonEdit() { + finish(); + } + } + + /** + * STOPSHIP: non-fragmented dispatch to edit incoming settings. Replace with fragment flip. + */ + public void onIncomingSettings(Account account) { + try { + Store store = Store.getInstance(account.getStoreUri(this), getApplication(), null); + if (store != null) { + Class setting = store.getSettingActivityClass(); + if (setting != null) { + java.lang.reflect.Method m = setting.getMethod("actionEditIncomingSettings", + Activity.class, int.class, Account.class); + m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); + } + } + } catch (Exception e) { + Log.d(Email.LOG_TAG, "Error while trying to invoke store settings.", e); + } + } + + /** + * STOPSHIP: non-fragmented dispatch to edit outgoing settings. Replace with fragment flip. + */ + public void onOutgoingSettings(Account account) { + try { + Sender sender = Sender.getInstance(getApplication(), account.getSenderUri(this)); + if (sender != null) { + Class setting = sender.getSettingActivityClass(); + if (setting != null) { + java.lang.reflect.Method m = setting.getMethod("actionEditOutgoingSettings", + Activity.class, int.class, Account.class); + m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); + } + } + } catch (Exception e) { + Log.d(Email.LOG_TAG, "Error while trying to invoke sender settings.", e); + } + } + + /** + * Placeholder for app-wide preferences + * STOPSHIP - make this real + */ + public static class GeneralPreferences extends PreferenceFragment { + + /** STOPSHIP - this is hardcoded for now because getCanonicalName() doesn't return $ */ + public static String getCanonicalName() { + return "com.android.email.activity.setup.AccountSettingsXL$GeneralPreferences"; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.general_preferences); + } + } + +}