4
0
mirror of https://github.com/cwinfo/envayasms.git synced 2025-07-04 05:57:44 +00:00

support for incoming MMS

This commit is contained in:
Jesse Young
2011-09-17 18:38:16 -07:00
parent 60d49414e1
commit d994b10c35
23 changed files with 787 additions and 159 deletions

View File

@ -10,9 +10,11 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.util.Log;
import java.text.DateFormat;
@ -26,24 +28,56 @@ public final class App extends Application {
public static final String ACTION_OUTGOING = "outgoing";
public static final String ACTION_INCOMING = "incoming";
public static final String ACTION_SEND_STATUS = "send_status";
public static final String STATUS_QUEUED = "queued";
public static final String STATUS_FAILED = "failed";
public static final String STATUS_SENT = "sent";
public static final String MESSAGE_TYPE_MMS = "mms";
public static final String MESSAGE_TYPE_SMS = "sms";
public static final String LOG_NAME = "KALSMS";
public static final String LOG_INTENT = "org.envaya.kalsms.LOG";
public static final int MAX_DISPLAYED_LOG = 15000;
public static final int LOG_TIMESTAMP_INTERVAL = 60000;
private long lastLogTime = 0;
private SpannableStringBuilder displayedLog = new SpannableStringBuilder();
private Map<String, IncomingMessage> incomingSmsMap = new HashMap<String, IncomingMessage>();
private Map<String, OutgoingMessage> outgoingSmsMap = new HashMap<String, OutgoingMessage>();
// Each QueuedMessage is identified within our internal Map by its Uri.
// Currently QueuedMessage instances are only available within KalSMS,
// (but they could be made available to other applications later via a ContentProvider)
public static final Uri CONTENT_URI = Uri.parse("content://org.envaya.kalsms");
public static final Uri INCOMING_URI = Uri.withAppendedPath(CONTENT_URI, "incoming");
public static final Uri OUTGOING_URI = Uri.withAppendedPath(CONTENT_URI, "outgoing");
private Map<Uri, IncomingMessage> incomingMessages = new HashMap<Uri, IncomingMessage>();
private Map<Uri, OutgoingMessage> outgoingMessages = new HashMap<Uri, OutgoingMessage>();
public SharedPreferences getSettings()
private SharedPreferences settings;
private MmsObserver mmsObserver;
private SpannableStringBuilder displayedLog = new SpannableStringBuilder();
private long lastLogTime;
private MmsUtils mmsUtils;
@Override
public void onCreate()
{
return PreferenceManager.getDefaultSharedPreferences(this);
}
super.onCreate();
settings = PreferenceManager.getDefaultSharedPreferences(this);
mmsUtils = new MmsUtils(this);
log(Html.fromHtml(
isEnabled() ? "<b>SMS gateway running.</b>" : "<b>SMS gateway disabled.</b>"));
log("Server URL is: " + getDisplayString(getServerUrl()));
log("Your phone number is: " + getDisplayString(getPhoneNumber()));
mmsObserver = new MmsObserver(this);
mmsObserver.register();
setOutgoingMessageAlarm();
}
public void checkOutgoingMessages()
{
@ -92,29 +126,29 @@ public final class App extends Application {
}
public String getServerUrl() {
return getSettings().getString("server_url", "");
return settings.getString("server_url", "");
}
public String getPhoneNumber() {
return getSettings().getString("phone_number", "");
return settings.getString("phone_number", "");
}
public int getOutgoingPollSeconds() {
return Integer.parseInt(getSettings().getString("outgoing_interval", "0"));
return Integer.parseInt(settings.getString("outgoing_interval", "0"));
}
public boolean isEnabled()
{
return getSettings().getBoolean("enabled", false);
return settings.getBoolean("enabled", false);
}
public boolean getKeepInInbox()
{
return getSettings().getBoolean("keep_in_inbox", false);
return settings.getBoolean("keep_in_inbox", false);
}
public String getPassword() {
return getSettings().getString("password", "");
return settings.getString("password", "");
}
private void notifyStatus(OutgoingMessage sms, String status, String errorMessage) {
@ -150,35 +184,45 @@ public final class App extends Application {
}
public synchronized int getStuckMessageCount() {
return outgoingSmsMap.size() + incomingSmsMap.size();
return outgoingMessages.size() + incomingMessages.size();
}
public synchronized void retryStuckOutgoingMessages() {
for (OutgoingMessage sms : outgoingSmsMap.values()) {
for (OutgoingMessage sms : outgoingMessages.values()) {
sms.retryNow();
}
}
public synchronized void retryStuckIncomingMessages() {
for (IncomingMessage sms : incomingSmsMap.values()) {
for (IncomingMessage sms : incomingMessages.values()) {
sms.retryNow();
}
}
public synchronized void setIncomingMessageStatus(IncomingMessage sms, boolean success) {
String id = sms.getId();
public synchronized void setIncomingMessageStatus(IncomingMessage message, boolean success) {
Uri uri = message.getUri();
if (success)
{
incomingSmsMap.remove(id);
incomingMessages.remove(uri);
if (message instanceof IncomingMms)
{
IncomingMms mms = (IncomingMms)message;
if (!getKeepInInbox())
{
log("Deleting MMS " + mms.getId() + " from inbox...");
mmsUtils.deleteFromInbox(mms);
}
}
}
else if (!sms.scheduleRetry())
else if (!message.scheduleRetry())
{
incomingSmsMap.remove(id);
incomingMessages.remove(uri);
}
}
public synchronized void notifyOutgoingMessageStatus(String id, int resultCode) {
OutgoingMessage sms = outgoingSmsMap.get(id);
public synchronized void notifyOutgoingMessageStatus(Uri uri, int resultCode) {
OutgoingMessage sms = outgoingMessages.get(uri);
if (sms == null) {
return;
@ -210,52 +254,52 @@ public final class App extends Application {
case SmsManager.RESULT_ERROR_RADIO_OFF:
case SmsManager.RESULT_ERROR_NO_SERVICE:
if (!sms.scheduleRetry()) {
outgoingSmsMap.remove(id);
outgoingMessages.remove(uri);
}
break;
default:
outgoingSmsMap.remove(id);
outgoingMessages.remove(uri);
break;
}
}
public synchronized void sendOutgoingMessage(OutgoingMessage sms) {
String id = sms.getId();
if (outgoingSmsMap.containsKey(id)) {
Uri uri = sms.getUri();
if (outgoingMessages.containsKey(uri)) {
log(sms.getLogName() + " already sent, skipping");
return;
}
outgoingSmsMap.put(id, sms);
outgoingMessages.put(uri, sms);
log("Sending " + sms.getLogName() + " to " + sms.getTo());
sms.trySend();
}
public synchronized void forwardToServer(IncomingMessage sms) {
String id = sms.getId();
public synchronized void forwardToServer(IncomingMessage message) {
Uri uri = message.getUri();
if (incomingSmsMap.containsKey(id)) {
log("Duplicate incoming SMS, skipping");
if (incomingMessages.containsKey(uri)) {
log("Duplicate incoming "+message.getDisplayType()+", skipping");
return;
}
incomingSmsMap.put(id, sms);
incomingMessages.put(uri, message);
log("Received SMS from " + sms.getFrom());
log("Received "+message.getDisplayType()+" from " + message.getFrom());
sms.tryForwardToServer();
message.tryForwardToServer();
}
public synchronized void retryIncomingMessage(String id) {
IncomingMessage sms = incomingSmsMap.get(id);
if (sms != null) {
sms.retryNow();
public synchronized void retryIncomingMessage(Uri uri) {
IncomingMessage message = incomingMessages.get(uri);
if (message != null) {
message.retryNow();
}
}
public synchronized void retryOutgoingMessage(String id) {
OutgoingMessage sms = outgoingSmsMap.get(id);
public synchronized void retryOutgoingMessage(Uri uri) {
OutgoingMessage sms = outgoingMessages.get(uri);
if (sms != null) {
sms.retryNow();
}
@ -265,7 +309,7 @@ public final class App extends Application {
Log.d(LOG_NAME, msg);
}
public void log(CharSequence msg)
public synchronized void log(CharSequence msg)
{
Log.d(LOG_NAME, msg.toString());
@ -303,7 +347,7 @@ public final class App extends Application {
sendBroadcast(broadcast);
}
public CharSequence getDisplayedLog()
public synchronized CharSequence getDisplayedLog()
{
return displayedLog;
}
@ -328,6 +372,10 @@ public final class App extends Application {
logError("Inner exception:", innerEx, true);
}
}
}
public MmsUtils getMmsUtils()
{
return mmsUtils;
}
}