mirror of
https://github.com/cwinfo/envayasms.git
synced 2024-12-04 20:45:32 +00:00
instead of deleting messages from inbox, prevent them from getting there in the first place (unless user wants to keep them)
This commit is contained in:
parent
bead45360f
commit
e535266d9a
@ -24,7 +24,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<receiver android:name=".IncomingMessageForwarder">
|
<receiver android:name=".IncomingMessageForwarder">
|
||||||
<intent-filter>
|
<intent-filter android:priority="101">
|
||||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
@ -30,5 +30,14 @@
|
|||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="launch_on_boot"
|
android:key="launch_on_boot"
|
||||||
android:title="Launch automatically?"
|
android:title="Launch automatically?"
|
||||||
|
android:summaryOff="KalSMS will not open when phone boots (but will still forward SMS)"
|
||||||
|
android:summaryOn="KalSMS will open when phone boots"
|
||||||
></CheckBoxPreference>
|
></CheckBoxPreference>
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="keep_in_inbox"
|
||||||
|
android:title="Keep new messages?"
|
||||||
|
android:summaryOff="Incoming SMS will not be stored in Messaging inbox"
|
||||||
|
android:summaryOn="Incoming SMS will be stored in Messaging inbox"
|
||||||
|
></CheckBoxPreference>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@ -7,9 +7,11 @@ package org.envaya.kalsms;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@ -22,349 +24,289 @@ import org.apache.http.HttpResponse;
|
|||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
public static final String ACTION_OUTGOING = "outgoing";
|
public static final String ACTION_OUTGOING = "outgoing";
|
||||||
public static final String ACTION_INCOMING = "incoming";
|
public static final String ACTION_INCOMING = "incoming";
|
||||||
public static final String ACTION_SEND_STATUS = "send_status";
|
public static final String ACTION_SEND_STATUS = "send_status";
|
||||||
|
|
||||||
public static final String STATUS_QUEUED = "queued";
|
public static final String STATUS_QUEUED = "queued";
|
||||||
public static final String STATUS_FAILED = "failed";
|
public static final String STATUS_FAILED = "failed";
|
||||||
public static final String STATUS_SENT = "sent";
|
public static final String STATUS_SENT = "sent";
|
||||||
|
|
||||||
public static final String LOG_NAME = "KALSMS";
|
public static final String LOG_NAME = "KALSMS";
|
||||||
public static final String LOG_INTENT = "org.envaya.kalsms.LOG";
|
public static final String LOG_INTENT = "org.envaya.kalsms.LOG";
|
||||||
|
private static App app;
|
||||||
private static App app;
|
|
||||||
|
|
||||||
private Map<String, QueuedIncomingSms> incomingSmsMap = new HashMap<String, QueuedIncomingSms>();
|
private Map<String, QueuedIncomingSms> incomingSmsMap = new HashMap<String, QueuedIncomingSms>();
|
||||||
private Map<String, QueuedOutgoingSms> outgoingSmsMap = new HashMap<String, QueuedOutgoingSms>();
|
private Map<String, QueuedOutgoingSms> outgoingSmsMap = new HashMap<String, QueuedOutgoingSms>();
|
||||||
|
|
||||||
public Context context;
|
public Context context;
|
||||||
public SharedPreferences settings;
|
public SharedPreferences settings;
|
||||||
|
|
||||||
private abstract class QueuedMessage<T>
|
private abstract class QueuedMessage<T> {
|
||||||
{
|
|
||||||
public T sms;
|
public T sms;
|
||||||
public long nextAttemptTime = 0;
|
public long nextAttemptTime = 0;
|
||||||
public int numAttempts = 0;
|
public int numAttempts = 0;
|
||||||
|
|
||||||
public boolean canAttemptNow()
|
public boolean canAttemptNow() {
|
||||||
{
|
|
||||||
return (nextAttemptTime > 0 && nextAttemptTime < SystemClock.elapsedRealtime());
|
return (nextAttemptTime > 0 && nextAttemptTime < SystemClock.elapsedRealtime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean scheduleNextAttempt()
|
public boolean scheduleNextAttempt() {
|
||||||
{
|
|
||||||
long now = SystemClock.elapsedRealtime();
|
long now = SystemClock.elapsedRealtime();
|
||||||
numAttempts++;
|
numAttempts++;
|
||||||
|
|
||||||
if (numAttempts > 4)
|
if (numAttempts > 4) {
|
||||||
{
|
|
||||||
log("5th failure: giving up");
|
log("5th failure: giving up");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int second = 1000;
|
int second = 1000;
|
||||||
int minute = second * 60;
|
int minute = second * 60;
|
||||||
|
|
||||||
if (numAttempts == 1)
|
if (numAttempts == 1) {
|
||||||
{
|
|
||||||
log("1st failure; retry in 1 minute");
|
log("1st failure; retry in 1 minute");
|
||||||
nextAttemptTime = now + 1 * minute;
|
nextAttemptTime = now + 1 * minute;
|
||||||
}
|
} else if (numAttempts == 2) {
|
||||||
else if (numAttempts == 2)
|
|
||||||
{
|
|
||||||
log("2nd failure; retry in 10 minutes");
|
log("2nd failure; retry in 10 minutes");
|
||||||
nextAttemptTime = now + 10 * minute;
|
nextAttemptTime = now + 10 * minute;
|
||||||
}
|
} else if (numAttempts == 3) {
|
||||||
else if (numAttempts == 3)
|
|
||||||
{
|
|
||||||
log("3rd failure; retry in 1 hour");
|
log("3rd failure; retry in 1 hour");
|
||||||
nextAttemptTime = now + 60 * minute;
|
nextAttemptTime = now + 60 * minute;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
log("4th failure: retry in 1 day");
|
log("4th failure: retry in 1 day");
|
||||||
nextAttemptTime = now + 24 * 60 * minute;
|
nextAttemptTime = now + 24 * 60 * minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
|
||||||
0,
|
0,
|
||||||
getAttemptIntent(),
|
getAttemptIntent(),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
alarm.set(
|
alarm.set(
|
||||||
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
nextAttemptTime,
|
nextAttemptTime,
|
||||||
pendingIntent);
|
pendingIntent);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void attemptNow();
|
public abstract void attemptNow();
|
||||||
protected abstract Intent getAttemptIntent();
|
|
||||||
}
|
protected abstract Intent getAttemptIntent();
|
||||||
|
}
|
||||||
|
|
||||||
private class QueuedIncomingSms extends QueuedMessage<SmsMessage> {
|
private class QueuedIncomingSms extends QueuedMessage<SmsMessage> {
|
||||||
public QueuedIncomingSms(SmsMessage sms)
|
|
||||||
{
|
public QueuedIncomingSms(SmsMessage sms) {
|
||||||
this.sms = sms;
|
this.sms = sms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attemptNow()
|
public void attemptNow() {
|
||||||
{
|
log("Retrying forwarding SMS from " + sms.getOriginatingAddress());
|
||||||
log("Retrying forwarding SMS from " + sms.getOriginatingAddress());
|
|
||||||
trySendMessageToServer(sms);
|
trySendMessageToServer(sms);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Intent getAttemptIntent()
|
protected Intent getAttemptIntent() {
|
||||||
{
|
|
||||||
Intent intent = new Intent(context, IncomingMessageRetry.class);
|
Intent intent = new Intent(context, IncomingMessageRetry.class);
|
||||||
intent.setData(Uri.parse("kalsms://incoming/" + getSmsId(sms)));
|
intent.setData(Uri.parse("kalsms://incoming/" + getSmsId(sms)));
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class QueuedOutgoingSms extends QueuedMessage<OutgoingSmsMessage> {
|
private class QueuedOutgoingSms extends QueuedMessage<OutgoingSmsMessage> {
|
||||||
public QueuedOutgoingSms(OutgoingSmsMessage sms)
|
|
||||||
{
|
public QueuedOutgoingSms(OutgoingSmsMessage sms) {
|
||||||
this.sms = sms;
|
this.sms = sms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attemptNow()
|
public void attemptNow() {
|
||||||
{
|
log("Retrying sending " + sms.getLogName() + " to " + sms.getTo());
|
||||||
log("Retrying sending " +sms.getLogName() + " to " + sms.getTo());
|
trySendSMS(sms);
|
||||||
trySendSMS(sms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Intent getAttemptIntent()
|
protected Intent getAttemptIntent() {
|
||||||
{
|
|
||||||
Intent intent = new Intent(context, OutgoingMessageRetry.class);
|
Intent intent = new Intent(context, OutgoingMessageRetry.class);
|
||||||
intent.setData(Uri.parse("kalsms://outgoing/" + sms.getId()));
|
intent.setData(Uri.parse("kalsms://outgoing/" + sms.getId()));
|
||||||
log("id=" + sms.getId());
|
log("id=" + sms.getId());
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected App(Context context)
|
protected App(Context context) {
|
||||||
{
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.settings = PreferenceManager.getDefaultSharedPreferences(context);
|
this.settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static App getInstance(Context context)
|
public static App getInstance(Context context) {
|
||||||
{
|
if (app == null) {
|
||||||
if (app == null)
|
|
||||||
{
|
|
||||||
app = new App(context);
|
app = new App(context);
|
||||||
}
|
}
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(String msg)
|
public void debug(String msg) {
|
||||||
{
|
|
||||||
Log.d(LOG_NAME, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void log(String msg)
|
|
||||||
{
|
|
||||||
Log.d(LOG_NAME, msg);
|
Log.d(LOG_NAME, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String msg) {
|
||||||
|
Log.d(LOG_NAME, msg);
|
||||||
|
|
||||||
Intent broadcast = new Intent(App.LOG_INTENT);
|
Intent broadcast = new Intent(App.LOG_INTENT);
|
||||||
broadcast.putExtra("message", msg);
|
broadcast.putExtra("message", msg);
|
||||||
context.sendBroadcast(broadcast);
|
context.sendBroadcast(broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkOutgoingMessages()
|
public void checkOutgoingMessages() {
|
||||||
{
|
|
||||||
String serverUrl = getServerUrl();
|
String serverUrl = getServerUrl();
|
||||||
if (serverUrl.length() > 0)
|
if (serverUrl.length() > 0) {
|
||||||
{
|
|
||||||
log("Checking for outgoing messages");
|
log("Checking for outgoing messages");
|
||||||
new PollerTask().execute(
|
new PollerTask().execute(
|
||||||
new BasicNameValuePair("action", App.ACTION_OUTGOING)
|
new BasicNameValuePair("action", App.ACTION_OUTGOING));
|
||||||
);
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Can't check outgoing messages; server URL not set");
|
log("Can't check outgoing messages; server URL not set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutgoingMessageAlarm()
|
public void setOutgoingMessageAlarm() {
|
||||||
{
|
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
|
||||||
0,
|
0,
|
||||||
new Intent(context, OutgoingMessagePoller.class),
|
new Intent(context, OutgoingMessagePoller.class),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
alarm.cancel(pendingIntent);
|
alarm.cancel(pendingIntent);
|
||||||
|
|
||||||
int pollSeconds = getOutgoingPollSeconds();
|
int pollSeconds = getOutgoingPollSeconds();
|
||||||
|
|
||||||
if (pollSeconds > 0)
|
if (pollSeconds > 0) {
|
||||||
{
|
|
||||||
alarm.setRepeating(
|
alarm.setRepeating(
|
||||||
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
SystemClock.elapsedRealtime(),
|
SystemClock.elapsedRealtime(),
|
||||||
pollSeconds * 1000,
|
pollSeconds * 1000,
|
||||||
pendingIntent);
|
pendingIntent);
|
||||||
log("Checking for outgoing messages every " + pollSeconds + " sec");
|
log("Checking for outgoing messages every " + pollSeconds + " sec");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Not checking for outgoing messages.");
|
log("Not checking for outgoing messages.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logError(Throwable ex)
|
public void logError(Throwable ex) {
|
||||||
{
|
|
||||||
logError("ERROR", ex);
|
logError("ERROR", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logError(String msg, Throwable ex)
|
public void logError(String msg, Throwable ex) {
|
||||||
{
|
|
||||||
logError(msg, ex, false);
|
logError(msg, ex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logError(String msg, Throwable ex, boolean detail)
|
public void logError(String msg, Throwable ex, boolean detail) {
|
||||||
{
|
|
||||||
log(msg + ": " + ex.getClass().getName() + ": " + ex.getMessage());
|
log(msg + ": " + ex.getClass().getName() + ": " + ex.getMessage());
|
||||||
|
|
||||||
if (detail)
|
if (detail) {
|
||||||
{
|
for (StackTraceElement elem : ex.getStackTrace()) {
|
||||||
for (StackTraceElement elem : ex.getStackTrace())
|
|
||||||
{
|
|
||||||
log(elem.getClassName() + ":" + elem.getMethodName() + ":" + elem.getLineNumber());
|
log(elem.getClassName() + ":" + elem.getMethodName() + ":" + elem.getLineNumber());
|
||||||
}
|
}
|
||||||
Throwable innerEx = ex.getCause();
|
Throwable innerEx = ex.getCause();
|
||||||
if (innerEx != null)
|
if (innerEx != null) {
|
||||||
{
|
|
||||||
logError("Inner exception:", innerEx, true);
|
logError("Inner exception:", innerEx, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public String getDisplayString(String str)
|
|
||||||
{
|
|
||||||
if (str.length() == 0)
|
|
||||||
{
|
|
||||||
return "(not set)";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerUrl()
|
public String getDisplayString(String str) {
|
||||||
{
|
if (str.length() == 0) {
|
||||||
|
return "(not set)";
|
||||||
|
} else {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerUrl() {
|
||||||
return settings.getString("server_url", "");
|
return settings.getString("server_url", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPhoneNumber()
|
public String getPhoneNumber() {
|
||||||
{
|
|
||||||
return settings.getString("phone_number", "");
|
return settings.getString("phone_number", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOutgoingPollSeconds() {
|
||||||
|
return Integer.parseInt(settings.getString("outgoing_interval", "0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getLaunchOnBoot() {
|
||||||
|
return settings.getBoolean("launch_on_boot", false);
|
||||||
|
}
|
||||||
|
|
||||||
public int getOutgoingPollSeconds()
|
public boolean getKeepInInbox()
|
||||||
{
|
|
||||||
return Integer.parseInt(settings.getString("outgoing_interval", "0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getLaunchOnBoot()
|
|
||||||
{
|
|
||||||
return settings.getBoolean("launch_on_boot", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword()
|
|
||||||
{
|
{
|
||||||
|
return settings.getBoolean("keep_in_inbox", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
return settings.getString("password", "");
|
return settings.getString("password", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyStatus(OutgoingSmsMessage sms, String status, String errorMessage)
|
private void notifyStatus(OutgoingSmsMessage sms, String status, String errorMessage) {
|
||||||
{
|
|
||||||
String serverId = sms.getServerId();
|
String serverId = sms.getServerId();
|
||||||
|
|
||||||
String logMessage;
|
String logMessage;
|
||||||
if (status.equals(App.STATUS_SENT))
|
if (status.equals(App.STATUS_SENT)) {
|
||||||
{
|
logMessage = "sent successfully";
|
||||||
logMessage = "sent successfully";
|
} else if (status.equals(App.STATUS_FAILED)) {
|
||||||
}
|
|
||||||
else if (status.equals(App.STATUS_FAILED))
|
|
||||||
{
|
|
||||||
logMessage = "could not be sent (" + errorMessage + ")";
|
logMessage = "could not be sent (" + errorMessage + ")";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
logMessage = "queued";
|
logMessage = "queued";
|
||||||
}
|
}
|
||||||
String smsDesc = sms.getLogName();
|
String smsDesc = sms.getLogName();
|
||||||
|
|
||||||
if (serverId != null)
|
if (serverId != null) {
|
||||||
{
|
app.log("Notifying server " + smsDesc + " " + logMessage);
|
||||||
app.log("Notifying server " + smsDesc + " " + logMessage);
|
|
||||||
|
|
||||||
new HttpTask(app).execute(
|
new HttpTask(app).execute(
|
||||||
new BasicNameValuePair("id", serverId),
|
new BasicNameValuePair("id", serverId),
|
||||||
new BasicNameValuePair("status", status),
|
new BasicNameValuePair("status", status),
|
||||||
new BasicNameValuePair("error", errorMessage),
|
new BasicNameValuePair("error", errorMessage),
|
||||||
new BasicNameValuePair("action", App.ACTION_SEND_STATUS)
|
new BasicNameValuePair("action", App.ACTION_SEND_STATUS));
|
||||||
);
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
app.log(smsDesc + " " + logMessage);
|
app.log(smsDesc + " " + logMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void retryStuckMessages()
|
public synchronized void retryStuckMessages() {
|
||||||
{
|
|
||||||
retryStuckOutgoingMessages();
|
retryStuckOutgoingMessages();
|
||||||
retryStuckIncomingMessages();
|
retryStuckIncomingMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int getStuckMessageCount()
|
public synchronized int getStuckMessageCount() {
|
||||||
{
|
|
||||||
return outgoingSmsMap.size() + incomingSmsMap.size();
|
return outgoingSmsMap.size() + incomingSmsMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void retryStuckOutgoingMessages()
|
public synchronized void retryStuckOutgoingMessages() {
|
||||||
{
|
for (QueuedOutgoingSms queuedSms : outgoingSmsMap.values()) {
|
||||||
for (QueuedOutgoingSms queuedSms : outgoingSmsMap.values())
|
|
||||||
{
|
|
||||||
queuedSms.attemptNow();
|
queuedSms.attemptNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void retryStuckIncomingMessages()
|
public synchronized void retryStuckIncomingMessages() {
|
||||||
{
|
for (QueuedIncomingSms queuedSms : incomingSmsMap.values()) {
|
||||||
for (QueuedIncomingSms queuedSms : incomingSmsMap.values())
|
|
||||||
{
|
|
||||||
queuedSms.attemptNow();
|
queuedSms.attemptNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void notifyOutgoingMessageStatus(String id, int resultCode)
|
public synchronized void notifyOutgoingMessageStatus(String id, int resultCode) {
|
||||||
{
|
|
||||||
QueuedOutgoingSms queuedSms = outgoingSmsMap.get(id);
|
QueuedOutgoingSms queuedSms = outgoingSmsMap.get(id);
|
||||||
|
|
||||||
if (queuedSms == null)
|
if (queuedSms == null) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutgoingSmsMessage sms = queuedSms.sms;
|
OutgoingSmsMessage sms = queuedSms.sms;
|
||||||
|
|
||||||
switch (resultCode) {
|
switch (resultCode) {
|
||||||
case Activity.RESULT_OK:
|
case Activity.RESULT_OK:
|
||||||
this.notifyStatus(sms, App.STATUS_SENT, "");
|
this.notifyStatus(sms, App.STATUS_SENT, "");
|
||||||
break;
|
break;
|
||||||
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
||||||
this.notifyStatus(sms, App.STATUS_FAILED, "generic failure");
|
this.notifyStatus(sms, App.STATUS_FAILED, "generic failure");
|
||||||
break;
|
break;
|
||||||
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
||||||
@ -373,7 +315,7 @@ public class App {
|
|||||||
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
||||||
this.notifyStatus(sms, App.STATUS_FAILED, "no service");
|
this.notifyStatus(sms, App.STATUS_FAILED, "no service");
|
||||||
break;
|
break;
|
||||||
case SmsManager.RESULT_ERROR_NULL_PDU:
|
case SmsManager.RESULT_ERROR_NULL_PDU:
|
||||||
this.notifyStatus(sms, App.STATUS_FAILED, "null PDU");
|
this.notifyStatus(sms, App.STATUS_FAILED, "null PDU");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -381,69 +323,63 @@ public class App {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (resultCode) {
|
switch (resultCode) {
|
||||||
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
||||||
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
||||||
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
||||||
if (!queuedSms.scheduleNextAttempt())
|
if (!queuedSms.scheduleNextAttempt()) {
|
||||||
{
|
|
||||||
outgoingSmsMap.remove(id);
|
outgoingSmsMap.remove(id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
outgoingSmsMap.remove(id);
|
outgoingSmsMap.remove(id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendSMS(OutgoingSmsMessage sms)
|
public synchronized void sendSMS(OutgoingSmsMessage sms) {
|
||||||
{
|
|
||||||
String id = sms.getId();
|
String id = sms.getId();
|
||||||
if (outgoingSmsMap.containsKey(id))
|
if (outgoingSmsMap.containsKey(id)) {
|
||||||
{
|
|
||||||
log(sms.getLogName() + " already sent, skipping");
|
log(sms.getLogName() + " already sent, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuedOutgoingSms queueEntry = new QueuedOutgoingSms(sms);
|
QueuedOutgoingSms queueEntry = new QueuedOutgoingSms(sms);
|
||||||
outgoingSmsMap.put(id, queueEntry);
|
outgoingSmsMap.put(id, queueEntry);
|
||||||
|
|
||||||
log("Sending " +sms.getLogName() + " to " + sms.getTo());
|
log("Sending " + sms.getLogName() + " to " + sms.getTo());
|
||||||
trySendSMS(sms);
|
trySendSMS(sms);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void trySendSMS(OutgoingSmsMessage sms)
|
private void trySendSMS(OutgoingSmsMessage sms) {
|
||||||
{
|
|
||||||
SmsManager smgr = SmsManager.getDefault();
|
SmsManager smgr = SmsManager.getDefault();
|
||||||
|
|
||||||
Intent intent = new Intent(context, MessageStatusNotifier.class);
|
Intent intent = new Intent(context, MessageStatusNotifier.class);
|
||||||
intent.setData(Uri.parse("kalsms://outgoing/" + sms.getId()));
|
intent.setData(Uri.parse("kalsms://outgoing/" + sms.getId()));
|
||||||
|
|
||||||
PendingIntent sentIntent = PendingIntent.getBroadcast(
|
PendingIntent sentIntent = PendingIntent.getBroadcast(
|
||||||
this.context,
|
this.context,
|
||||||
0,
|
0,
|
||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_ONE_SHOT);
|
PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
|
||||||
smgr.sendTextMessage(sms.getTo(), null, sms.getMessage(), sentIntent, null);
|
smgr.sendTextMessage(sms.getTo(), null, sms.getMessage(), sentIntent, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PollerTask extends HttpTask {
|
private class PollerTask extends HttpTask {
|
||||||
|
|
||||||
public PollerTask()
|
public PollerTask() {
|
||||||
{
|
|
||||||
super(app);
|
super(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleResponse(HttpResponse response) throws Exception {
|
protected void handleResponse(HttpResponse response) throws Exception {
|
||||||
for (OutgoingSmsMessage reply : parseResponseXML(response)) {
|
for (OutgoingSmsMessage reply : parseResponseXML(response)) {
|
||||||
app.sendSMS(reply);
|
app.sendSMS(reply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class ForwarderTask extends HttpTask {
|
private class ForwarderTask extends HttpTask {
|
||||||
|
|
||||||
@ -455,94 +391,79 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getDefaultToAddress()
|
protected String getDefaultToAddress() {
|
||||||
{
|
|
||||||
return originalSms.getOriginatingAddress();
|
return originalSms.getOriginatingAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleResponse(HttpResponse response) throws Exception {
|
protected void handleResponse(HttpResponse response) throws Exception {
|
||||||
|
|
||||||
for (OutgoingSmsMessage reply : parseResponseXML(response)) {
|
for (OutgoingSmsMessage reply : parseResponseXML(response)) {
|
||||||
app.sendSMS(reply);
|
app.sendSMS(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.notifyIncomingMessageStatus(originalSms, true);
|
app.notifyIncomingMessageStatus(originalSms, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleFailure()
|
protected void handleFailure() {
|
||||||
{
|
|
||||||
app.notifyIncomingMessageStatus(originalSms, false);
|
app.notifyIncomingMessageStatus(originalSms, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSmsId(SmsMessage sms)
|
private String getSmsId(SmsMessage sms) {
|
||||||
{
|
|
||||||
return sms.getOriginatingAddress() + ":" + sms.getMessageBody() + ":" + sms.getTimestampMillis();
|
return sms.getOriginatingAddress() + ":" + sms.getMessageBody() + ":" + sms.getTimestampMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendMessageToServer(SmsMessage sms)
|
public synchronized void sendMessageToServer(SmsMessage sms) {
|
||||||
{
|
|
||||||
String id = getSmsId(sms);
|
String id = getSmsId(sms);
|
||||||
if (incomingSmsMap.containsKey(id))
|
if (incomingSmsMap.containsKey(id)) {
|
||||||
{
|
|
||||||
log("Duplicate incoming SMS, skipping");
|
log("Duplicate incoming SMS, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuedIncomingSms queuedSms = new QueuedIncomingSms(sms);
|
QueuedIncomingSms queuedSms = new QueuedIncomingSms(sms);
|
||||||
incomingSmsMap.put(id, queuedSms);
|
incomingSmsMap.put(id, queuedSms);
|
||||||
|
|
||||||
app.log("Received SMS from " + sms.getOriginatingAddress());
|
app.log("Received SMS from " + sms.getOriginatingAddress());
|
||||||
|
|
||||||
trySendMessageToServer(sms);
|
trySendMessageToServer(sms);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trySendMessageToServer(SmsMessage sms)
|
public void trySendMessageToServer(SmsMessage sms) {
|
||||||
{
|
|
||||||
String message = sms.getMessageBody();
|
String message = sms.getMessageBody();
|
||||||
String sender = sms.getOriginatingAddress();
|
String sender = sms.getOriginatingAddress();
|
||||||
|
|
||||||
new ForwarderTask(sms).execute(
|
new ForwarderTask(sms).execute(
|
||||||
new BasicNameValuePair("from", sender),
|
new BasicNameValuePair("from", sender),
|
||||||
new BasicNameValuePair("message", message),
|
new BasicNameValuePair("message", message),
|
||||||
new BasicNameValuePair("action", App.ACTION_INCOMING)
|
new BasicNameValuePair("action", App.ACTION_INCOMING));
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void notifyIncomingMessageStatus(SmsMessage sms, boolean success)
|
private synchronized void notifyIncomingMessageStatus(SmsMessage sms, boolean success) {
|
||||||
{
|
|
||||||
String id = getSmsId(sms);
|
String id = getSmsId(sms);
|
||||||
|
|
||||||
QueuedIncomingSms queuedSms = incomingSmsMap.get(id);
|
QueuedIncomingSms queuedSms = incomingSmsMap.get(id);
|
||||||
|
|
||||||
if (queuedSms != null)
|
if (queuedSms != null) {
|
||||||
{
|
if (success || !queuedSms.scheduleNextAttempt()) {
|
||||||
if (success || !queuedSms.scheduleNextAttempt())
|
|
||||||
{
|
|
||||||
incomingSmsMap.remove(id);
|
incomingSmsMap.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void retryIncomingMessage(String id)
|
public synchronized void retryIncomingMessage(String id) {
|
||||||
{
|
|
||||||
QueuedIncomingSms queuedSms = incomingSmsMap.get(id);
|
QueuedIncomingSms queuedSms = incomingSmsMap.get(id);
|
||||||
if (queuedSms != null)
|
if (queuedSms != null) {
|
||||||
{
|
|
||||||
queuedSms.attemptNow();
|
queuedSms.attemptNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void retryOutgoingMessage(String id)
|
public synchronized void retryOutgoingMessage(String id) {
|
||||||
{
|
|
||||||
QueuedOutgoingSms queuedSms = outgoingSmsMap.get(id);
|
QueuedOutgoingSms queuedSms = outgoingSmsMap.get(id);
|
||||||
if (queuedSms != null)
|
if (queuedSms != null) {
|
||||||
{
|
|
||||||
queuedSms.attemptNow();
|
queuedSms.attemptNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@ package org.envaya.kalsms;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -50,41 +52,35 @@ public class HttpTask extends AsyncTask<BasicNameValuePair, Void, HttpResponse>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getSignature(String url, List<BasicNameValuePair> params)
|
private String getSignature(String url, List<BasicNameValuePair> params)
|
||||||
|
throws NoSuchAlgorithmException, UnsupportedEncodingException
|
||||||
{
|
{
|
||||||
try {
|
Collections.sort(params, new Comparator() {
|
||||||
Collections.sort(params, new Comparator() {
|
public int compare(Object o1, Object o2)
|
||||||
public int compare(Object o1, Object o2)
|
|
||||||
{
|
|
||||||
return ((BasicNameValuePair)o1).getName().compareTo(((BasicNameValuePair)o2).getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append(url);
|
|
||||||
for (BasicNameValuePair param : params)
|
|
||||||
{
|
{
|
||||||
builder.append(",");
|
return ((BasicNameValuePair)o1).getName().compareTo(((BasicNameValuePair)o2).getName());
|
||||||
builder.append(param.getName());
|
|
||||||
builder.append("=");
|
|
||||||
builder.append(param.getValue());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(url);
|
||||||
|
for (BasicNameValuePair param : params)
|
||||||
|
{
|
||||||
builder.append(",");
|
builder.append(",");
|
||||||
builder.append(app.getPassword());
|
builder.append(param.getName());
|
||||||
|
builder.append("=");
|
||||||
String value = builder.toString();
|
builder.append(param.getValue());
|
||||||
|
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
|
||||||
|
|
||||||
md.update(value.getBytes("utf-8"));
|
|
||||||
|
|
||||||
byte[] digest = md.digest();
|
|
||||||
|
|
||||||
return new String(Base64Coder.encode(digest));
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
app.logError("Error computing signature", ex);
|
|
||||||
}
|
}
|
||||||
return "";
|
builder.append(",");
|
||||||
|
builder.append(app.getPassword());
|
||||||
|
|
||||||
|
String value = builder.toString();
|
||||||
|
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
|
md.update(value.getBytes("utf-8"));
|
||||||
|
|
||||||
|
byte[] digest = md.digest();
|
||||||
|
|
||||||
|
return new String(Base64Coder.encode(digest));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpResponse doInBackground(BasicNameValuePair... params) {
|
protected HttpResponse doInBackground(BasicNameValuePair... params) {
|
||||||
|
@ -13,18 +13,21 @@ public class IncomingMessageForwarder extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
app = App.getInstance(context.getApplicationContext());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.app = App.getInstance(context.getApplicationContext());
|
|
||||||
|
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
|
|
||||||
if (action.equals("android.provider.Telephony.SMS_RECEIVED")) {
|
if (action.equals("android.provider.Telephony.SMS_RECEIVED")) {
|
||||||
|
|
||||||
for (SmsMessage sms : getMessagesFromIntent(intent)) {
|
for (SmsMessage sms : getMessagesFromIntent(intent)) {
|
||||||
app.sendMessageToServer(sms);
|
app.sendMessageToServer(sms);
|
||||||
|
}
|
||||||
//DeleteSMSFromInbox(context, mesg);
|
|
||||||
|
if (!app.getKeepInInbox())
|
||||||
|
{
|
||||||
|
this.abortBroadcast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
@ -32,28 +35,6 @@ public class IncomingMessageForwarder extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
private void DeleteSMSFromInbox(Context context, SmsMessage mesg) {
|
|
||||||
Log.d("KALSMS", "try to delete SMS");
|
|
||||||
try {
|
|
||||||
Uri uriSms = Uri.parse("content://sms/inbox");
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("address='" + mesg.getOriginatingAddress() + "' AND ");
|
|
||||||
sb.append("body='" + mesg.getMessageBody() + "'");
|
|
||||||
Cursor c = context.getContentResolver().query(uriSms, null, sb.toString(), null, null);
|
|
||||||
c.moveToFirst();
|
|
||||||
int thread_id = c.getInt(1);
|
|
||||||
context.getContentResolver().delete(Uri.parse("content://sms/conversations/" + thread_id), null, null);
|
|
||||||
c.close();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
// deletions don't work most of the time since the timing of the
|
|
||||||
// receipt and saving to the inbox
|
|
||||||
// makes it difficult to match up perfectly. the SMS might not be in
|
|
||||||
// the inbox yet when this receiver triggers!
|
|
||||||
Log.d("SmsReceiver", "Error deleting sms from inbox: " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// from http://github.com/dimagi/rapidandroid
|
// from http://github.com/dimagi/rapidandroid
|
||||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||||
private SmsMessage[] getMessagesFromIntent(Intent intent) {
|
private SmsMessage[] getMessagesFromIntent(Intent intent) {
|
||||||
|
Loading…
Reference in New Issue
Block a user