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