Clean up launch-time & account setup behaviors.

* Moved welcome message into account setup basics (name/pass)
* Reworked Welcome to go to AccountSetupBasics on count=0
* In AccountFolderList, removed old welcome message code, and add
  code to launch AccountSetupBasics when last account is deleted
* Fixed shortcut picker so launcher shortcuts work again
* Reimplemented shortcut receiver (in MessageList now)
* Default EAS accounts to SSL

Addresses bug 1916583 & 1987440
This commit is contained in:
Andrew Stadler 2009-07-21 11:06:14 -07:00
parent 28fc7799ce
commit 4e4abc645c
9 changed files with 109 additions and 160 deletions

View File

@ -119,14 +119,14 @@
<activity
android:name=".activity.FolderMessageList">
<intent-filter>
<!-- This action is only to allow an entry point for launcher shortcuts -->
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".activity.MessageList">
<intent-filter>
<!-- This action is only to allow an entry point for launcher shortcuts -->
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity

View File

@ -23,34 +23,4 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<LinearLayout
android:id="@+id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/accounts_welcome"
android:textColor="?android:attr/textColorPrimary" />
<View
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="54dip"
android:background="@android:drawable/bottom_bar">
<Button
android:id="@+id/add_new_account"
android:layout_width="wrap_content"
android:minWidth="@dimen/button_minWidth"
android:layout_height="wrap_content"
android:text="@string/next_action"
android:drawableRight="@drawable/button_indicator_next"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>

View File

@ -17,15 +17,23 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TextView
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/accounts_welcome"
android:textColor="?android:attr/textColorPrimary" />
<View
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1" />
<TextView
android:text="@string/account_setup_basics_instructions"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorPrimary"
/>
android:textColor="?android:attr/textColorPrimary" />
<EditText
android:id="@+id/account_email"
android:hint="@string/account_setup_basics_email_hint"

View File

@ -143,8 +143,6 @@
<string name="special_mailbox_display_name_trash">Trash</string>
<!-- In the folder list view, the sent will be displayed with this name -->
<string name="special_mailbox_display_name_sent">Sent</string>
<!-- Text on screen when you don't have any external email accounts set up -->
<string name="accounts_welcome">Welcome to Email setup!\n\nUse any email account with Email.\n\nMost popular email accounts can be set up in 2 steps!</string>
<!-- Version number, shown only on debug screen -->
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
@ -233,8 +231,10 @@
<!-- Title of screen when setting up new email account -->
<string name="account_setup_basics_title">Set up email</string>
<!-- On "Set up email" screen, enthusiastic welcome message. -->
<string name="accounts_welcome">Welcome to Email setup!\n\nUse any email account with Email. Most popular email accounts can be set up in 2 steps!</string>
<!-- On "Set up email" screen, brief instructions -->
<string name="account_setup_basics_instructions">Type your account email address:</string>
<string name="account_setup_basics_instructions">To begin, type your email address and password:</string>
<!-- On "Set up email" screen, hint for account email address text field -->
<string name="account_setup_basics_email_hint">Email address</string>
<!-- On "Set up email" screen, hint for account email password text field -->

View File

@ -60,7 +60,7 @@ import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
public class AccountFolderList extends ExpandableListActivity implements OnClickListener {
public class AccountFolderList extends ExpandableListActivity {
private static final int DIALOG_REMOVE_ACCOUNT = 1;
/**
* Key codes used to open a debug settings screen.
@ -125,8 +125,6 @@ public class AccountFolderList extends ExpandableListActivity implements OnClick
mListView.setLongClickable(true);
registerForContextMenu(mListView);
findViewById(R.id.add_new_account).setOnClickListener(this);
if (icicle != null && icicle.containsKey(ICICLE_SELECTED_ACCOUNT)) {
mSelectedContextAccount = (Account) icicle.getParcelable(ICICLE_SELECTED_ACCOUNT);
}
@ -294,10 +292,6 @@ public class AccountFolderList extends ExpandableListActivity implements OnClick
mListAdapter = new AccountsAdapter(merged, AccountFolderList.this);
mListView.setAdapter(mListAdapter);
// This is deferred until after the first fetch, so it won't flicker
// while we're waiting to find out if we have any accounts
mListView.setEmptyView(findViewById(R.id.empty));
}
}
@ -377,12 +371,6 @@ public class AccountFolderList extends ExpandableListActivity implements OnClick
}
}
public void onClick(View view) {
if (view.getId() == R.id.add_new_account) {
onAddNewAccount();
}
}
private void onDeleteAccount(long accountId) {
mSelectedContextAccount = Account.restoreAccountWithId(this, accountId);
showDialog(DIALOG_REMOVE_ACCOUNT);
@ -432,6 +420,14 @@ public class AccountFolderList extends ExpandableListActivity implements OnClick
// Ignore
}
Email.setServicesEnabled(AccountFolderList.this);
// Jump to account setup if the last/only account was deleted
int numAccounts = EmailContent.count(AccountFolderList.this,
Account.CONTENT_URI, null, null);
if (numAccounts == 0) {
AccountSetupBasics.actionNewAccount(AccountFolderList.this);
finish();
}
}
})
.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {

View File

@ -16,10 +16,10 @@
package com.android.email.activity;
import com.android.email.Email;
import com.android.email.R;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Mailbox;
import android.app.ListActivity;
import android.content.Context;
@ -90,17 +90,13 @@ public class AccountShortcutPicker extends ListActivity implements OnItemClickLi
listView.setAdapter(a);
}
private void onOpenAccount(Account account) {
// generate & return intents
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cursor = (Cursor)parent.getItemAtPosition(position);
Account account = new Account().restore(cursor);
setupShortcut(account);
finish();
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Account account = (Account)parent.getItemAtPosition(position);
onOpenAccount(account);
}
private static class AccountsAdapter extends SimpleCursorAdapter {
public AccountsAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
@ -158,11 +154,11 @@ public class AccountShortcutPicker extends ListActivity implements OnItemClickLi
* with an appropriate Uri for your content, but any Intent will work here as long as it
* triggers the desired action within your Activity.
*/
private void setupShortcut(EmailContent.Account account) {
private void setupShortcut(Account account) {
// First, set up the shortcut intent.
Intent shortcutIntent = FolderMessageList.actionHandleAccountUriIntent(this,
account.mId, Email.INBOX);
Intent shortcutIntent = MessageList.actionHandleAccountUriIntent(this,
account.mId, Mailbox.TYPE_INBOX);
// Then, set up the container intent (the response to the caller)

View File

@ -22,6 +22,7 @@ import com.android.email.Utility;
import com.android.email.activity.setup.AccountSettings;
import com.android.email.mail.MessagingException;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.email.provider.EmailContent.Message;
@ -178,6 +179,23 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
return intent;
}
/**
* Used for generating lightweight (Uri-only) intents.
*
* @param context Calling context for building the intent
* @param accountId The account of interest
* @param mailboxType The folder name to open (typically Mailbox.TYPE_INBOX)
* @return an Intent which can be used to view that account
*/
public static Intent actionHandleAccountUriIntent(Context context, long accountId,
int mailboxType) {
Intent i = actionHandleAccountIntent(context, accountId, mailboxType);
i.removeExtra(EXTRA_ACCOUNT_ID);
Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
i.setData(uri);
return i;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@ -204,17 +222,33 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
// TODO extend this to properly deal with multiple mailboxes, cursor, etc.
// Select 'by id' or 'by type' mode and launch appropriate queries
// Select 'by id' or 'by type' or 'by uri' mode and launch appropriate queries
mMailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, -1);
if (mMailboxId != -1) {
// Specific mailbox ID was provided - go directly to it
mLoadMessagesTask = new LoadMessagesTask(mMailboxId);
mLoadMessagesTask.execute();
} else {
long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
int mailboxType = getIntent().getIntExtra(EXTRA_MAILBOX_TYPE, -1);
mFindMailboxTask = new FindMailboxTask(accountId, mailboxType, true);
mFindMailboxTask.execute();
long accountId = -1;
int mailboxType = getIntent().getIntExtra(EXTRA_MAILBOX_TYPE, Mailbox.TYPE_INBOX);
Uri uri = getIntent().getData();
if (uri != null
&& "content".equals(uri.getScheme())
&& EmailContent.AUTHORITY.equals(uri.getAuthority())) {
// A content URI was provided - try to look up the account
String accountIdString = uri.getPathSegments().get(1);
if (accountIdString != null) {
accountId = Long.parseLong(accountIdString);
}
mFindMailboxTask = new FindMailboxTask(accountId, mailboxType, false);
mFindMailboxTask.execute();
} else {
// Go by account id + type
accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
mFindMailboxTask = new FindMailboxTask(accountId, mailboxType, true);
mFindMailboxTask.execute();
}
}
// TODO set title to "account > mailbox (#unread)"

View File

@ -16,36 +16,32 @@
package com.android.email.activity;
import com.android.email.provider.EmailContent;
import com.android.email.activity.setup.AccountSetupBasics;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.exchange.SyncManager;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
/**
* The Welcome activity initializes the application and decides what Activity
* the user should start with.
* If no accounts are configured the user is taken to the Accounts Activity where they
* If no accounts are configured the user is taken to the AccountSetupBasics Activity where they
* can configure an account.
* If a single account is configured the user is taken directly to the FolderMessageList for
* If a single account is configured the user is taken directly to the MessageList for
* the INBOX of that account.
* If more than one account is configured the user is taken to the Accounts Activity so they
* can select an account.
* If more than one account is configured the user is taken to the AccountFolderList Activity so
* they can select an account.
*/
public class Welcome extends Activity {
private static final boolean DEBUG_ADD_TEST_ACCOUNTS = false; // DO NOT CHECK IN "TRUE"
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (DEBUG_ADD_TEST_ACCOUNTS) {
testAccounts();
}
// TODO Automatically start Exchange service, until we can base this on the existence of
// at least one Exchange account
startService(new Intent(this, SyncManager.class));
@ -54,15 +50,21 @@ public class Welcome extends Activity {
Cursor c = null;
try {
c = getContentResolver().query(
EmailContent.Account.CONTENT_URI,
EmailContent.Account.ID_PROJECTION,
Account.CONTENT_URI,
Account.ID_PROJECTION,
null, null, null);
if (c.getCount() == 1) {
c.moveToFirst();
long accountId = c.getLong(EmailContent.Account.CONTENT_ID_COLUMN);
MessageList.actionHandleAccount(this, accountId, EmailContent.Mailbox.TYPE_INBOX);
finish();
return;
switch (c.getCount()) {
case 0:
AccountSetupBasics.actionNewAccount(this);
break;
case 1:
c.moveToFirst();
long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
MessageList.actionHandleAccount(this, accountId, Mailbox.TYPE_INBOX);
break;
default:
AccountFolderList.actionShowAccounts(this);
break;
}
} finally {
if (c != null) {
@ -70,64 +72,7 @@ public class Welcome extends Activity {
}
}
// Otherwise (n=0 or n>1) go to the account info screen
AccountFolderList.actionShowAccounts(this);
// In all cases, do not return to this activity
finish();
}
private void testAccounts() {
EmailContent.Account acct = EmailContent.Account.getDefaultAccount(this);
Log.i("EmailApp", "Default (none) = " + ((acct == null) ? "none" : acct.mDisplayName));
EmailContent.HostAuth ha = new EmailContent.HostAuth();
ha.mAddress = "imap.everyone.net";
ha.mLogin = "foo@nextobject.com";
ha.mPassword = "flatearth";
ha.mProtocol = "imap";
EmailContent.HostAuth sha = new EmailContent.HostAuth();
sha.mAddress = "smtp.everyone.net";
sha.mLogin = "foo@nextobject.com";
sha.mPassword = "flatearth";
sha.mProtocol = "smtp";
EmailContent.Account acct1 = new EmailContent.Account();
acct1.mHostAuthRecv = ha;
acct1.mHostAuthSend = sha;
acct1.mDisplayName = "Nextobject";
acct1.mEmailAddress = "foo@nextobject.com";
acct1.mIsDefault = true;
acct1.saveOrUpdate(this);
ha = new EmailContent.HostAuth();
ha.mAddress = "imap.gmail.com";
ha.mLogin = "mblank@google.com";
ha.mPassword = "flatearth";
ha.mProtocol = "imap";
sha = new EmailContent.HostAuth();
sha.mAddress = "smtp.gmail.com";
sha.mLogin = "mblank@google.com";
sha.mPassword = "flatearth";
sha.mProtocol = "smtp";
EmailContent.Account acct2 = new EmailContent.Account();
acct2.mHostAuthRecv = ha;
acct2.mHostAuthSend = sha;
acct2.mDisplayName = "Google";
acct2.mEmailAddress = "mblank@google.com";
acct2.mIsDefault = true; // this should supercede the previous one
acct2.saveOrUpdate(this);
// TODO this should move to unit tests of the new Account code
acct = EmailContent.Account.getDefaultAccount(this);
Log.i("EmailApp", "Default (Google) = " + (acct == null ? "none" : acct.mDisplayName));
acct1.setDefaultAccount(true);
acct1.saveOrUpdate(this);
acct = EmailContent.Account.getDefaultAccount(this);
Log.i("EmailApp", "Default (Nextobject) = " + (acct == null ? "none" : acct.mDisplayName));
}
}

View File

@ -19,7 +19,6 @@ package com.android.email.activity.setup;
import com.android.email.R;
import com.android.email.mail.Store;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import android.app.Activity;
@ -43,10 +42,10 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private EmailContent.Account mAccount;
private Account mAccount;
private boolean mMakeDefault;
public static void actionSelectAccountType(Activity fromActivity, EmailContent.Account account,
public static void actionSelectAccountType(Activity fromActivity, Account account,
boolean makeDefault) {
Intent i = new Intent(fromActivity, AccountSetupAccountType.class);
i.putExtra(EXTRA_ACCOUNT, account);
@ -62,7 +61,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
((Button)findViewById(R.id.imap)).setOnClickListener(this);
((Button)findViewById(R.id.exchange)).setOnClickListener(this);
mAccount = (EmailContent.Account)getIntent().getParcelableExtra(EXTRA_ACCOUNT);
mAccount = (Account) getIntent().getParcelableExtra(EXTRA_ACCOUNT);
mMakeDefault = getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false);
if (isExchangeAvailable()) {
@ -103,7 +102,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
}
// Delete policy must be set explicitly, because IMAP does not provide a UI selection
// for it. This logic needs to be followed in the auto setup flow as well.
mAccount.setDeletePolicy(EmailContent.Account.DELETE_POLICY_ON_DELETE);
mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE);
AccountSetupIncoming.actionIncomingSettings(this, mAccount, mMakeDefault);
finish();
}
@ -116,7 +115,8 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
private void onExchange() {
try {
URI uri = new URI(mAccount.getStoreUri(this));
uri = new URI("eas", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
uri = new URI("eas+ssl+", uri.getUserInfo(), uri.getHost(), uri.getPort(),
null, null, null);
mAccount.setStoreUri(this, uri.toString());
mAccount.setSenderUri(this, uri.toString());
} catch (URISyntaxException use) {
@ -126,8 +126,8 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
throw new Error(use);
}
// TODO: Confirm correct delete policy for exchange
mAccount.setDeletePolicy(EmailContent.Account.DELETE_POLICY_ON_DELETE);
mAccount.setAutomaticCheckIntervalMinutes(EmailContent.Account.CHECK_INTERVAL_PUSH);
mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE);
mAccount.setAutomaticCheckIntervalMinutes(Account.CHECK_INTERVAL_PUSH);
mAccount.setSyncWindow(1);
AccountSetupExchange.actionIncomingSettings(this, mAccount, mMakeDefault);
finish();
@ -166,11 +166,11 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
Cursor c = null;
try {
c = this.getContentResolver().query(
EmailContent.Account.CONTENT_URI,
EmailContent.Account.CONTENT_PROJECTION,
Account.CONTENT_URI,
Account.CONTENT_PROJECTION,
null, null, null);
while (c.moveToNext()) {
EmailContent.Account account = EmailContent.getContent(c, Account.class);
Account account = EmailContent.getContent(c, Account.class);
String storeUri = account.getStoreUri(this);
if (storeUri != null && storeUri.startsWith(storeInfo.mScheme)) {
currentAccountsCount++;