1 package ro
.ieval
.fonbot
;
3 import static ro
.ieval
.fonbot
.R
.string
.*;
4 import static ro
.ieval
.fonbot
.Utils
.toNonNull
;
6 import java
.util
.Collections
;
7 import java
.util
.EnumSet
;
10 import org
.eclipse
.jdt
.annotation
.Nullable
;
12 import ro
.ieval
.fonbot
.Utils
.OngoingEvent
;
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
;
26 * Copyright © 2013 Marius Gavrilescu
28 * This file is part of FonBot.
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.
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.
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/>.
47 * @author Marius Gavrilescu
49 public final class FonBotMainService
extends Service
{
51 * Binder for the service. It lets clients get a reference to the service.
53 * @author Marius Gavrilescu <marius@ieval.ro>
55 public final class Binder
extends android
.os
.Binder
{
57 * Get a reference to the {@link FonBotMainService}
58 * @return a reference to the {@link FonBotMainService}
60 public FonBotMainService
getService(){
61 return FonBotMainService
.this;
66 * Broadcast action: add an ongoing event
68 public static final String ACTION_PUT_ONGOING
="ro.ieval.fonbot.FonBotMainService.ACTION_PUT_ONGOING";
70 * Broadcast action: remove an ongoing event
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";
76 * Extra: ongoing event id
79 * @see #ACTION_DELETE_ONGOING
80 * @see #ACTION_PUT_ONGOING
82 public static final String EXTRA_ONGOING_ID
="ro.ieval.fonbot.FonBotMainService.EXTRA_ONGOING_ID";
84 * Broadcast sent when the ongoing event list is updated.
86 public static final String ACTION_ONGOING_UPDATE
="ro.ieval.fonbot.FonBotMainService.ACTION_ONGOING_UPDATE";
88 * IntentFilter for events caught by the {@link DynamicEventReceiver}
90 private static final IntentFilter DYNAMIC_BROADCAST_FILTER
=new IntentFilter();
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
);
99 * The one instance of {@link DynamicEventReceiver}
101 private final DynamicEventReceiver receiver
=new DynamicEventReceiver();
103 * Set of ongoing events.
105 private final Set
<OngoingEvent
> ongoing
=EnumSet
.noneOf(OngoingEvent
.class);
107 /** true if running in foreground, false otherwise */
108 private boolean isForeground
= false;
111 * Get the set of ongoing events.
113 * @return a set of ongoing events
115 public Set
<OngoingEvent
> getOngoingEvents(){
116 return toNonNull(Collections
.unmodifiableSet(ongoing
));
120 public @Nullable IBinder
onBind(final @Nullable Intent intent
) {
125 public void onCreate() {
127 registerReceiver(receiver
, DYNAMIC_BROADCAST_FILTER
);
131 public void onDestroy() {
133 unregisterReceiver(receiver
);
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;
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;
150 if(intent
!=null && intent
.getAction()==ACTION_TRIGGER_POLL
)
151 Utils
.pollServer(this);
153 final boolean runForeground
=PreferenceManager
.getDefaultSharedPreferences(this).getBoolean("foreground", false);
155 stopForeground(true);
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)).
170 if(!ongoing
.isEmpty()) {
171 final NotificationCompat
.InboxStyle inboxBuilder
=new NotificationCompat
.InboxStyle(builder
);
173 for(final OngoingEvent event
: ongoing
)
174 inboxBuilder
.addLine(getString(event
.resource
));
177 final Notification notification
=builder
.build();
180 startForeground(1337, notification
);
182 man
.notify(1337, notification
);
187 isForeground
=runForeground
;