import static ro.ieval.fonbot.Utils.toNonNull;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.EnumSet;
import java.util.Set;
import org.eclipse.jdt.annotation.Nullable;
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.ConnectivityManager;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
/*
* Copyright © 2013 Marius Gavrilescu
}
}
+ /**
+ * Runnable that continously long polls the server for commands
+ *
+ * @author Marius Gavrilescu <marius@ieval.ro>
+ */
+ private final class LongPollRunnable implements Runnable{
+ public void run(){
+ final ConnectivityManager man=(ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+ final HttpCallExecutableRunnable runnable=new HttpCallExecutableRunnable("/get", null, FonBotMainService.this, new PollResultCallback(FonBotMainService.this), false);
+
+ Log.d("LongPollRunnable", "Long polling started");
+ while(man.getActiveNetworkInfo() != null && man.getActiveNetworkInfo().isConnected())
+ try {
+ runnable.run();
+ } catch (final Exception ex){
+ ex.printStackTrace();
+ }
+ Log.d("LongPollRunnable", "Long polling stopped");
+ }
+ }
+
/**
* Broadcast action: add an ongoing event
*/
* Broadcast action: remove an ongoing event
*/
public static final String ACTION_DELETE_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_DELETE_ONGOING";
+ /** Broadcast action: trigger a server poll */
+ public static final String ACTION_TRIGGER_POLL="ro.ieval.fonbot.FonBotMainService.ACTION_TRIGGER_POLL";
/**
* Extra: ongoing event id
*
private static final IntentFilter DYNAMIC_BROADCAST_FILTER=new IntentFilter();
static{
- DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_SCREEN_ON);
DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_BATTERY_CHANGED);
DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_HEADSET_PLUG);
}
/**
* Set of ongoing events.
*/
- private final Set<OngoingEvent> ongoing=new HashSet<OngoingEvent>(10);
+ private final Set<OngoingEvent> ongoing=EnumSet.noneOf(OngoingEvent.class);
+
+ /** true if running in foreground, false otherwise */
+ private boolean isForeground = false;
+
+ /** Thread that runs a {@link LongPollRunnable} */
+ private Thread longPollThread;
/**
* Get the set of ongoing events.
@Override
public int onStartCommand(final @Nullable Intent intent, final int flags, final int startId) {
+ boolean updateNotification = false;
if(intent!=null && intent.getAction()==ACTION_PUT_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
ongoing.add(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
+ updateNotification=true;
}
if(intent!=null && intent.getAction()==ACTION_DELETE_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
ongoing.remove(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
+ updateNotification=true;
+ }
+
+ if(longPollThread == null || !longPollThread.isAlive()){
+ longPollThread = new Thread(new LongPollRunnable());
+ longPollThread.start();
}
final boolean runForeground=PreferenceManager.getDefaultSharedPreferences(this).getBoolean("foreground", false);
if(!runForeground)
stopForeground(true);
- if(runForeground||!ongoing.isEmpty()){
+ final NotificationManager man=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ final boolean shouldNotify=runForeground||!ongoing.isEmpty();
+ if(shouldNotify && (updateNotification || runForeground != isForeground)){
final Intent mainIntent=new Intent(this, FonBotMainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final NotificationCompat.Builder builder=new NotificationCompat.Builder(this).
setContentIntent(PendingIntent.getActivity(this, 0, mainIntent, 0)).
setOngoing(true);
- final Notification notification;
- if(ongoing.isEmpty())
- notification=builder.build();
- else {
+ if(!ongoing.isEmpty()) {
final NotificationCompat.InboxStyle inboxBuilder=new NotificationCompat.InboxStyle(builder);
for(final OngoingEvent event : ongoing)
inboxBuilder.addLine(getString(event.resource));
- notification=inboxBuilder.build();
}
+ final Notification notification=builder.build();
if(runForeground)
- startForeground(1337, builder.build());
- else{
- final NotificationManager man=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ startForeground(1337, notification);
+ else
man.notify(1337, notification);
- }
}
+ if(!shouldNotify)
+ man.cancel(1337);
+ isForeground=runForeground;
return START_STICKY;
}
}