AccountSettings.java revision 9e2ddca59d048fc9ac55278b193ee36b330a7981
1/* 2 * Copyright (C) 2008 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 */ 16 17package com.android.email.activity.setup; 18 19import com.android.email.Email; 20import com.android.email.R; 21import com.android.email.mail.MessagingException; 22import com.android.email.mail.Sender; 23import com.android.email.mail.Store; 24import com.android.email.provider.EmailContent.Account; 25import com.android.email.provider.EmailContent.AccountColumns; 26import com.android.email.provider.EmailContent.HostAuth; 27 28import android.app.Activity; 29import android.content.ContentResolver; 30import android.content.Intent; 31import android.content.SharedPreferences; 32import android.database.Cursor; 33import android.os.Bundle; 34import android.preference.CheckBoxPreference; 35import android.preference.EditTextPreference; 36import android.preference.ListPreference; 37import android.preference.Preference; 38import android.preference.PreferenceActivity; 39import android.preference.PreferenceCategory; 40import android.preference.RingtonePreference; 41import android.provider.Calendar; 42import android.provider.ContactsContract; 43import android.util.Log; 44import android.view.KeyEvent; 45 46public class AccountSettings extends PreferenceActivity { 47 private static final String PREFERENCE_TOP_CATEGORY = "account_settings"; 48 private static final String PREFERENCE_DESCRIPTION = "account_description"; 49 private static final String PREFERENCE_NAME = "account_name"; 50 private static final String PREFERENCE_SIGNATURE = "account_signature"; 51 private static final String PREFERENCE_FREQUENCY = "account_check_frequency"; 52 private static final String PREFERENCE_DEFAULT = "account_default"; 53 private static final String PREFERENCE_NOTIFY = "account_notify"; 54 private static final String PREFERENCE_VIBRATE_WHEN = "account_settings_vibrate_when"; 55 private static final String PREFERENCE_RINGTONE = "account_ringtone"; 56 private static final String PREFERENCE_SERVER_CATERGORY = "account_servers"; 57 private static final String PREFERENCE_INCOMING = "incoming"; 58 private static final String PREFERENCE_OUTGOING = "outgoing"; 59 private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts"; 60 private static final String PREFERENCE_SYNC_CALENDAR = "account_sync_calendar"; 61 62 // These strings must match account_settings_vibrate_when_* strings in strings.xml 63 private static final String PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS = "always"; 64 private static final String PREFERENCE_VALUE_VIBRATE_WHEN_SILENT = "silent"; 65 private static final String PREFERENCE_VALUE_VIBRATE_WHEN_NEVER = "never"; 66 67 // NOTE: This string must match the one in res/xml/account_preferences.xml 68 public static final String ACTION_ACCOUNT_MANAGER_ENTRY = 69 "com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY"; 70 // NOTE: This constant should eventually be defined in android.accounts.Constants, but for 71 // now we define it here 72 private static final String ACCOUNT_MANAGER_EXTRA_ACCOUNT = "account"; 73 private static final String EXTRA_ACCOUNT_ID = "account_id"; 74 75 private long mAccountId = -1; 76 private Account mAccount; 77 private boolean mAccountDirty; 78 79 private EditTextPreference mAccountDescription; 80 private EditTextPreference mAccountName; 81 private EditTextPreference mAccountSignature; 82 private ListPreference mCheckFrequency; 83 private ListPreference mSyncWindow; 84 private CheckBoxPreference mAccountDefault; 85 private CheckBoxPreference mAccountNotify; 86 private ListPreference mAccountVibrateWhen; 87 private RingtonePreference mAccountRingtone; 88 private CheckBoxPreference mSyncContacts; 89 private CheckBoxPreference mSyncCalendar; 90 91 /** 92 * Display (and edit) settings for a specific account 93 */ 94 public static void actionSettings(Activity fromActivity, long accountId) { 95 Intent i = new Intent(fromActivity, AccountSettings.class); 96 i.putExtra(EXTRA_ACCOUNT_ID, accountId); 97 fromActivity.startActivity(i); 98 } 99 100 @Override 101 public void onCreate(Bundle savedInstanceState) { 102 super.onCreate(savedInstanceState); 103 104 Intent i = getIntent(); 105 if (ACTION_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) { 106 // This case occurs if we're changing account settings from Settings -> Accounts 107 setAccountIdFromAccountManagerIntent(); 108 } else { 109 // Otherwise, we're called from within the Email app and look for our extra 110 mAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); 111 } 112 113 // If there's no accountId, we're done 114 if (mAccountId == -1) { 115 finish(); 116 return; 117 } 118 119 mAccount = Account.restoreAccountWithId(this, mAccountId); 120 // Similarly, if the account has been deleted 121 if (mAccount == null) { 122 finish(); 123 return; 124 } 125 mAccount.mHostAuthRecv = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeyRecv); 126 mAccount.mHostAuthSend = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeySend); 127 // Or if HostAuth's have been deleted 128 if (mAccount.mHostAuthRecv == null || mAccount.mHostAuthSend == null) { 129 finish(); 130 return; 131 } 132 mAccountDirty = false; 133 134 addPreferencesFromResource(R.xml.account_settings_preferences); 135 136 PreferenceCategory topCategory = (PreferenceCategory) findPreference(PREFERENCE_TOP_CATEGORY); 137 topCategory.setTitle(getString(R.string.account_settings_title_fmt)); 138 139 mAccountDescription = (EditTextPreference) findPreference(PREFERENCE_DESCRIPTION); 140 mAccountDescription.setSummary(mAccount.getDisplayName()); 141 mAccountDescription.setText(mAccount.getDisplayName()); 142 mAccountDescription.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 143 public boolean onPreferenceChange(Preference preference, Object newValue) { 144 final String summary = newValue.toString(); 145 mAccountDescription.setSummary(summary); 146 mAccountDescription.setText(summary); 147 return false; 148 } 149 }); 150 151 mAccountName = (EditTextPreference) findPreference(PREFERENCE_NAME); 152 mAccountName.setSummary(mAccount.getSenderName()); 153 mAccountName.setText(mAccount.getSenderName()); 154 mAccountName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 155 public boolean onPreferenceChange(Preference preference, Object newValue) { 156 final String summary = newValue.toString(); 157 mAccountName.setSummary(summary); 158 mAccountName.setText(summary); 159 return false; 160 } 161 }); 162 163 mAccountSignature = (EditTextPreference) findPreference(PREFERENCE_SIGNATURE); 164 mAccountSignature.setSummary(mAccount.getSignature()); 165 mAccountSignature.setText(mAccount.getSignature()); 166 mAccountSignature.setOnPreferenceChangeListener( 167 new Preference.OnPreferenceChangeListener() { 168 public boolean onPreferenceChange(Preference preference, Object newValue) { 169 String summary = newValue.toString(); 170 if (summary == null || summary.length() == 0) { 171 mAccountSignature.setSummary(R.string.account_settings_signature_hint); 172 } else { 173 mAccountSignature.setSummary(summary); 174 } 175 mAccountSignature.setText(summary); 176 return false; 177 } 178 }); 179 180 mCheckFrequency = (ListPreference) findPreference(PREFERENCE_FREQUENCY); 181 182 // Before setting value, we may need to adjust the lists 183 Store.StoreInfo info = Store.StoreInfo.getStoreInfo(mAccount.getStoreUri(this), this); 184 if (info.mPushSupported) { 185 mCheckFrequency.setEntries(R.array.account_settings_check_frequency_entries_push); 186 mCheckFrequency.setEntryValues(R.array.account_settings_check_frequency_values_push); 187 } 188 189 mCheckFrequency.setValue(String.valueOf(mAccount.getSyncInterval())); 190 mCheckFrequency.setSummary(mCheckFrequency.getEntry()); 191 mCheckFrequency.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 192 public boolean onPreferenceChange(Preference preference, Object newValue) { 193 final String summary = newValue.toString(); 194 int index = mCheckFrequency.findIndexOfValue(summary); 195 mCheckFrequency.setSummary(mCheckFrequency.getEntries()[index]); 196 mCheckFrequency.setValue(summary); 197 return false; 198 } 199 }); 200 201 // Add check window preference 202 mSyncWindow = null; 203 if (info.mVisibleLimitDefault == -1) { 204 mSyncWindow = new ListPreference(this); 205 mSyncWindow.setTitle(R.string.account_setup_options_mail_window_label); 206 mSyncWindow.setEntries(R.array.account_settings_mail_window_entries); 207 mSyncWindow.setEntryValues(R.array.account_settings_mail_window_values); 208 mSyncWindow.setValue(String.valueOf(mAccount.getSyncLookback())); 209 mSyncWindow.setSummary(mSyncWindow.getEntry()); 210 mSyncWindow.setOrder(4); 211 mSyncWindow.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 212 public boolean onPreferenceChange(Preference preference, Object newValue) { 213 final String summary = newValue.toString(); 214 int index = mSyncWindow.findIndexOfValue(summary); 215 mSyncWindow.setSummary(mSyncWindow.getEntries()[index]); 216 mSyncWindow.setValue(summary); 217 return false; 218 } 219 }); 220 topCategory.addPreference(mSyncWindow); 221 } 222 223 mAccountDefault = (CheckBoxPreference) findPreference(PREFERENCE_DEFAULT); 224 mAccountDefault.setChecked(mAccount.mId == Account.getDefaultAccountId(this)); 225 226 mAccountNotify = (CheckBoxPreference) findPreference(PREFERENCE_NOTIFY); 227 mAccountNotify.setChecked(0 != (mAccount.getFlags() & Account.FLAGS_NOTIFY_NEW_MAIL)); 228 229 mAccountRingtone = (RingtonePreference) findPreference(PREFERENCE_RINGTONE); 230 231 // XXX: The following two lines act as a workaround for the RingtonePreference 232 // which does not let us set/get the value programmatically 233 SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences(); 234 prefs.edit().putString(PREFERENCE_RINGTONE, mAccount.getRingtone()).commit(); 235 236 mAccountVibrateWhen = (ListPreference) findPreference(PREFERENCE_VIBRATE_WHEN); 237 boolean flagsVibrate = 0 != (mAccount.getFlags() & Account.FLAGS_VIBRATE_ALWAYS); 238 boolean flagsVibrateSilent = 0 != (mAccount.getFlags() & Account.FLAGS_VIBRATE_WHEN_SILENT); 239 mAccountVibrateWhen.setValue( 240 flagsVibrate ? PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS : 241 flagsVibrateSilent ? PREFERENCE_VALUE_VIBRATE_WHEN_SILENT : 242 PREFERENCE_VALUE_VIBRATE_WHEN_NEVER); 243 244 findPreference(PREFERENCE_INCOMING).setOnPreferenceClickListener( 245 new Preference.OnPreferenceClickListener() { 246 public boolean onPreferenceClick(Preference preference) { 247 onIncomingSettings(); 248 return true; 249 } 250 }); 251 252 // Hide the outgoing account setup link if it's not activated 253 Preference prefOutgoing = findPreference(PREFERENCE_OUTGOING); 254 boolean showOutgoing = true; 255 try { 256 Sender sender = Sender.getInstance(getApplication(), mAccount.getSenderUri(this)); 257 if (sender != null) { 258 Class<? extends android.app.Activity> setting = sender.getSettingActivityClass(); 259 showOutgoing = (setting != null); 260 } 261 } catch (MessagingException me) { 262 // just leave showOutgoing as true - bias towards showing it, so user can fix it 263 } 264 if (showOutgoing) { 265 prefOutgoing.setOnPreferenceClickListener( 266 new Preference.OnPreferenceClickListener() { 267 public boolean onPreferenceClick(Preference preference) { 268 onOutgoingSettings(); 269 return true; 270 } 271 }); 272 } else { 273 PreferenceCategory serverCategory = (PreferenceCategory) findPreference( 274 PREFERENCE_SERVER_CATERGORY); 275 serverCategory.removePreference(prefOutgoing); 276 } 277 278 mSyncContacts = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CONTACTS); 279 mSyncCalendar = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CALENDAR); 280 if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) { 281 android.accounts.Account acct = new android.accounts.Account(mAccount.mEmailAddress, 282 Email.EXCHANGE_ACCOUNT_MANAGER_TYPE); 283 mSyncContacts.setChecked(ContentResolver 284 .getSyncAutomatically(acct, ContactsContract.AUTHORITY)); 285 mSyncCalendar.setChecked(ContentResolver 286 .getSyncAutomatically(acct, Calendar.AUTHORITY)); 287 } else { 288 PreferenceCategory serverCategory = (PreferenceCategory) findPreference( 289 PREFERENCE_SERVER_CATERGORY); 290 serverCategory.removePreference(mSyncContacts); 291 serverCategory.removePreference(mSyncCalendar); 292 } 293 } 294 295 private void setAccountIdFromAccountManagerIntent() { 296 // First, get the AccountManager account that we've been ask to handle 297 android.accounts.Account acct = 298 (android.accounts.Account)getIntent() 299 .getParcelableExtra(ACCOUNT_MANAGER_EXTRA_ACCOUNT); 300 // Find a HostAuth using eas and whose login is klthe name of the AccountManager account 301 Cursor c = getContentResolver().query(Account.CONTENT_URI, 302 new String[] {AccountColumns.ID}, AccountColumns.EMAIL_ADDRESS + "=?", 303 new String[] {acct.name}, null); 304 try { 305 if (c.moveToFirst()) { 306 mAccountId = c.getLong(0); 307 } 308 } finally { 309 c.close(); 310 } 311 } 312 313 @Override 314 public void onResume() { 315 super.onResume(); 316 if (mAccountDirty) { 317 // if we are coming back from editing incoming or outgoing settings, 318 // we need to refresh them here so we don't accidentally overwrite the 319 // old values we're still holding here 320 mAccount.mHostAuthRecv = 321 HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeyRecv); 322 mAccount.mHostAuthSend = 323 HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeySend); 324 // Because "delete policy" UI is on edit incoming settings, we have 325 // to refresh that as well. 326 Account refreshedAccount = Account.restoreAccountWithId(this, mAccount.mId); 327 if (refreshedAccount == null || mAccount.mHostAuthRecv == null 328 || mAccount.mHostAuthSend == null) { 329 finish(); 330 return; 331 } 332 mAccount.setDeletePolicy(refreshedAccount.getDeletePolicy()); 333 mAccountDirty = false; 334 } 335 } 336 337 private void saveSettings() { 338 int newFlags = mAccount.getFlags() & 339 ~(Account.FLAGS_NOTIFY_NEW_MAIL | 340 Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_VIBRATE_WHEN_SILENT); 341 342 mAccount.setDefaultAccount(mAccountDefault.isChecked()); 343 mAccount.setDisplayName(mAccountDescription.getText()); 344 mAccount.setSenderName(mAccountName.getText()); 345 mAccount.setSignature(mAccountSignature.getText()); 346 newFlags |= mAccountNotify.isChecked() ? Account.FLAGS_NOTIFY_NEW_MAIL : 0; 347 mAccount.setSyncInterval(Integer.parseInt(mCheckFrequency.getValue())); 348 if (mSyncWindow != null) { 349 mAccount.setSyncLookback(Integer.parseInt(mSyncWindow.getValue())); 350 } 351 if (mAccountVibrateWhen.getValue().equals(PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS)) { 352 newFlags |= Account.FLAGS_VIBRATE_ALWAYS; 353 } else if (mAccountVibrateWhen.getValue().equals(PREFERENCE_VALUE_VIBRATE_WHEN_SILENT)) { 354 newFlags |= Account.FLAGS_VIBRATE_WHEN_SILENT; 355 } 356 SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences(); 357 mAccount.setRingtone(prefs.getString(PREFERENCE_RINGTONE, null)); 358 mAccount.setFlags(newFlags); 359 360 if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) { 361 android.accounts.Account acct = new android.accounts.Account(mAccount.mEmailAddress, 362 Email.EXCHANGE_ACCOUNT_MANAGER_TYPE); 363 ContentResolver.setSyncAutomatically(acct, ContactsContract.AUTHORITY, 364 mSyncContacts.isChecked()); 365 ContentResolver.setSyncAutomatically(acct, Calendar.AUTHORITY, 366 mSyncCalendar.isChecked()); 367 368 } 369 AccountSettingsUtils.commitSettings(this, mAccount); 370 Email.setServicesEnabled(this); 371 } 372 373 @Override 374 public boolean onKeyDown(int keyCode, KeyEvent event) { 375 if (keyCode == KeyEvent.KEYCODE_BACK) { 376 saveSettings(); 377 } 378 return super.onKeyDown(keyCode, event); 379 } 380 381 private void onIncomingSettings() { 382 try { 383 Store store = Store.getInstance(mAccount.getStoreUri(this), getApplication(), null); 384 if (store != null) { 385 Class<? extends android.app.Activity> setting = store.getSettingActivityClass(); 386 if (setting != null) { 387 java.lang.reflect.Method m = setting.getMethod("actionEditIncomingSettings", 388 android.app.Activity.class, Account.class); 389 m.invoke(null, this, mAccount); 390 mAccountDirty = true; 391 } 392 } 393 } catch (Exception e) { 394 Log.d(Email.LOG_TAG, "Error while trying to invoke store settings.", e); 395 } 396 } 397 398 private void onOutgoingSettings() { 399 try { 400 Sender sender = Sender.getInstance(getApplication(), mAccount.getSenderUri(this)); 401 if (sender != null) { 402 Class<? extends android.app.Activity> setting = sender.getSettingActivityClass(); 403 if (setting != null) { 404 java.lang.reflect.Method m = setting.getMethod("actionEditOutgoingSettings", 405 android.app.Activity.class, Account.class); 406 m.invoke(null, this, mAccount); 407 mAccountDirty = true; 408 } 409 } 410 } catch (Exception e) { 411 Log.d(Email.LOG_TAG, "Error while trying to invoke sender settings.", e); 412 } 413 } 414} 415