Fix the service notification
[fonbot.git] / src / ro / ieval / fonbot / FonBotMainService.java
1 package ro.ieval.fonbot;
2
3 import static ro.ieval.fonbot.R.string.*;
4 import static ro.ieval.fonbot.Utils.toNonNull;
5
6 import java.util.Collections;
7 import java.util.EnumSet;
8 import java.util.Set;
9
10 import org.eclipse.jdt.annotation.Nullable;
11
12 import ro.ieval.fonbot.Utils.OngoingEvent;
13
14 import android.app.Notification;
15 import android.app.NotificationManager;
16 import android.app.PendingIntent;
17 import android.app.Service;
18 import android.content.Intent;
19 import android.content.IntentFilter;
20 import android.os.IBinder;
21 import android.preference.PreferenceManager;
22 import android.support.v4.app.NotificationCompat;
23 import android.support.v4.content.LocalBroadcastManager;
24
25 /*
26 * Copyright © 2013 Marius Gavrilescu
27 *
28 * This file is part of FonBot.
29 *
30 * FonBot is free software: you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation, either version 3 of the License, or
33 * (at your option) any later version.
34 *
35 * FonBot is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
42 */
43
44 /**
45 * Main service.
46 *
47 * @author Marius Gavrilescu
48 */
49 public final class FonBotMainService extends Service {
50 /**
51 * Binder for the service. It lets clients get a reference to the service.
52 *
53 * @author Marius Gavrilescu <marius@ieval.ro>
54 */
55 public final class Binder extends android.os.Binder{
56 /**
57 * Get a reference to the {@link FonBotMainService}
58 * @return a reference to the {@link FonBotMainService}
59 */
60 public FonBotMainService getService(){
61 return FonBotMainService.this;
62 }
63 }
64
65 /**
66 * Broadcast action: add an ongoing event
67 */
68 public static final String ACTION_PUT_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_PUT_ONGOING";
69 /**
70 * Broadcast action: remove an ongoing event
71 */
72 public static final String ACTION_DELETE_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_DELETE_ONGOING";
73 /** Broadcast action: trigger a server poll */
74 public static final String ACTION_TRIGGER_POLL="ro.ieval.fonbot.FonBotMainService.ACTION_TRIGGER_POLL";
75 /**
76 * Extra: ongoing event id
77 *
78 * @see OngoingEvent
79 * @see #ACTION_DELETE_ONGOING
80 * @see #ACTION_PUT_ONGOING
81 */
82 public static final String EXTRA_ONGOING_ID="ro.ieval.fonbot.FonBotMainService.EXTRA_ONGOING_ID";
83 /**
84 * Broadcast sent when the ongoing event list is updated.
85 */
86 public static final String ACTION_ONGOING_UPDATE="ro.ieval.fonbot.FonBotMainService.ACTION_ONGOING_UPDATE";
87 /**
88 * IntentFilter for events caught by the {@link DynamicEventReceiver}
89 */
90 private static final IntentFilter DYNAMIC_BROADCAST_FILTER=new IntentFilter();
91
92 static{
93 DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_SCREEN_ON);
94 DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_BATTERY_CHANGED);
95 DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_HEADSET_PLUG);
96 }
97
98 /**
99 * The one instance of {@link DynamicEventReceiver}
100 */
101 private final DynamicEventReceiver receiver=new DynamicEventReceiver();
102 /**
103 * Set of ongoing events.
104 */
105 private final Set<OngoingEvent> ongoing=EnumSet.noneOf(OngoingEvent.class);
106
107 /** true if running in foreground, false otherwise */
108 private boolean isForeground = false;
109
110 /**
111 * Get the set of ongoing events.
112 *
113 * @return a set of ongoing events
114 */
115 public Set<OngoingEvent> getOngoingEvents(){
116 return toNonNull(Collections.unmodifiableSet(ongoing));
117 }
118
119 @Override
120 public @Nullable IBinder onBind(final @Nullable Intent intent) {
121 return new Binder();
122 }
123
124 @Override
125 public void onCreate() {
126 super.onCreate();
127 registerReceiver(receiver, DYNAMIC_BROADCAST_FILTER);
128 }
129
130 @Override
131 public void onDestroy() {
132 super.onDestroy();
133 unregisterReceiver(receiver);
134 }
135
136 @Override
137 public int onStartCommand(final @Nullable Intent intent, final int flags, final int startId) {
138 boolean updateNotification = false;
139 if(intent!=null && intent.getAction()==ACTION_PUT_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
140 ongoing.add(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
141 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
142 updateNotification=true;
143 }
144 if(intent!=null && intent.getAction()==ACTION_DELETE_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
145 ongoing.remove(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
146 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
147 updateNotification=true;
148 }
149
150 if(intent!=null && intent.getAction()==ACTION_TRIGGER_POLL)
151 Utils.pollServer(this);
152
153 final boolean runForeground=PreferenceManager.getDefaultSharedPreferences(this).getBoolean("foreground", false);
154 if(!runForeground)
155 stopForeground(true);
156
157 final NotificationManager man=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
158 final boolean shouldNotify=runForeground||!ongoing.isEmpty();
159 if(shouldNotify && (updateNotification || runForeground != isForeground)){
160 final Intent mainIntent=new Intent(this, FonBotMainActivity.class);
161 mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
162 final NotificationCompat.Builder builder=new NotificationCompat.Builder(this).
163 setContentText(getString(foreground_notification_text)).
164 setContentTitle(getString(foreground_notification_title)).
165 setSmallIcon(android.R.drawable.stat_notify_sync_noanim).
166 setPriority(NotificationCompat.PRIORITY_MIN).
167 setContentIntent(PendingIntent.getActivity(this, 0, mainIntent, 0)).
168 setOngoing(true);
169
170 if(!ongoing.isEmpty()) {
171 final NotificationCompat.InboxStyle inboxBuilder=new NotificationCompat.InboxStyle(builder);
172
173 for(final OngoingEvent event : ongoing)
174 inboxBuilder.addLine(getString(event.resource));
175
176 }
177 final Notification notification=builder.build();
178
179 if(runForeground)
180 startForeground(1337, notification);
181 else
182 man.notify(1337, notification);
183 }
184
185 if(!shouldNotify)
186 man.cancel(1337);
187 isForeground=runForeground;
188 return START_STICKY;
189 }
190 }
This page took 0.024653 seconds and 4 git commands to generate.