package com.laulkar.services;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import com.laulkar.Constants;
import com.laulkar.R;
import com.laulkar.activities.SubwayList;
import com.laulkar.dataproviders.Alarm;
import com.laulkar.dataproviders.AlarmDbAdapter;
import com.laulkar.dataproviders.DataProvider;
import com.laulkar.dataproviders.MtaStatus;
import com.laulkar.dataproviders.Subway;
import com.laulkar.dataproviders.SubwayDbAdapter;
public class MessengerService extends Service {
MtaStatus status;
/** For showing and hiding our notification. */
NotificationManager mNM;
/** Keeps track of all current registered clients. */
ArrayList<Messenger> mClients = new ArrayList<Messenger>();
/** Holds last value set by a client. */
int mValue = 0;
/**
* Command to the service to register a client, receiving callbacks
* from the service. The Message's replyTo field must be a Messenger of
* the client where callbacks should be sent.
*/
public static final int MSG_REGISTER_CLIENT = 1;
/**
* Command to the service to unregister a client, ot stop receiving callbacks
* from the service. The Message's replyTo field must be a Messenger of
* the client as previously given with MSG_REGISTER_CLIENT.
*/
public static final int MSG_UNREGISTER_CLIENT = 2;
/**
* Command to service to set a new value. This can be sent to the
* service to supply a new value, and will be sent by the service to
* any registered clients with the new value.
*/
public static final int MSG_GET_STATUS = 3;
/**
* Command to service to set a new value. This can be sent to the
* service to supply a new value, and will be sent by the service to
* any registered clients with the new value.
*/
public static final int MSG_START_PERIODIC =4;
/**
* Command to service to set a new value. This can be sent to the
* service to supply a new value, and will be sent by the service to
* any registered clients with the new value.
*/
public static final int MSG_STOP_PERIODIC = 5;
/**
* Key for subway list
*/
public static final String SUBWAY_LIST_KEY = "subway_list";
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_GET_STATUS:
informCurrentStatus();
break;
case MSG_START_PERIODIC:
//startPeriodicCheck();
break;
case MSG_STOP_PERIODIC:
//stopPeriodicCheck();
break;
default:
super.handleMessage(msg);
}
}
}
public void informCurrentStatus()
{
Message m = Message.obtain(null, MSG_GET_STATUS, mValue, 0);
Bundle b = new Bundle();
//b.putParcelable(MessengerService.SUBWAY_LIST_KEY, new Subway());
b.putParcelableArrayList(MessengerService.SUBWAY_LIST_KEY, status.subways);
//b.putParcelableArray(MessengerService.SUBWAY_LIST_KEY, subway);
m.setData(b);
for (int i=mClients.size()-1; i>=0; i--) {
try {
mClients.get(i).send(m);
} catch (RemoteException e) {
// The client is dead. Remove it from the list;
// we are going through the list from back to front
// so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
private SubwayDbAdapter mDbHelper;
public MtaStatus checkStatus()
{
MtaStatus status = DataProvider.getStatusCSV();
for(Subway s : status.subways)
{
Subway sdb = mDbHelper.fetchSubway(s.line);
if(sdb == null)
{
mDbHelper.createSubway(s.line, s.status);
}
else {
mDbHelper.updateSubway(s.line, s.status);
checkIfNotificationRequired(sdb, s.status);
}
}
return status;
}
private void checkIfNotificationRequired(Subway s, String status) {
SharedPreferences pref = getSharedPreferences(Constants.SHARED_PREF_SUBWAY, 0);
Log.i("checkNotification", "Subway " + s.line + " status:"+ status);
boolean informUser = pref.getBoolean(s.line, true);
// If user does not subscribe to this line, return
if(!informUser)
return;
// Do not warn if the status is same
//if(s.status.equalsIgnoreCase(status))
// return;
if(status.equalsIgnoreCase("delays"))
alertUserDelays(s.line);
// Service has been restored
if(status.equalsIgnoreCase("good service") && !s.status.equalsIgnoreCase("good service"))
{
alertUserGoodService(s.line);
}
}
private void alertUserGoodService(String line) {
//In this sample, we'll use the same text for the ticker and the expanded notification
String text = "Line " + line + " Good Service";
// Set the icon, scrolling text and timestamp
int id = Constants.subway_icons.get(line);
Notification notification = new Notification(id, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, SubwayList.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, text,
text, contentIntent);
// Send the notification.
// We use a string id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.remote_service_connected, notification);
}
private void alertUserDelays(String line) {
//In this sample, we'll use the same text for the ticker and the expanded notification
String text = "Line " + line + " Delays";
// Set the icon, scrolling text and timestamp
int id = Constants.subway_icons.get(line);
Notification notification = new Notification(id, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, SubwayList.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, text ,
text, contentIntent);
// Send the notification.
// We use a string id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.remote_service_connected, notification);
}
/*
public void startPeriodicCheck()
{
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 30*1000, mAlarmSender);
// Tell the user about what we did.
//Toast.makeText(AlarmService.this, R.string.repeating_scheduled,
// Toast.LENGTH_LONG).show();
}
public void stopPeriodicCheck()
{
}
*/
public MtaStatus getStatus()
{
Toast.makeText(this, R.string.remote_service_connected, Toast.LENGTH_SHORT).show();
//URL url = new URL(eText.getText().toString());
MtaStatus status = null;
try {
status = DataProvider.parseStatus(getResources());
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//TODO Check for settings and notifications goes here
return status;
}
@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Display a notification about us starting.
//status = getStatus();
AlarmDbAdapter db = new AlarmDbAdapter(this);
db.open();
List<Alarm> alarms = db.checkAlarms();
if(alarms == null)
{
MessengerService.this.stopSelf();
}
showNotification();
mDbHelper = new SubwayDbAdapter(this);
mDbHelper.open();
checkStatus();
MessengerService.this.stopSelf();
}
@Override
public void onDestroy() {
// Cancel the persistent notification.
//mNM.cancel(R.string.remote_service_started);
// Tell the user we stopped.
Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
mDbHelper.close();
}
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
/**
* Show a notification while this service is running.
*/
private void showNotification() {
Toast.makeText(this, R.string.remote_service_connected, Toast.LENGTH_SHORT).show();
Log.i("service**", "Doing some work");
}
}
|