/**************************************************************************************************
* Copyright (C) 2010 Sense Observation Systems, Rotterdam, the Netherlands. All rights reserved. *
*************************************************************************************************/
package nl.sense_os.service;
import nl.sense_os.service.constants.SensePrefs;
import nl.sense_os.service.constants.SensePrefs.Auth;
import nl.sense_os.service.constants.SenseStatusCodes;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.app.NotificationCompat;
/**
* This class is responsible for keeping track of the Sense service state and updating the status
* bar notification when the service is started or changes login status. We use the singleton
* pattern to make sure the entire application can see the same state object.
*
* @author Steven Mulder <steven@sense-os.nl>
*/
public class ServiceStateHelper {
private static ServiceStateHelper instance = null;
/**
* ID for the notification in the status bar. Used to cancel the notification.
*/
public static final int NOTIF_ID = 1;
@SuppressWarnings("unused")
private static final String TAG = "Sense Service State";
/**
* @param context
* Context for lazy creating the ServiceStateHelper. Used to create notifications.
* @return Singleton instance of the ServiceStateHelper
*/
public static ServiceStateHelper getInstance(Context context) {
if (null != instance) {
return instance;
} else {
return instance = new ServiceStateHelper(context);
}
}
private final Context context;
private boolean started, foreground, loggedIn;
/**
* Private constructor to enforce singleton pattern.
*
* @param context
* @see ServiceStateHelper#getInstance(Context)
*/
private ServiceStateHelper(Context context) {
this.context = context;
}
public Notification getStateNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
// icon and content text depend on the current state
int icon = -1;
int contentText = -1;
if (isStarted()) {
if (isLoggedIn()) {
icon = R.drawable.ic_stat_sense;
contentText = R.string.stat_notify_content_on_loggedin;
} else {
icon = R.drawable.ic_stat_sense_warning;
contentText = R.string.stat_notify_content_on_loggedout;
}
} else {
if (isLoggedIn()) {
icon = R.drawable.ic_stat_sense_error;
contentText = R.string.stat_notify_content_off_loggedin;
} else {
icon = R.drawable.ic_stat_sense_error;
contentText = R.string.stat_notify_content_off_loggedout;
}
}
builder.setSmallIcon(icon);
// username will be substituted into the content text
final SharedPreferences authPrefs = context.getSharedPreferences(SensePrefs.AUTH_PREFS,
Context.MODE_PRIVATE);
String username = authPrefs.getString(Auth.LOGIN_USERNAME,
context.getString(android.R.string.unknownName));
builder.setContentText(context.getString(contentText, username));
builder.setContentTitle(context.getString(R.string.stat_notify_title));
// action to take when the notification is tapped
final Intent notifIntent = new Intent(context.getString(R.string.stat_notify_action));
notifIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notifIntent, 0);
builder.setContentIntent(contentIntent);
// time of the notification
builder.setWhen(System.currentTimeMillis());
builder.setOngoing(true);
return builder.build();
}
public boolean isForeground() {
return foreground;
}
public boolean isLoggedIn() {
return loggedIn;
}
public boolean isStarted() {
return started;
}
public void setForeground(boolean foreground) {
if (foreground != isForeground()) {
this.foreground = foreground;
// Log.v(TAG, isForeground()
// ? "Sense Platform Service is in foreground..."
// : "Sense Platform Service is in background...");
updateNotification();
}
// context.startService(new Intent(context.getString(R.string.action_widget_update)));
}
public void setLoggedIn(boolean loggedIn) {
if (loggedIn != isLoggedIn()) {
this.loggedIn = loggedIn;
// Log.v(TAG, isLoggedIn() ? "Sense Platform Service logged in..."
// : "Sense Platform Service logged out...");
updateNotification();
}
// context.startService(new Intent(context.getString(R.string.action_widget_update)));
}
public void setStarted(boolean started) {
if (started != isStarted()) {
this.started = started;
// Log.v(TAG, isStarted()
// ? "Sense Platform Service started..."
// : "Sense Platform Service stopped...");
updateNotification();
}
// context.startService(new Intent(context.getString(R.string.action_widget_update)));
}
/**
* Shows a status bar notification that the Sense service is active, also displaying the
* username if the service is logged in.
*
* @param loggedIn
* set to <code>true</code> if the service is logged in.
*/
private void updateNotification() {
NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
if (isForeground()) {
nm.notify(NOTIF_ID, getStateNotification());
} else {
nm.cancel(NOTIF_ID);
}
}
/**
* @return the current status of the sensing modules
*/
public int getStatusCode() {
int status = 0;
status = isStarted() ? SenseStatusCodes.RUNNING : status;
status = isLoggedIn() ? status + SenseStatusCodes.CONNECTED : status;
return status;
}
}