mirror of
https://github.com/cwinfo/envayasms.git
synced 2024-12-04 12:35:32 +00:00
use POST in http requests; use different url for outgoing sms; poll for outgoing sms more frequently; notify server when sms messages are sent
This commit is contained in:
parent
448eafecd8
commit
9473ab1610
28
AndroidManifest.xml
Normal file → Executable file
28
AndroidManifest.xml
Normal file → Executable file
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="kalsms.niryariv.itp"
|
||||
package="org.envaya.kalsms"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
@ -19,18 +19,24 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".SMSReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".IncomingMessageForwarder">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".SMSSender">
|
||||
</receiver>
|
||||
<receiver android:name=".OutgoingMessagePoller">
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".Prefs"
|
||||
android:label="@string/app_name">
|
||||
</activity>
|
||||
<receiver android:name=".MessageStatusNotifier">
|
||||
<intent-filter>
|
||||
<action android:name="org.envaya.kalsms.SEND_STATUS" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".Prefs"
|
||||
android:label="@string/app_name">
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
17
build.properties
Executable file
17
build.properties
Executable file
@ -0,0 +1,17 @@
|
||||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked in Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
79
build.xml
Executable file
79
build.xml
Executable file
@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="KalSMS" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android'
|
||||
tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The build.properties file can be created by you and is never touched
|
||||
by the 'android' tool. This is the place to change some of the
|
||||
default property values used by the Ant rules.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="build.properties" />
|
||||
|
||||
<!-- The default.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<property file="default.properties" />
|
||||
|
||||
|
||||
<!-- Required pre-setup import -->
|
||||
<import file="${sdk.dir}/tools/ant/pre_setup.xml" />
|
||||
|
||||
|
||||
<!-- extension targets. Uncomment the ones where you want to do custom work
|
||||
in between standard targets -->
|
||||
<!--
|
||||
<target name="-pre-build">
|
||||
</target>
|
||||
<target name="-pre-compile">
|
||||
</target>
|
||||
|
||||
[This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir}]
|
||||
<target name="-post-compile">
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- Execute the Android Setup task that will setup some properties
|
||||
specific to the target, and import the build rules files.
|
||||
|
||||
The rules file is imported from
|
||||
<SDK>/tools/ant/
|
||||
Depending on the project type it can be either:
|
||||
- main_rules.xml
|
||||
- lib_rules.xml
|
||||
- test_rules.xml
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<setup> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole script.
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, *after* the <setup> task
|
||||
- disable the import of the rules by changing the setup task
|
||||
below to <setup import="false" />.
|
||||
- customize to your needs.
|
||||
-->
|
||||
<setup />
|
||||
|
||||
</project>
|
10
local.properties
Executable file
10
local.properties
Executable file
@ -0,0 +1,10 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must *NOT* be checked in Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
|
||||
# location of the SDK. This is only used by Ant
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
sdk.dir=C:\\android-sdk
|
40
proguard.cfg
Executable file
40
proguard.cfg
Executable file
@ -0,0 +1,40 @@
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
12
res/layout/main.xml
Normal file → Executable file
12
res/layout/main.xml
Normal file → Executable file
@ -3,11 +3,11 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:background="#333333">
|
||||
<TextView
|
||||
<TextView
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
android:textColor="#FFFFFF" android:textSize="30px" android:layout_margin="2px"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/info" android:textColor="#FFFFFF" android:layout_margin="5px"></TextView>
|
||||
<!--<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/settingsButton" android:text="Edit Settings" android:layout_marginRight="50px" android:layout_marginLeft="50px"></Button>-->
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/info"
|
||||
android:textColor="#FFFFFF"
|
||||
android:layout_margin="5px"></TextView>
|
||||
</LinearLayout>
|
||||
|
3
res/values/strings.xml
Normal file → Executable file
3
res/values/strings.xml
Normal file → Executable file
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="hello">SMS Gateway Running.\n</string>
|
||||
<string name="app_name">KalSMS</string>
|
||||
<string name="app_name">KalSMS Envaya</string>
|
||||
</resources>
|
||||
|
43
res/xml/prefs.xml
Normal file → Executable file
43
res/xml/prefs.xml
Normal file → Executable file
@ -1,26 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<EditTextPreference
|
||||
android:key="server_url"
|
||||
android:title="Server URL"
|
||||
android:defaultValue="http://192.168.70.1:3000/"
|
||||
></EditTextPreference>
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_target_url"
|
||||
android:title="Target URL"
|
||||
android:summary="URL to load when the SMS is received"
|
||||
android:defaultValue="http://qkhack.appspot.com/kalsms_demo"
|
||||
></EditTextPreference>
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_identifier"
|
||||
android:title="SMS Identifier"
|
||||
android:summary="Handle only SMS messages starting with this string (leave empty to handle all messages)"
|
||||
android:defaultValue="kal "
|
||||
></EditTextPreference>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="pref_poll_switch"
|
||||
android:title="Server Polling"
|
||||
android:disableDependentsState="false"
|
||||
android:summary="Poll target URL every 15 minutes (Note: increases power usage)"
|
||||
></CheckBoxPreference>
|
||||
|
||||
<EditTextPreference
|
||||
android:key="phone_number"
|
||||
android:title="Your Phone Number"
|
||||
android:defaultValue="16507993371"
|
||||
></EditTextPreference>
|
||||
|
||||
<EditTextPreference
|
||||
android:key="password"
|
||||
android:title="Password"
|
||||
android:password="true"
|
||||
></EditTextPreference>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="detailed_log"
|
||||
android:title="Detailed log messages?"
|
||||
android:disableDependentsState="false"
|
||||
></CheckBoxPreference>
|
||||
</PreferenceScreen>
|
@ -1,91 +0,0 @@
|
||||
package kalsms.niryariv.itp;
|
||||
|
||||
import kalsms.niryariv.itp.R;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class Main extends Activity {
|
||||
|
||||
// public static final String PREFS_NAME = "KalPrefsFile";
|
||||
|
||||
public String identifier = "";
|
||||
public String targetUrl = "";
|
||||
public Boolean polling = false;
|
||||
|
||||
public void onResume() {
|
||||
Log.d("KALSMS", "RESUME");
|
||||
super.onResume();
|
||||
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
this.identifier = settings.getString("pref_identifier", "");
|
||||
this.targetUrl = settings.getString("pref_target_url", "");
|
||||
this.polling = settings.getBoolean("pref_poll_switch", false);
|
||||
|
||||
Log.d("KALSMS", "onResume ident:" + this.identifier +"\ntarget:" + this.targetUrl);
|
||||
|
||||
String infoText = new String();
|
||||
|
||||
// Home Screen text
|
||||
infoText = "All SMS messages";
|
||||
|
||||
if (this.identifier.trim() != "") {
|
||||
infoText += " starting with <b>" + this.identifier + "</b>";
|
||||
}
|
||||
|
||||
infoText += " are now sent to <b>" + this.targetUrl +"</b> in the following format:";
|
||||
infoText += "<p><tt>GET " + this.targetUrl + "?sender=<phone#>&msg=<message></tt></p>";
|
||||
infoText += "If the response body contains text, it will SMS back to the originating phone.";
|
||||
|
||||
if (this.polling) {
|
||||
infoText += "<p>The target URL will be polled every 15 minutes (<i>note that polling increases power consumption</i>)</p>";
|
||||
}
|
||||
|
||||
infoText += "<br /><br /><b>Press Menu to set SMS identifier or target URL.</b>";
|
||||
|
||||
infoText += "<p>Questions/feedback: niryariv@gmail.com</p>";
|
||||
// END Home Screen text
|
||||
|
||||
TextView info = (TextView) this.findViewById(R.id.info);
|
||||
info.setText(Html.fromHtml(infoText));
|
||||
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
|
||||
|
||||
Log.d("KALSMS", "STARTED");
|
||||
}
|
||||
|
||||
|
||||
// first time the Menu key is pressed
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
|
||||
// any other time the Menu key is pressed
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop(){
|
||||
// dont do much with this, atm..
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package kalsms.niryariv.itp;
|
||||
|
||||
import kalsms.niryariv.itp.R;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
|
||||
|
||||
public class Prefs extends PreferenceActivity implements OnSharedPreferenceChangeListener {
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
}
|
||||
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Set up a listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
// Unregister the listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
Preference pref = findPreference(key);
|
||||
if (pref instanceof EditTextPreference) {
|
||||
EditTextPreference textPref = (EditTextPreference) pref;
|
||||
pref.setSummary(textPref.getSummary());
|
||||
Log.d("KALSMS", "textPref.getSummary(): " + textPref.getSummary());
|
||||
}
|
||||
if(pref instanceof CheckBoxPreference) {
|
||||
CheckBoxPreference checkbox = (CheckBoxPreference) pref;
|
||||
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
Intent pintent = new Intent(this, SMSSender.class);
|
||||
PendingIntent pIntent = PendingIntent.getBroadcast(this,0,pintent, 0);
|
||||
if(checkbox.isChecked()) {
|
||||
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);
|
||||
Log.d("KALSMS", "alarm manager turned on");
|
||||
} else {
|
||||
alarm.cancel(pIntent);
|
||||
Log.d("SMS_GATEWAY", "alarm manager turned off");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// first time the Menu key is pressed
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
|
||||
// any other time the Menu key is pressed
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +0,0 @@
|
||||
package kalsms.niryariv.itp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.util.Log;
|
||||
|
||||
public class SMSReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get settings
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
TargetUrlRequest url = new TargetUrlRequest();
|
||||
|
||||
String identifier = settings.getString("pref_identifier", "");
|
||||
String targetUrl = settings.getString("pref_target_url", "");
|
||||
|
||||
SmsMessage msgs[] = getMessagesFromIntent(intent);
|
||||
|
||||
for (int i = 0; i < msgs.length; i++) {
|
||||
SmsMessage mesg = msgs[i];
|
||||
String message = mesg.getDisplayMessageBody();
|
||||
String sender = mesg.getDisplayOriginatingAddress();
|
||||
|
||||
if (message != null && message.length() > 0
|
||||
&& (message.toLowerCase().startsWith(identifier) || identifier.trim() == "")) {
|
||||
Log.d("KALSMS", "MSG RCVD:\"" + message + "\" from: " + sender);
|
||||
|
||||
// send the message to the URL
|
||||
String resp = url.openURL(sender, message, targetUrl, false).toString();
|
||||
Log.d("KALSMS", "RESP:\"" + resp);
|
||||
|
||||
// SMS back the response
|
||||
if (resp.trim().length() > 0) {
|
||||
ArrayList<ArrayList<String>> items = url.parseXML(resp);
|
||||
url.sendMessages(items);
|
||||
}
|
||||
// delete SMS from inbox, to prevent it from filling up
|
||||
DeleteSMSFromInbox(context, mesg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||
private SmsMessage[] getMessagesFromIntent(Intent intent) {
|
||||
SmsMessage retMsgs[] = null;
|
||||
Bundle bdl = intent.getExtras();
|
||||
try {
|
||||
Object pdus[] = (Object[]) bdl.get("pdus");
|
||||
retMsgs = new SmsMessage[pdus.length];
|
||||
for (int n = 0; n < pdus.length; n++) {
|
||||
byte[] byteData = (byte[]) pdus[n];
|
||||
retMsgs[n] = SmsMessage.createFromPdu(byteData);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("KALSMS", "GetMessages ERROR\n" + e);
|
||||
}
|
||||
return retMsgs;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package kalsms.niryariv.itp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class SMSSender extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
// acquiring the wake clock to prevent device from sleeping while request is processed
|
||||
final PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||
PowerManager.WakeLock wake = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "http_request");
|
||||
wake.acquire();
|
||||
|
||||
// get settings
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String targetUrl = settings.getString("pref_target_url", "");
|
||||
Log.d("KALSMS", "url:\"" + targetUrl);
|
||||
TargetUrlRequest url = new TargetUrlRequest();
|
||||
// send the message to the URL
|
||||
String resp = url.openURL("","",targetUrl, true).toString();
|
||||
|
||||
Log.d("KALSMS", "RESP:\"" + resp);
|
||||
|
||||
// SMS back the response
|
||||
if (resp.trim().length() > 0) {
|
||||
ArrayList<ArrayList<String>> items = url.parseXML(resp);
|
||||
url.sendMessages(items);
|
||||
}
|
||||
wake.release();
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
package kalsms.niryariv.itp;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import android.telephony.SmsManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class TargetUrlRequest {
|
||||
|
||||
private String sender = "";
|
||||
|
||||
public String openURL(String sender, String message, String targetUrl, Boolean isPollRequest) {
|
||||
|
||||
this.sender = sender;
|
||||
|
||||
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
|
||||
|
||||
if(sender.trim().length() > 0 && message.trim().length() > 0) {
|
||||
qparams.add(new BasicNameValuePair("sender", sender));
|
||||
qparams.add(new BasicNameValuePair("msg", message));
|
||||
} else if (isPollRequest) {
|
||||
qparams.add(new BasicNameValuePair("poll", "true"));
|
||||
}
|
||||
|
||||
String url = targetUrl + "?" + URLEncodedUtils.format(qparams, "UTF-8");
|
||||
|
||||
try {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpGet get = new HttpGet(url);
|
||||
|
||||
HttpResponse responseGet = client.execute(get);
|
||||
HttpEntity resEntityGet = responseGet.getEntity();
|
||||
if (resEntityGet != null) {
|
||||
String resp = EntityUtils.toString(resEntityGet);
|
||||
Log.e("KALSMS", "HTTP RESP" + resp);
|
||||
return resp;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("KALSMS", "HTTP REQ FAILED:" + url);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public ArrayList<ArrayList<String>> parseXML(String xml) {
|
||||
ArrayList<ArrayList<String>> output = new ArrayList<ArrayList<String>>();
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
Document doc = dBuilder.parse(new InputSource(new StringReader(xml)));
|
||||
|
||||
NodeList rnodes = doc.getElementsByTagName("reply");
|
||||
|
||||
NodeList nodes = rnodes.item(0).getChildNodes();
|
||||
|
||||
for (int i=0; i < nodes.getLength(); i++) {
|
||||
try {
|
||||
List<String> item = new ArrayList<String>();
|
||||
|
||||
Node node = nodes.item(i);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) continue;
|
||||
|
||||
Element e = (Element) node;
|
||||
String nodeName = e.getNodeName();
|
||||
|
||||
if (nodeName.equalsIgnoreCase("sms")) {
|
||||
if (!e.getAttribute("phone").equals("")) {
|
||||
item.add(e.getAttribute("phone"));
|
||||
item.add(e.getFirstChild().getNodeValue());
|
||||
output.add((ArrayList<String>) item);
|
||||
}
|
||||
} else if (nodeName.equalsIgnoreCase("sms-to-sender")) {
|
||||
item.add("sender");
|
||||
item.add(e.getFirstChild().getNodeValue());
|
||||
output.add((ArrayList<String>) item);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e){
|
||||
Log.e("KALSMS", "FAILED PARSING XML NODE# " + i );
|
||||
}
|
||||
}
|
||||
Log.e("KALSMS", "PARSING XML RETURNS " + output );
|
||||
return (output);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("KALSMS", "PARSING XML FAILED: " + xml );
|
||||
e.printStackTrace();
|
||||
return (output);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessages(ArrayList<ArrayList<String>> items) {
|
||||
SmsManager smgr = SmsManager.getDefault();
|
||||
for (int j = 0; j < items.size(); j++) {
|
||||
String sendTo = items.get(j).get(0);
|
||||
if (sendTo.toLowerCase() == "sender") sendTo = this.sender;
|
||||
String sendMsg = items.get(j).get(1);
|
||||
try {
|
||||
Log.d("KALSMS", "SEND MSG:\"" + sendMsg + "\" TO: " + sendTo);
|
||||
smgr.sendTextMessage(sendTo, null, sendMsg, null, null);
|
||||
} catch (Exception ex) {
|
||||
Log.d("KALSMS", "SMS FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
158
src/org/envaya/kalsms/App.java
Executable file
158
src/org/envaya/kalsms/App.java
Executable file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jesse
|
||||
*/
|
||||
public class App {
|
||||
|
||||
public static final int OUTGOING_POLL_SECONDS = 30;
|
||||
|
||||
public static final String LOG_NAME = "KALSMS";
|
||||
public static final String LOG_INTENT = "org.envaya.kalsms.LOG";
|
||||
public static final String SEND_STATUS_INTENT = "org.envaya.kalsms.SEND_STATUS";
|
||||
|
||||
public Context context;
|
||||
public SharedPreferences settings;
|
||||
|
||||
public App(Context context)
|
||||
{
|
||||
this.context = context;
|
||||
this.settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
static void debug(String msg)
|
||||
{
|
||||
Log.d(LOG_NAME, msg);
|
||||
}
|
||||
|
||||
public void log(String msg)
|
||||
{
|
||||
Log.d(LOG_NAME, msg);
|
||||
|
||||
Intent broadcast = new Intent(App.LOG_INTENT);
|
||||
broadcast.putExtra("message", msg);
|
||||
context.sendBroadcast(broadcast);
|
||||
}
|
||||
|
||||
public void logError(Throwable ex)
|
||||
{
|
||||
logError("ERROR", ex);
|
||||
}
|
||||
|
||||
public void logError(String msg, Throwable ex)
|
||||
{
|
||||
logError(msg, ex, false);
|
||||
}
|
||||
|
||||
public void logError(String msg, Throwable ex, boolean detail)
|
||||
{
|
||||
log(msg + ": " + ex.getClass().getName() + ": " + ex.getMessage());
|
||||
|
||||
if (detail)
|
||||
{
|
||||
for (StackTraceElement elem : ex.getStackTrace())
|
||||
{
|
||||
log(elem.getClassName() + ":" + elem.getMethodName() + ":" + elem.getLineNumber());
|
||||
}
|
||||
Throwable innerEx = ex.getCause();
|
||||
if (innerEx != null)
|
||||
{
|
||||
logError("Inner exception:", innerEx, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getIncomingUrl()
|
||||
{
|
||||
return getServerUrl() + "/pg/receive_sms";
|
||||
}
|
||||
|
||||
public String getOutgoingUrl()
|
||||
{
|
||||
return getServerUrl() + "/pg/dequeue_sms";
|
||||
}
|
||||
|
||||
public String getSendStatusUrl()
|
||||
{
|
||||
return getServerUrl() + "/pg/sms_sent";
|
||||
}
|
||||
|
||||
public String getServerUrl()
|
||||
{
|
||||
return settings.getString("server_url", "");
|
||||
}
|
||||
|
||||
public String getPhoneNumber()
|
||||
{
|
||||
return settings.getString("phone_number", "");
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return settings.getString("password", "");
|
||||
}
|
||||
|
||||
private SQLiteDatabase db;
|
||||
public SQLiteDatabase getWritableDatabase()
|
||||
{
|
||||
if (db == null)
|
||||
{
|
||||
db = new DBHelper(context).getWritableDatabase();
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
public void sendSMS(OutgoingSmsMessage sms)
|
||||
{
|
||||
String serverId = sms.getServerId();
|
||||
|
||||
if (serverId != null)
|
||||
{
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
Cursor cursor =
|
||||
db.rawQuery("select 1 from sent_sms where server_id=?", new String[] { serverId });
|
||||
|
||||
boolean exists = (cursor.getCount() > 0);
|
||||
cursor.close();
|
||||
if (exists)
|
||||
{
|
||||
log(sms.getLogName() + " already sent, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("server_id", serverId);
|
||||
db.insert("sent_sms", null, values);
|
||||
}
|
||||
|
||||
SmsManager smgr = SmsManager.getDefault();
|
||||
|
||||
Intent intent = new Intent(App.SEND_STATUS_INTENT);
|
||||
intent.putExtra("serverId", serverId);
|
||||
|
||||
PendingIntent sentIntent = PendingIntent.getBroadcast(
|
||||
this.context,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_ONE_SHOT);
|
||||
|
||||
log("Sending " +sms.getLogName() + " to " + sms.getTo());
|
||||
smgr.sendTextMessage(sms.getTo(), null, sms.getMessage(), sentIntent, null);
|
||||
}
|
||||
}
|
37
src/org/envaya/kalsms/DBHelper.java
Executable file
37
src/org/envaya/kalsms/DBHelper.java
Executable file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jesse
|
||||
*/
|
||||
public class DBHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
private static final String DATABASE_NAME = "org.envaya.kalsms.db";
|
||||
|
||||
private static final String SENT_SMS_TABLE_CREATE =
|
||||
"CREATE TABLE sent_sms (server_id text);"
|
||||
+ "CREATE INDEX server_id_index ON sent_sms (server_id);";
|
||||
|
||||
public DBHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(SENT_SMS_TABLE_CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
|
||||
}
|
||||
}
|
161
src/org/envaya/kalsms/IncomingMessageForwarder.java
Executable file
161
src/org/envaya/kalsms/IncomingMessageForwarder.java
Executable file
@ -0,0 +1,161 @@
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import java.util.ArrayList;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
public class IncomingMessageForwarder extends BroadcastReceiver {
|
||||
|
||||
private App app;
|
||||
|
||||
public List<OutgoingSmsMessage> sendMessageToServer(SmsMessage sms) {
|
||||
|
||||
String message = sms.getDisplayMessageBody();
|
||||
String sender = sms.getDisplayOriginatingAddress();
|
||||
String recipient = app.getPhoneNumber();
|
||||
|
||||
app.log("Received SMS from " + sender);
|
||||
|
||||
if (message == null || message.length() == 0) {
|
||||
return new ArrayList<OutgoingSmsMessage>();
|
||||
}
|
||||
|
||||
List<OutgoingSmsMessage> replies = new ArrayList<OutgoingSmsMessage>();
|
||||
|
||||
try {
|
||||
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("from", sender));
|
||||
params.add(new BasicNameValuePair("to", recipient));
|
||||
params.add(new BasicNameValuePair("message", message));
|
||||
params.add(new BasicNameValuePair("secret", app.getPassword()));
|
||||
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(app.getIncomingUrl());
|
||||
post.setEntity(new UrlEncodedFormEntity(params));
|
||||
|
||||
app.log("Forwarding incoming SMS to server");
|
||||
|
||||
HttpResponse response = client.execute(post);
|
||||
|
||||
InputStream responseStream = response.getEntity().getContent();
|
||||
DocumentBuilder xmlBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document xml = xmlBuilder.parse(responseStream);
|
||||
|
||||
NodeList smsNodes = xml.getElementsByTagName("Sms");
|
||||
for (int i = 0; i < smsNodes.getLength(); i++) {
|
||||
Element smsElement = (Element) smsNodes.item(i);
|
||||
|
||||
OutgoingSmsMessage reply = new OutgoingSmsMessage();
|
||||
|
||||
reply.setFrom(recipient);
|
||||
reply.setTo(sender);
|
||||
reply.setMessage(smsElement.getFirstChild().getNodeValue());
|
||||
|
||||
replies.add(reply);
|
||||
}
|
||||
} catch (SAXException ex) {
|
||||
app.logError("Error parsing response from server while forwarding incoming message", ex);
|
||||
} catch (IOException ex) {
|
||||
app.logError("Error forwarding incoming message to server", ex);
|
||||
} catch (ParserConfigurationException ex) {
|
||||
app.logError("Error configuring XML parser", ex);
|
||||
}
|
||||
|
||||
return replies;
|
||||
}
|
||||
|
||||
public void smsReceived(Intent intent) {
|
||||
|
||||
for (SmsMessage sms : getMessagesFromIntent(intent)) {
|
||||
List<OutgoingSmsMessage> replies = sendMessageToServer(sms);
|
||||
|
||||
for (OutgoingSmsMessage reply : replies)
|
||||
{
|
||||
app.sendSMS(reply);
|
||||
}
|
||||
|
||||
//DeleteSMSFromInbox(context, mesg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
try {
|
||||
this.app = new App(context);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
if (action.equals("android.provider.Telephony.SMS_RECEIVED")) {
|
||||
smsReceived(intent);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
app.logError("Unexpected error in IncomingMessageForwarder", ex, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
// source: http://www.devx.com/wireless/Article/39495/1954
|
||||
|
||||
private SmsMessage[] getMessagesFromIntent(Intent intent) {
|
||||
SmsMessage retMsgs[] = null;
|
||||
Bundle bdl = intent.getExtras();
|
||||
Object pdus[] = (Object[]) bdl.get("pdus");
|
||||
retMsgs = new SmsMessage[pdus.length];
|
||||
for (int n = 0; n < pdus.length; n++) {
|
||||
byte[] byteData = (byte[]) pdus[n];
|
||||
retMsgs[n] = SmsMessage.createFromPdu(byteData);
|
||||
}
|
||||
return retMsgs;
|
||||
}
|
||||
}
|
102
src/org/envaya/kalsms/Main.java
Executable file
102
src/org/envaya/kalsms/Main.java
Executable file
@ -0,0 +1,102 @@
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Html;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.view.Menu;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class Main extends Activity {
|
||||
|
||||
private BroadcastReceiver logReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
showLogMessage(intent.getExtras().getString("message"));
|
||||
}
|
||||
};
|
||||
|
||||
public void showLogMessage(String message)
|
||||
{
|
||||
TextView info = (TextView) Main.this.findViewById(R.id.info);
|
||||
if (message != null)
|
||||
{
|
||||
info.append(message + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
App.debug("RESUME");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
App.debug("STARTED");
|
||||
|
||||
setContentView(R.layout.main);
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
|
||||
|
||||
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
|
||||
0,
|
||||
new Intent(this, OutgoingMessagePoller.class),
|
||||
0);
|
||||
|
||||
alarm.setRepeating(
|
||||
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime(),
|
||||
App.OUTGOING_POLL_SECONDS * 1000,
|
||||
pendingIntent);
|
||||
|
||||
App app = new App(this.getApplication());
|
||||
|
||||
TextView info = (TextView) this.findViewById(R.id.info);
|
||||
|
||||
info.setText(Html.fromHtml("<b>SMS Gateway running.</b><br />"));
|
||||
|
||||
showLogMessage("Server URL is: " + app.getServerUrl());
|
||||
showLogMessage("Your phone number is: " + app.getPhoneNumber());
|
||||
showLogMessage("Checking for outgoing messages every " + App.OUTGOING_POLL_SECONDS + " sec");
|
||||
|
||||
info.append(Html.fromHtml("<b>Press Menu to edit settings.</b><br />"));
|
||||
|
||||
info.setMovementMethod(new ScrollingMovementMethod());
|
||||
|
||||
IntentFilter logReceiverFilter = new IntentFilter();
|
||||
|
||||
logReceiverFilter.addAction(App.LOG_INTENT);
|
||||
registerReceiver(logReceiver, logReceiverFilter);
|
||||
}
|
||||
|
||||
// first time the Menu key is pressed
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
|
||||
// any other time the Menu key is pressed
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop(){
|
||||
// dont do much with this, atm..
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
}
|
82
src/org/envaya/kalsms/MessageStatusNotifier.java
Executable file
82
src/org/envaya/kalsms/MessageStatusNotifier.java
Executable file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.telephony.SmsManager;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
public class MessageStatusNotifier extends BroadcastReceiver {
|
||||
|
||||
private App app;
|
||||
|
||||
public void notifySuccess(String serverId)
|
||||
{
|
||||
if (serverId != null)
|
||||
{
|
||||
try {
|
||||
app.log("Notifying server of sent SMS id=" + serverId);
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("from", app.getPhoneNumber()));
|
||||
params.add(new BasicNameValuePair("secret", app.getPassword()));
|
||||
params.add(new BasicNameValuePair("id", serverId));
|
||||
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(app.getSendStatusUrl());
|
||||
post.setEntity(new UrlEncodedFormEntity(params));
|
||||
|
||||
client.execute(post);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
app.logError("Error while notifying server of outgoing message", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
app = new App(context);
|
||||
|
||||
String serverId = intent.getExtras().getString("serverId");
|
||||
|
||||
String desc = serverId == null ? "SMS reply" : ("SMS id=" + serverId);
|
||||
|
||||
switch (getResultCode()) {
|
||||
case Activity.RESULT_OK:
|
||||
app.log(desc + " sent successfully");
|
||||
this.notifySuccess(serverId);
|
||||
break;
|
||||
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
|
||||
app.log(desc + " could not be sent (generic failure)");
|
||||
break;
|
||||
case SmsManager.RESULT_ERROR_RADIO_OFF:
|
||||
app.log(desc + " could not be sent (radio off)");
|
||||
break;
|
||||
case SmsManager.RESULT_ERROR_NO_SERVICE:
|
||||
app.log(desc + " could not be sent (no service)");
|
||||
break;
|
||||
case SmsManager.RESULT_ERROR_NULL_PDU:
|
||||
app.log(desc + " could not be sent (null PDU");
|
||||
break;
|
||||
default:
|
||||
app.log("SMS could not be sent (unknown error)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
89
src/org/envaya/kalsms/OutgoingMessagePoller.java
Executable file
89
src/org/envaya/kalsms/OutgoingMessagePoller.java
Executable file
@ -0,0 +1,89 @@
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class OutgoingMessagePoller extends BroadcastReceiver {
|
||||
|
||||
private App app;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
try
|
||||
{
|
||||
app = new App(context);
|
||||
|
||||
app.log("Checking for outgoing messages");
|
||||
|
||||
for (OutgoingSmsMessage sms : getOutgoingMessages())
|
||||
{
|
||||
app.sendSMS(sms);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
app.logError("Unexpected error in OutgoingMessagePoller", ex, true);
|
||||
}
|
||||
}
|
||||
|
||||
public List<OutgoingSmsMessage> getOutgoingMessages() {
|
||||
List<OutgoingSmsMessage> messages = new ArrayList<OutgoingSmsMessage>();
|
||||
|
||||
try {
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("from", app.getPhoneNumber()));
|
||||
params.add(new BasicNameValuePair("secret", app.getPassword()));
|
||||
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(app.getOutgoingUrl());
|
||||
post.setEntity(new UrlEncodedFormEntity(params));
|
||||
|
||||
HttpResponse response = client.execute(post);
|
||||
|
||||
InputStream responseStream = response.getEntity().getContent();
|
||||
DocumentBuilder xmlBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document xml = xmlBuilder.parse(responseStream);
|
||||
|
||||
NodeList smsNodes = xml.getElementsByTagName("Sms");
|
||||
for (int i = 0; i < smsNodes.getLength(); i++) {
|
||||
Element smsElement = (Element) smsNodes.item(i);
|
||||
OutgoingSmsMessage sms = new OutgoingSmsMessage();
|
||||
|
||||
sms.setFrom(app.getPhoneNumber());
|
||||
sms.setTo(smsElement.getAttribute("to"));
|
||||
sms.setMessage(smsElement.getFirstChild().getNodeValue());
|
||||
sms.setServerId(smsElement.getAttribute("id"));
|
||||
|
||||
messages.add(sms);
|
||||
}
|
||||
} catch (SAXException ex) {
|
||||
app.logError("Error parsing response from server while retreiving outgoing messages", ex);
|
||||
} catch (IOException ex) {
|
||||
app.logError("Error retreiving outgoing messages from server", ex);
|
||||
} catch (ParserConfigurationException ex) {
|
||||
app.logError("Error configuring XML parser", ex);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
}
|
60
src/org/envaya/kalsms/OutgoingSmsMessage.java
Executable file
60
src/org/envaya/kalsms/OutgoingSmsMessage.java
Executable file
@ -0,0 +1,60 @@
|
||||
|
||||
package org.envaya.kalsms;
|
||||
|
||||
public class OutgoingSmsMessage {
|
||||
|
||||
private String serverId;
|
||||
private String message;
|
||||
private String from;
|
||||
private String to;
|
||||
|
||||
public OutgoingSmsMessage()
|
||||
{
|
||||
}
|
||||
|
||||
public String getLogName()
|
||||
{
|
||||
return (serverId == null) ? "SMS reply" : ("SMS id=" + serverId);
|
||||
}
|
||||
|
||||
public String getServerId()
|
||||
{
|
||||
return serverId;
|
||||
}
|
||||
|
||||
public void setServerId(String id)
|
||||
{
|
||||
this.serverId = id;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getFrom()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from)
|
||||
{
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public String getTo()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setTo(String to)
|
||||
{
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
}
|
71
src/org/envaya/kalsms/Prefs.java
Executable file
71
src/org/envaya/kalsms/Prefs.java
Executable file
@ -0,0 +1,71 @@
|
||||
package org.envaya.kalsms;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.view.Menu;
|
||||
|
||||
public class Prefs extends PreferenceActivity implements OnSharedPreferenceChangeListener {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Set up a listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
// Unregister the listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
/*
|
||||
Preference pref = findPreference(key);
|
||||
if (pref instanceof EditTextPreference) {
|
||||
EditTextPreference textPref = (EditTextPreference) pref;
|
||||
pref.setSummary(textPref.getSummary());
|
||||
Log.d("KALSMS", "textPref.getSummary(): " + textPref.getSummary());
|
||||
}
|
||||
if(pref instanceof CheckBoxPreference) {
|
||||
CheckBoxPreference checkbox = (CheckBoxPreference) pref;
|
||||
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
Intent pintent = new Intent(this, SMSSender.class);
|
||||
PendingIntent pIntent = PendingIntent.getBroadcast(this,0,pintent, 0);
|
||||
if(checkbox.isChecked()) {
|
||||
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime(),
|
||||
AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);
|
||||
Log.d("KALSMS", "alarm manager turned on");
|
||||
} else {
|
||||
alarm.cancel(pIntent);
|
||||
Log.d("SMS_GATEWAY", "alarm manager turned off");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// first time the Menu key is pressed
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return (true);
|
||||
}
|
||||
|
||||
// any other time the Menu key is pressed
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
startActivity(new Intent(this, Prefs.class));
|
||||
return (true);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user