1. 程式人生 > >MTK Email內建預設賬戶

MTK Email內建預設賬戶

專案需求: 如題

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 = "
[email protected]
"; + 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 = "
[email protected]
"; + 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