package com.android.smap.sms;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import com.android.smap.GatewayApp;
import com.android.smap.api.services.MessageSender;
import com.android.smap.api.services.MessageResponder;
import com.android.smap.commonsware.wakefull.WakefulIntentService;
import com.android.smap.controllers.ControllerError;
import com.android.smap.controllers.ControllerErrorListener;
import com.android.smap.controllers.ControllerListener;
import com.android.smap.models.SmapTextMessage;
import com.android.smap.models.TextMessage;
import java.io.IOException;
import java.util.List;
public class GatewayService extends Service implements
CellularModem.SmsModemListener,
ControllerListener,
ControllerErrorListener,
MessageSender {
public static final String TAG = GatewayService.class
.getCanonicalName();
public static GatewayService s_this = null;
public CellularModem modem;
public static GatewayService get() {
return s_this;
}
public static boolean doReset = false;
private final IBinder mBinder = new LocalBinder();
@Override
public void onCreate() {
s_this = this;
modem = new CellularModem(getApplicationContext(), this);
Log.d(TAG, "RelayService Created.");
promoteErroredMessages();
kickService();
}
public class LocalBinder extends Binder {
public GatewayService getService() {
// Return this instance of LocalService so clients can call public methods
return GatewayService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* This should be run only when our service starts, and takes care of
* resending any messages that were queued but which we never got a reply
* for. This could result in double sends but that's better than leaving a
* message on the floor.
*/
public void promoteErroredMessages() {
// for all messages that never got replied to (and so never had their
// pending status revoked. ) ?
// call sendPendingMessagesToServer?
// call only at startup
// TODO
}
/**
* Goes through all the messages which have errors and resends them. Note
* that we only try to send five at a time, so it could take a bit to clear
* out the backlog.
*/
public void resendErroredSMS() {
// TODO
}
/**
* Sends all our pending outgoing messages to our server.
*/
public void sendPendingMessagesToServer() throws IOException {
List<TextMessage> msgs = null;
// first send any that haven't yet been tried
// get all the msgs with fresh status
for (TextMessage msg : msgs) {
sendMessageToServer(msg);
}
// then those that had an error when we tried to contact the server
// get all the error sattus msgs
for (TextMessage msg : msgs) {
sendMessageToServer(msg);
}
}
public void markDeliveries() {
// change status to delivered
}
/**
* Sends a message to our server.
*
* @param msg
*/
public void sendMessageToServer(TextMessage msg) throws IOException {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
String receiveURL = prefs.getString("receive_url", null);
boolean process_outgoing = prefs.getBoolean("process_outgoing", false);
// message
// send volley request
}
public void markMessageDelivered(TextMessage msg) {
// update status of message, pending becomes sent. etc
}
// triggers our background service to go do things
public void kickService() {
WakefulIntentService.sendWakefulWork(this, MonitorService.class);
}
public void sendMessage(TextMessage msg) {
Log.d(TAG, "=== SMS OUT: " + msg.number + ": " + msg.text);
try {
modem.sendSms(msg.number, msg.text, "" + msg.id);
} catch (Exception e) {
msg.status = TextMessage.ERRORED;
}
}
// SMS received by gateway
public void onNewSMS(String number, String message) {
MessageResponder responder = getResponder();
responder.setResource(this.getApplicationContext().getResources());
SmapTextMessage textMessage = new SmapTextMessage(number, message);
if (!textMessage.isSmapMessage()) {
Log.i(TAG,"Not a SMAP Message");
return;
}
responder.handleMessage(this, textMessage);
}
private MessageResponder getResponder() {
return GatewayApp.getDependencyContainer().getInjector().getInstance(MessageResponder.class);
}
public void onSMSSendError(String token, String errorDetails) {
TextMessage msg = null;
// change status, add to backlog
}
public void onSMSSent(String token) {
// change status to sent,
// kickService()
}
@Override
public void onControllerError(ControllerError error) {
// TODO error with request handeling.
}
@Override
public void onControllerResult() {
// TODO succesfull outbound request
}
}