项目需求: 如题
kk版本
修改文件:
M packages/apps/Email/res/xml/providers.xml
M packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java
修改内容:
Index: packages/apps/Email/res/xml/providers.xml
===================================================================
--- packages/apps/Email/res/xml/providers.xml (revision 134)
+++ packages/apps/Email/res/xml/providers.xml (working copy)
@@ -465,4 +465,8 @@
<incoming uri="imap+ssl+://android.imap.mail.yahoo.com" username="$email" />
<outgoing uri="smtp+ssl+://android.smtp.mail.yahoo.com" username="$email" />
</provider>
+ <provider id="gaj" label="gaj" domain="gaj.cq">
+ <incoming uri="pop3+://127.0.0.1:7001" username="$email" /> <!-- 注: <span style="font-family: Arial, Helvetica, sans-serif;">pop3+ 没有ssl是安全类型为 无 </span><span style="font-family: Arial, Helvetica, sans-serif;"> :7001为port 花了n久验证才搞清楚的 --></span>
+ <outgoing uri="smtp+://127.0.0.1:7002" username="$email" />
+ </provider>
</providers>
Index: packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java
===================================================================
--- packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java (revision 134)
+++ packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java (working copy)
@@ -60,6 +60,30 @@
import java.util.Map;
import java.util.Set;
+
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.FragmentTransaction;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.RemoteException;
+import com.android.email.activity.setup.AccountCheckSettingsFragment;
+import com.android.email.activity.setup.AccountSettingsUtils;
+import com.android.email.activity.setup.AccountSetupOptions;
+import com.android.email.activity.setup.DuplicateAccountDialogFragment;
+import com.android.email.activity.setup.SetupData;
+import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
+import com.android.emailcommon.VendorPolicyLoader.Provider;
+import com.android.emailcommon.service.EmailServiceProxy;
+import com.android.emailcommon.utility.AsyncTask;
+import com.android.emailcommon.utility.Utility;
+import com.android.mail.preferences.AccountPreferences;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
/**
* The service that really handles broadcast intents on a worker thread.
*
@@ -94,6 +118,8 @@
///M: The number of unread Email is also displayed after you clear data.
private static final String EMIAL_PACKAGE_NAME = "com.android.email";
+ private static final String EMAIL_FIRST_LAUNCH = "email_first_launch";
+
public EmailBroadcastProcessorService() {
// Class name will be the thread name.
super(EmailBroadcastProcessorService.class.getName());
@@ -341,6 +367,8 @@
int unreadCount = Mailbox.getUnreadCountByMailboxType(this, Mailbox.TYPE_INBOX);
NotificationController.notifyEmailUnreadNumber(this, unreadCount);
/**@}*/
+
+ restorePreservedAccount();//jimbo add
}
private void reconcileAndStartServices() {
@@ -457,4 +485,134 @@
}
/**@}*/
+
+ AccountManagerCallback<Bundle> mAccountManagerCallback = new AccountManagerCallback<Bundle>() {
+ @Override
+ public void run(AccountManagerFuture<Bundle> future) {
+ Utility.getMainThreadHandler().post(new Runnable() {
+ public void run() {
+ mRestoreAccount.mFlags &= ~Account.FLAGS_INCOMPLETE;
+ mRestoreAccount.mFlags &= ~Account.FLAGS_SECURITY_HOLD;
+ AccountSettingsUtils.commitSettings(EmailBroadcastProcessorService.this,
+ mRestoreAccount);
+ // Update the folder list (to get our starting folders, e.g. Inbox)
+ final EmailServiceProxy proxy = EmailServiceUtils.getServiceForAccount(EmailBroadcastProcessorService.this, mRestoreAccount.mId);
+ try {
+ proxy.updateFolderList(mRestoreAccount.mId);
+ } catch (RemoteException e) {
+ // It's all good
+ }
+ }
+ });
+ return;
+ }
+ };
+
+ /**
+ * Async task that continues the work of finishAutoSetup(). Checks for a duplicate
+ * account and then either alerts the user, or continues.
+ */
+ private class DuplicateCheckTask extends AsyncTask<Void, Void, String> {
+ private final Context mContext;
+ private final String mCheckAddress;
+ private final boolean mAutoSetup;
+
+ public DuplicateCheckTask(Context context, String checkAddress,
+ boolean autoSetup) {
+ mContext = context;
+ mCheckAddress = checkAddress;
+ mAutoSetup = autoSetup;
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ return Utility.findExistingAccount(mContext, null, mCheckAddress);
+ }
+
+ @Override
+ protected void onPostExecute(String duplicateAccountName) {
+ // Show duplicate account warning, or proceed
+ if (duplicateAccountName != null) {
+ LogUtils.d("KK", "Account has exsited");
+ } else {
+ mRestoreAccount.setFlags(mRestoreAccount.getFlags()
+ & ~(Account.FLAGS_BACKGROUND_ATTACHMENTS));
+ //for smart push
+ mRestoreAccount.setSyncInterval(-2);
+ mRestoreAccount.mFlags |= Account.FLAGS_SMART_PUSH;
+ mRestoreAccount.mFlags |= Account.FLAGS_INCOMPLETE;
+ final Context context = EmailBroadcastProcessorService.this;
+ AccountSettingsUtils.commitSettings(context, mRestoreAccount);
+ EmailServiceUtils.setupAccountManagerAccount(context, mRestoreAccount,
+ true, false, false, mAccountManagerCallback);
+
+ // We can move the notification setting to the inbox
+ // FolderPreferences later, once
+ // we know what the inbox is
+ final AccountPreferences accountPreferences =
+ new AccountPreferences(context, mRestoreAccount.getEmailAddress());
+ accountPreferences.setDefaultInboxNotificationsEnabled(true);
+ }
+ }
+
+ @Override
+ protected void onCancelled(String s) {
+ LogUtils.d(LogUtils.TAG, "DuplicateCheckTask cancelled (AccountSetupBasics)");
+ }
+ }
+
+ private Account mRestoreAccount;
+
+ private void populateSetupData(Account account, String senderName, String senderEmail) {
+ account.setSenderName(senderName);
+ account.setEmailAddress(senderEmail);
+ account.setDisplayName(senderEmail);
+ final String protocol = account.mHostAuthRecv.mProtocol;
+ if (protocol == null) return;
+ final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(this, protocol);
+ account.mSyncInterval = info.defaultSyncInterval;
+ account.mSyncLookback = info.defaultLookback;
+ if (info.offerLocalDeletes) {
+ account.setDeletePolicy(info.defaultLocalDeletes);
+ }
+ }
+
+ private void restorePreservedAccount() {
+ SharedPreferences shPre = getSharedPreferences(EMIAL_PACKAGE_NAME, Context.MODE_PRIVATE);
+ if (shPre.contains(EMAIL_FIRST_LAUNCH)) {
+ LogUtils.d("KK", "not firstLaunch");
+ return;
+ }
+ shPre.edit().putBoolean(EMAIL_FIRST_LAUNCH, false).apply();
+ String email = "xxxxxxx@gaj.cq";
+ final String[] emailParts = email.split("@");
+ final String domain = emailParts[1].trim();
+ Provider mProvider = AccountSettingsUtils.findProviderForDomain(this, domain);
+ mProvider.expandTemplates(email);
+
+ try {
+ mRestoreAccount = new Account();
+ Account account = mRestoreAccount;
+ account.setDisplayName("Email xxx");
+ final HostAuth recvAuth = account.getOrCreateHostAuthRecv(this);
+// recvAuth.mPort = 7001;
+ HostAuth.setHostAuthFromString(recvAuth, mProvider.incomingUri);
+ recvAuth.setLogin(mProvider.incomingUsername, "123");
+ final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(this,
+ recvAuth.mProtocol);
+// recvAuth.mPort =
+// ((recvAuth.mFlags & HostAuth.FLAG_SSL) != 0) ? info.portSsl : info.port;
+
+ final HostAuth sendAuth = account.getOrCreateHostAuthSend(this);
+// sendAuth.mPort = 7002;
+ HostAuth.setHostAuthFromString(sendAuth, mProvider.outgoingUri);
+ sendAuth.setLogin(mProvider.outgoingUsername, "123");
+ populateSetupData(account, "Email xxx", email);
+ } catch (URISyntaxException e) {
+ LogUtils.d("KK", "setHostAuthFromString error");
+ }
+ new DuplicateCheckTask(this, email, true)
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
}
达到的效果如下:
JB 版本实现
M packages/apps/Email/emailcommon/src/com/android/emailcommon/utility/Utility.java
M packages/apps/Email/res/xml/providers.xml
M packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java
M packages/apps/Email/src/com/android/email/service/EmailServiceUtils.java
Index: packages/apps/Email/emailcommon/src/com/android/emailcommon/utility/Utility.java
===================================================================
--- packages/apps/Email/emailcommon/src/com/android/emailcommon/utility/Utility.java (revision 658)
+++ packages/apps/Email/emailcommon/src/com/android/emailcommon/utility/Utility.java (working copy)
@@ -345,6 +345,44 @@
return null;
}
+//jimbo add start
+ /**
+ * This only actually matches against the email address. It's technically kosher to allow the
+ * same address across different account types, but that's a pretty rare use case and isn't well
+ * handled in the UI.
+ *
+ * @param context context
+ * @param syncAuthority the account manager type to check against or null for all types
+ * @param address email address to match against
+ * @return account name for match found or null
+ */
+ public static String findExistingAccount(final Context context, final String syncAuthority, final String address) {
+ final ContentResolver resolver = context.getContentResolver();
+ final Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION,
+ AccountColumns.EMAIL_ADDRESS + "=?", new String[] {address}, null);
+ try {
+ if (!c.moveToFirst()) {
+ return null;
+ }
+ return c.getString(c.getColumnIndex(Account.DISPLAY_NAME));
+ /*
+ do {
+ if (syncAuthority != null) {
+ // TODO: actually compare the sync authority to allow creating the same account
+ // on different protocols. Sadly this code can't directly access the service info
+ } else {
+ final Account account = new Account();
+ account.restore(c);
+ return account.mDisplayName;
+ }
+ } while (c.moveToNext());
+ */
+ } finally {
+ c.close();
+ }
+ }
+//jimbo add end
+
/**
* Generate a random message-id header for locally-generated messages.
*/
Index: packages/apps/Email/res/xml/providers.xml
===================================================================
--- packages/apps/Email/res/xml/providers.xml (revision 658)
+++ packages/apps/Email/res/xml/providers.xml (working copy)
@@ -473,4 +473,8 @@
<incoming uri="imap+ssl+://android.imap.mail.yahoo.com" username="$email" />
<outgoing uri="smtp+ssl+://android.smtp.mail.yahoo.com" username="$email" />
</provider>
+ <provider id="gaj" label="gaj" domain="gaj.cq">
+ <incoming uri="pop3+://127.0.0.1:7001" username="$email" />
+ <outgoing uri="smtp+://127.0.0.1:7002" username="$email" />
+ </provider>
</providers>
Index: packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java
===================================================================
--- packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java (revision 658)
+++ packages/apps/Email/src/com/android/email/service/EmailBroadcastProcessorService.java (working copy)
@@ -45,6 +45,35 @@
import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.HostAuth;
+
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.FragmentTransaction;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.RemoteException;
+import com.android.email.activity.setup.AccountCheckSettingsFragment;
+import com.android.email.activity.setup.AccountSettingsUtils;
+import com.android.email.activity.setup.AccountSetupOptions;
+import com.android.email.activity.setup.DuplicateAccountDialogFragment;
+import com.android.email.activity.setup.SetupData;
+//import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
+//import com.android.emailcommon.VendorPolicyLoader.Provider;
+import com.android.email.activity.setup.AccountSettingsUtils.Provider;
+import com.android.emailcommon.service.EmailServiceProxy;
+//import com.android.emailcommon.utility.AsyncTask;
+import com.android.emailcommon.utility.Utility;
+//import com.android.mail.preferences.AccountPreferences;
+import android.os.Bundle;
+import android.os.AsyncTask;
+import com.android.emailcommon.service.SyncWindow;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+
/**
* The service that really handles broadcast intents on a worker thread.
*
@@ -221,6 +250,8 @@
/// @}
}
mEmailBroadcastServiceFinished = true;
+
+ restorePreservedAccount();//jimbo add
}
private void performOneTimeInitialization() {
@@ -298,4 +329,172 @@
EmailServiceUtils.startExchangeService(this);
}
+
+
+//jimbo add start
+
+ private Account mRestoreAccount;
+ private static final String EMAIL_FIRST_LAUNCH = "email_first_launch";
+
+ AccountManagerCallback<Bundle> mAccountManagerCallback = new AccountManagerCallback<Bundle>() {
+ @Override
+ public void run(AccountManagerFuture<Bundle> future) {
+ Utility.getMainThreadHandler().post(new Runnable() {
+ public void run() {
+ mRestoreAccount.mFlags &= ~Account.FLAGS_INCOMPLETE;
+ mRestoreAccount.mFlags &= ~Account.FLAGS_SECURITY_HOLD;
+ AccountSettingsUtils.commitSettings(EmailBroadcastProcessorService.this, mRestoreAccount);
+ // Update the folder list (to get our starting folders, e.g. Inbox)
+ final EmailServiceProxy proxy = EmailServiceUtils.getServiceForAccount(EmailBroadcastProcessorService.this, mRestoreAccount.mId);
+ Log.d("KK", "AccountManagerCallback MainThreadHandler run");
+ try {
+ proxy.updateFolderList(mRestoreAccount.mId);
+ } catch (RemoteException e) {
+ // It's all good
+ }
+ }
+ });
+ return;
+ }
+ };
+
+ /**
+ * Async task that continues the work of finishAutoSetup(). Checks for a duplicate
+ * account and then either alerts the user, or continues.
+ */
+ private class DuplicateCheckTask extends AsyncTask<Void, Void, String> {
+ private final Context mContext;
+ private final String mCheckAddress;
+ private final boolean mAutoSetup;
+
+ public DuplicateCheckTask(Context context, String checkAddress, boolean autoSetup) {
+ mContext = context;
+ mCheckAddress = checkAddress;
+ mAutoSetup = autoSetup;
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ //return Utility.findExistingAccount(mContext, null, mCheckAddress);
+ String existAccount = Utility.findExistingAccount(mContext, null, mCheckAddress);
+ Log.d("KK", "doInBackground -- existAccount="+existAccount);
+ return existAccount;
+ }
+
+ @Override
+ protected void onPostExecute(String duplicateAccountName) {
+ // Show duplicate account warning, or proceed
+ if (duplicateAccountName != null) {
+ Log.d("KK", "onPostExecute -- Account has exsited");
+ } else {
+ Log.d("KK", "onPostExecute create default Account");
+
+ mRestoreAccount.setFlags(mRestoreAccount.getFlags() & ~(Account.FLAGS_BACKGROUND_ATTACHMENTS));
+ //for smart push
+ mRestoreAccount.setSyncInterval(-2);
+// mRestoreAccount.mFlags |= Account.FLAGS_SMART_PUSH;
+ mRestoreAccount.mFlags |= Account.FLAGS_INCOMPLETE;
+ final Context context = EmailBroadcastProcessorService.this;
+ AccountSettingsUtils.commitSettings(context, mRestoreAccount);
+ EmailServiceUtils.setupAccountManagerAccount(context, mRestoreAccount, true, false, false, mAccountManagerCallback);
+
+ Log.d("KK", "onPostExecute create default Account end");
+
+ // We can move the notification setting to the inbox
+ // FolderPreferences later, once
+ // we know what the inbox is
+// final AccountPreferences accountPreferences = new AccountPreferences(context, mRestoreAccount.getEmailAddress());
+// accountPreferences.setDefaultInboxNotificationsEnabled(true);
+ }
+ }
+
+ @Override
+ protected void onCancelled(String s) {
+ Log.d("KK", "DuplicateCheckTask cancelled (AccountSetupBasics)");
+ }
+ }
+
+
+
+ private void populateSetupData(Account account, String senderName, String senderEmail) {
+ account.setSenderName(senderName);
+ account.setEmailAddress(senderEmail);
+ account.setDisplayName(senderEmail);
+ final String protocol = account.mHostAuthRecv.mProtocol;
+ if (protocol == null) return;
+/* final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(this, protocol);
+ account.mSyncInterval = info.defaultSyncInterval;
+ account.mSyncLookback = info.defaultLookback;
+ if (info.offerLocalDeletes) {
+ account.setDeletePolicy(info.defaultLocalDeletes);
+ }
+*/
+ account.mSyncInterval = 15;
+ account.mSyncLookback = SyncWindow.SYNC_WINDOW_3_DAYS;
+ //account.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE);
+
+ }
+
+ private void restorePreservedAccount() {
+ SharedPreferences shPre = getSharedPreferences(EMIAL_PACKAGE_NAME, Context.MODE_PRIVATE);
+ if (shPre.contains(EMAIL_FIRST_LAUNCH)) {
+ Log.d("KK", "not firstLaunch");
+ return;
+ }
+ shPre.edit().putBoolean(EMAIL_FIRST_LAUNCH, false).apply();
+ String email = "xxxxxx@gaj.cq";
+ final String[] emailParts = email.split("@");
+ final String domain = emailParts[1].trim();
+ Provider mProvider = AccountSettingsUtils.findProviderForDomain(this, domain);
+ mProvider.expandTemplates(email);
+
+ try {
+ mRestoreAccount = new Account();
+ Account account = mRestoreAccount;
+ account.setDisplayName("Email xxx");
+ final HostAuth recvAuth = account.getOrCreateHostAuthRecv(this);
+ HostAuth.setHostAuthFromString(recvAuth, mProvider.incomingUri);
+ recvAuth.setLogin(mProvider.incomingUsername, "123");
+// final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(this,
+// recvAuth.mProtocol);
+// recvAuth.mPort =
+// ((recvAuth.mFlags & HostAuth.FLAG_SSL) != 0) ? info.portSsl : info.port;
+
+ final HostAuth sendAuth = account.getOrCreateHostAuthSend(this);
+ HostAuth.setHostAuthFromString(sendAuth, mProvider.outgoingUri);
+ sendAuth.setLogin(mProvider.outgoingUsername, "123");
+ populateSetupData(account, "Email xxx", email);
+ } catch (URISyntaxException e) {
+ Log.d("KK", "setHostAuthFromString error");
+ }
+
+
+ new DuplicateCheckTask(this, email, true).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+//jimbo add end
}
Index: packages/apps/Email/src/com/android/email/service/EmailServiceUtils.java
===================================================================
--- packages/apps/Email/src/com/android/email/service/EmailServiceUtils.java (revision 658)
+++ packages/apps/Email/src/com/android/email/service/EmailServiceUtils.java (working copy)
@@ -34,6 +34,14 @@
import com.android.emailcommon.service.OofParams;
import com.android.emailcommon.service.SearchParams;
+import com.android.emailcommon.provider.Account;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+
+import android.accounts.AccountManager;
+
/**
* Utility functions for EmailService support.
*/
@@ -66,7 +74,52 @@
return new EmailServiceProxy(context, intentAction, callback);
}
+//jimbo add start
/**
+ * For a given account id, return a service proxy if applicable, or null.
+ *
+ * @param accountId the message of interest
+ * @return service proxy, or null if n/a
+ */
+ public static EmailServiceProxy getServiceForAccount(Context context, long accountId) {
+ return new EmailServiceProxy(context, Account.getProtocol(context, accountId), null);
+ }
+
+ /**
+ * Add an account to the AccountManager.
+ * @param context Our {@link Context}.
+ * @param account The {@link Account} we're adding.
+ * @param email Whether the user wants to sync email on this account.
+ * @param calendar Whether the user wants to sync calendar on this account.
+ * @param contacts Whether the user wants to sync contacts on this account.
+ * @param callback A callback for when the AccountManager is done.
+ * @return The result of {@link AccountManager#addAccount}.
+ */
+ public static AccountManagerFuture<Bundle> setupAccountManagerAccount(final Context context,
+ final Account account, final boolean email, final boolean calendar,
+ final boolean contacts, final AccountManagerCallback<Bundle> callback) {
+ final Bundle options = new Bundle(5);
+ final HostAuth hostAuthRecv =
+ HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
+ if (hostAuthRecv == null) {
+ return null;
+ }
+ // Set up username/password
+ options.putString(EasAuthenticatorService.OPTIONS_USERNAME, account.mEmailAddress);
+ options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, hostAuthRecv.mPassword);
+ options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, contacts);
+ options.putBoolean(EasAuthenticatorService.OPTIONS_CALENDAR_SYNC_ENABLED, calendar);
+ options.putBoolean(EasAuthenticatorService.OPTIONS_EMAIL_SYNC_ENABLED, email);
+ return AccountManager.get(context).addAccount("com.android.email", null, null, options, null, callback, null);
+ }
+
+//jimbo add end
+
+
+ /**
* Determine if the EmailService is available
*/
public static boolean isServiceAvailable(Context context, String intentAction) {
参考 http://blog.csdn.net/wds1181977/article/details/11472843