MailService.java revision 8978aac1977408b05e386ae846c30920c7faa0a6
1
2package com.android.email.service;
3
4import java.util.HashMap;
5
6import android.app.AlarmManager;
7import android.app.Notification;
8import android.app.NotificationManager;
9import android.app.PendingIntent;
10import android.app.Service;
11import android.content.Context;
12import android.content.Intent;
13import android.os.IBinder;
14import android.os.SystemClock;
15import android.util.Config;
16import android.util.Log;
17import android.text.TextUtils;
18import android.net.Uri;
19
20import com.android.email.Account;
21import com.android.email.Email;
22import com.android.email.MessagingController;
23import com.android.email.MessagingListener;
24import com.android.email.Preferences;
25import com.android.email.R;
26import com.android.email.activity.Accounts;
27import com.android.email.activity.FolderMessageList;
28
29/**
30 */
31public class MailService extends Service {
32    private static final String ACTION_CHECK_MAIL = "com.android.email.intent.action.MAIL_SERVICE_WAKEUP";
33    private static final String ACTION_RESCHEDULE = "com.android.email.intent.action.MAIL_SERVICE_RESCHEDULE";
34    private static final String ACTION_CANCEL = "com.android.email.intent.action.MAIL_SERVICE_CANCEL";
35
36    private Listener mListener = new Listener();
37
38    private int mStartId;
39
40    public static void actionReschedule(Context context) {
41        Intent i = new Intent();
42        i.setClass(context, MailService.class);
43        i.setAction(MailService.ACTION_RESCHEDULE);
44        context.startService(i);
45    }
46
47    public static void actionCancel(Context context)  {
48        Intent i = new Intent();
49        i.setClass(context, MailService.class);
50        i.setAction(MailService.ACTION_CANCEL);
51        context.startService(i);
52    }
53
54    @Override
55    public void onStart(Intent intent, int startId) {
56        super.onStart(intent, startId);
57        this.mStartId = startId;
58
59        MessagingController.getInstance(getApplication()).addListener(mListener);
60        if (ACTION_CHECK_MAIL.equals(intent.getAction())) {
61            if (Config.LOGV) {
62                Log.v(Email.LOG_TAG, "***** MailService *****: checking mail");
63            }
64            MessagingController.getInstance(getApplication()).checkMail(this, null, mListener);
65        }
66        else if (ACTION_CANCEL.equals(intent.getAction())) {
67            if (Config.LOGV) {
68                Log.v(Email.LOG_TAG, "***** MailService *****: cancel");
69            }
70            cancel();
71            stopSelf(startId);
72        }
73        else if (ACTION_RESCHEDULE.equals(intent.getAction())) {
74            if (Config.LOGV) {
75                Log.v(Email.LOG_TAG, "***** MailService *****: reschedule");
76            }
77            reschedule();
78            stopSelf(startId);
79        }
80    }
81
82    @Override
83    public void onDestroy() {
84        super.onDestroy();
85        MessagingController.getInstance(getApplication()).removeListener(mListener);
86    }
87
88    private void cancel() {
89        AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
90        Intent i = new Intent();
91        i.setClassName("com.android.email", "com.android.email.service.MailService");
92        i.setAction(ACTION_CHECK_MAIL);
93        PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
94        alarmMgr.cancel(pi);
95    }
96
97    private void reschedule() {
98        AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
99        Intent i = new Intent();
100        i.setClassName("com.android.email", "com.android.email.service.MailService");
101        i.setAction(ACTION_CHECK_MAIL);
102        PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
103
104        int shortestInterval = -1;
105        for (Account account : Preferences.getPreferences(this).getAccounts()) {
106            if (account.getAutomaticCheckIntervalMinutes() != -1
107                    && (account.getAutomaticCheckIntervalMinutes() < shortestInterval || shortestInterval == -1)) {
108                shortestInterval = account.getAutomaticCheckIntervalMinutes();
109            }
110        }
111
112        if (shortestInterval == -1) {
113            alarmMgr.cancel(pi);
114        }
115        else {
116            alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
117                    + (shortestInterval * (60 * 1000)), pi);
118        }
119    }
120
121    public IBinder onBind(Intent intent) {
122        return null;
123    }
124
125    class Listener extends MessagingListener {
126        HashMap<Account, Integer> accountsWithNewMail = new HashMap<Account, Integer>();
127
128        @Override
129        public void checkMailStarted(Context context, Account account) {
130            accountsWithNewMail.clear();
131        }
132
133        @Override
134        public void checkMailFailed(Context context, Account account, String reason) {
135            reschedule();
136            stopSelf(mStartId);
137        }
138
139        @Override
140        public void synchronizeMailboxFinished(
141                Account account,
142                String folder,
143                int totalMessagesInMailbox,
144                int numNewMessages) {
145            if (account.isNotifyNewMail() && numNewMessages > 0) {
146                accountsWithNewMail.put(account, numNewMessages);
147            }
148        }
149
150        @Override
151        public void checkMailFinished(Context context, Account account) {
152            NotificationManager notifMgr = (NotificationManager)context
153                    .getSystemService(Context.NOTIFICATION_SERVICE);
154
155            if (accountsWithNewMail.size() > 0) {
156                Notification notif = new Notification(R.drawable.stat_notify_email_generic,
157                        getString(R.string.notification_new_title), System.currentTimeMillis());
158                boolean vibrate = false;
159                String ringtone = null;
160                if (accountsWithNewMail.size() > 1) {
161                    for (Account account1 : accountsWithNewMail.keySet()) {
162                        if (account1.isVibrate()) vibrate = true;
163                        ringtone = account1.getRingtone();
164                    }
165                    Intent i = new Intent(context, Accounts.class);
166                    PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
167                    notif.setLatestEventInfo(context, getString(R.string.notification_new_title),
168                            getString(R.string.notification_new_multi_account_fmt,
169                                    accountsWithNewMail.size()), pi);
170                } else {
171                    Account account1 = accountsWithNewMail.keySet().iterator().next();
172                    int totalNewMails = accountsWithNewMail.get(account1);
173                    Intent i = FolderMessageList.actionHandleAccountIntent(context, account1, Email.INBOX);
174                    PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
175                    notif.setLatestEventInfo(context, getString(R.string.notification_new_title),
176                            getString(R.string.notification_new_one_account_fmt, totalNewMails,
177                                    account1.getDescription()), pi);
178                    vibrate = account1.isVibrate();
179                    ringtone = account1.getRingtone();
180                }
181                notif.defaults = Notification.DEFAULT_LIGHTS;
182                notif.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
183                if (vibrate) {
184                    notif.defaults |= Notification.DEFAULT_VIBRATE;
185                }
186                notifMgr.notify(1, notif);
187            }
188
189            reschedule();
190            stopSelf(mStartId);
191        }
192    }
193}
194