From aee1061c5a89732eca1cfecfd72f3b5eb3cd048b Mon Sep 17 00:00:00 2001 From: Nir Yariv Date: Sat, 15 Jan 2011 14:42:26 -0500 Subject: [PATCH] initial import of polling code --- AndroidManifest.xml | 10 +- README.txt | 2 +- res/xml/prefs.xml | 6 +- src/kalsms/niryariv/itp/Main.java | 2 - src/kalsms/niryariv/itp/Prefs.java | 55 +++++++- src/kalsms/niryariv/itp/SMSReceiver.java | 124 +----------------- src/kalsms/niryariv/itp/SMSSender.java | 53 ++++++++ src/kalsms/niryariv/itp/TargetUrlRequest.java | 105 +++++++++++++++ src/kalsms/niryariv/itp/URLopen.java | 74 ----------- 9 files changed, 226 insertions(+), 205 deletions(-) mode change 100644 => 100755 src/kalsms/niryariv/itp/Prefs.java create mode 100755 src/kalsms/niryariv/itp/SMSSender.java create mode 100644 src/kalsms/niryariv/itp/TargetUrlRequest.java delete mode 100644 src/kalsms/niryariv/itp/URLopen.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0af7a82..7841597 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4,10 +4,11 @@ android:versionCode="1" android:versionName="1.0"> - + + @@ -17,12 +18,15 @@ - - + + + + + diff --git a/README.txt b/README.txt index 3c2335b..e07f1cb 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -(Polling branch) +(Polling branch - this adds periodic URL polling functionality) KalSMS is an simple Android SMS gateway application. diff --git a/res/xml/prefs.xml b/res/xml/prefs.xml index 2692eac..449faf9 100644 --- a/res/xml/prefs.xml +++ b/res/xml/prefs.xml @@ -2,6 +2,8 @@ - - + + + + \ No newline at end of file diff --git a/src/kalsms/niryariv/itp/Main.java b/src/kalsms/niryariv/itp/Main.java index 3f5328f..1c9f5d3 100644 --- a/src/kalsms/niryariv/itp/Main.java +++ b/src/kalsms/niryariv/itp/Main.java @@ -4,8 +4,6 @@ import kalsms.niryariv.itp.R; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; -import android.preference.PreferenceActivity; -import android.preference.Preference; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.Html; diff --git a/src/kalsms/niryariv/itp/Prefs.java b/src/kalsms/niryariv/itp/Prefs.java old mode 100644 new mode 100755 index 10b3fa1..ab02076 --- a/src/kalsms/niryariv/itp/Prefs.java +++ b/src/kalsms/niryariv/itp/Prefs.java @@ -1,31 +1,80 @@ 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.preference.PreferenceManager; import android.util.Log; +import android.view.Menu; -public class Prefs extends PreferenceActivity { +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()) { + long interval = 60*Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(this).getString("pref_poll_interval", "5000"));//5mins;//5mins + long firstPoll = SystemClock.elapsedRealtime() + 60*Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(this).getString("pref_poll_interval", "5000")); + alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstPoll, interval, pIntent); + Log.d("KALSMS", "alarm manager turned on "+interval); + }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); } } diff --git a/src/kalsms/niryariv/itp/SMSReceiver.java b/src/kalsms/niryariv/itp/SMSReceiver.java index 207774c..5394982 100644 --- a/src/kalsms/niryariv/itp/SMSReceiver.java +++ b/src/kalsms/niryariv/itp/SMSReceiver.java @@ -1,15 +1,6 @@ package kalsms.niryariv.itp; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -22,27 +13,7 @@ import android.telephony.SmsManager; import android.telephony.SmsMessage; import android.util.Log; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.NameValuePair; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -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; - public class SMSReceiver extends BroadcastReceiver { - @Override // source: http://www.devx.com/wireless/Article/39495/1954 @@ -53,6 +24,7 @@ public class SMSReceiver extends BroadcastReceiver { // get settings SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + TargetUrlRequest url = new TargetUrlRequest(); String identifier = settings.getString("pref_identifier", ""); String targetUrl = settings.getString("pref_target_url", ""); @@ -66,25 +38,21 @@ public class SMSReceiver extends BroadcastReceiver { 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 = openURL(sender, message, targetUrl).toString(); - + String resp = url.openURL(sender, message, targetUrl).toString(); Log.d("KALSMS", "RESP:\"" + resp); // SMS back the response if (resp.trim().length() > 0) { - ArrayList> items = parseXML(resp); + ArrayList> items = url.parseXML(resp); SmsManager smgr = SmsManager.getDefault(); - for (int j = 0; j < items.size(); j++) { String sendTo = items.get(j).get(0); if (sendTo.toLowerCase() == "sender") sendTo = sender; String sendMsg = items.get(j).get(1); - try { Log.d("KALSMS", "SEND MSG:\"" + sendMsg + "\" TO: " + sendTo); smgr.sendTextMessage(sendTo, null, sendMsg, null, null); @@ -93,21 +61,16 @@ public class SMSReceiver extends BroadcastReceiver { } } } - // 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() + "'"); @@ -138,88 +101,9 @@ public class SMSReceiver extends BroadcastReceiver { byte[] byteData = (byte[]) pdus[n]; retMsgs[n] = SmsMessage.createFromPdu(byteData); } - } catch (Exception e) { Log.e("KALSMS", "GetMessages ERROR\n" + e); } return retMsgs; } - - - public String openURL(String sender, String message, String targetUrl) { - - List qparams = new ArrayList(); - qparams.add(new BasicNameValuePair("sender", sender)); - qparams.add(new BasicNameValuePair("msg", message)); - 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 static ArrayList> parseXML(String xml) { - ArrayList> output = new ArrayList>(); - - 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 item = new ArrayList(); - - 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) item); - } - } else if (nodeName.equalsIgnoreCase("sms-to-sender")) { - item.add("sender"); - item.add(e.getFirstChild().getNodeValue()); - output.add((ArrayList) 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); - } - } -} +} \ No newline at end of file diff --git a/src/kalsms/niryariv/itp/SMSSender.java b/src/kalsms/niryariv/itp/SMSSender.java new file mode 100755 index 0000000..004c629 --- /dev/null +++ b/src/kalsms/niryariv/itp/SMSSender.java @@ -0,0 +1,53 @@ +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.telephony.SmsManager; +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).toString(); + + Log.d("KALSMS", "RESP:\"" + resp); + + // SMS back the response + if (resp.trim().length() > 0) { + ArrayList> items = url.parseXML(resp); + + SmsManager smgr = SmsManager.getDefault(); + + for (int j = 0; j < items.size(); j++) { + String sendTo = items.get(j).get(0); + 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"); + } + } + } + wake.release(); + } +} diff --git a/src/kalsms/niryariv/itp/TargetUrlRequest.java b/src/kalsms/niryariv/itp/TargetUrlRequest.java new file mode 100644 index 0000000..ede5d55 --- /dev/null +++ b/src/kalsms/niryariv/itp/TargetUrlRequest.java @@ -0,0 +1,105 @@ +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.util.Log; + +public class TargetUrlRequest { + + public String openURL(String sender, String message, String targetUrl) { + + String url = targetUrl; + if(sender.trim().length() > 0 && message.trim().length() > 0) { + List qparams = new ArrayList(); + qparams.add(new BasicNameValuePair("sender", sender)); + qparams.add(new BasicNameValuePair("msg", message)); + 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> parseXML(String xml) { + ArrayList> output = new ArrayList>(); + + 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 item = new ArrayList(); + + 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) item); + } + } else if (nodeName.equalsIgnoreCase("sms-to-sender")) { + item.add("sender"); + item.add(e.getFirstChild().getNodeValue()); + output.add((ArrayList) 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); + } + } +} diff --git a/src/kalsms/niryariv/itp/URLopen.java b/src/kalsms/niryariv/itp/URLopen.java deleted file mode 100644 index 4aa8c1f..0000000 --- a/src/kalsms/niryariv/itp/URLopen.java +++ /dev/null @@ -1,74 +0,0 @@ -package kalsms.niryariv.itp; -//package txtgate.niryariv.itp; -// -//import java.io.BufferedInputStream; -//import java.io.InputStream; -//import java.net.URL; -//import java.net.URLConnection; -// -//import org.apache.http.util.ByteArrayBuffer; -// -//public class URLopen { -// private Thread checkUpdate = new Thread() { -// public void run() { -// try { -// URL updateURL = new URL("http://iconic.4feets.com/update"); -// URLConnection conn = updateURL.openConnection(); -// InputStream is = conn.getInputStream(); -// BufferedInputStream bis = new BufferedInputStream(is); -// ByteArrayBuffer baf = new ByteArrayBuffer(50); -// -// int current = 0; -// while((current = bis.read()) != -1){ -// baf.append((byte)current); -// } -// -// /* Convert the Bytes read to a String. */ -// final String s = new String(baf.toByteArray()); -//// mHandler.post(showUpdate); -// } catch (Exception e) { -// // -// } -// } -// }; -//} -// -////public class Iconic extends Activity { -//// private String html = ""; -//// private Handler mHandler; -//// -//// public void onCreate(Bundle savedInstanceState) { -//// super.onCreate(savedInstanceState); -//// setContentView(R.layout.main); -//// mHandler = new Handler(); -//// checkUpdate.start(); -//// } -//// -//// private Thread checkUpdate = new Thread() { -//// public void run() { -//// try { -//// URL updateURL = new URL("http://iconic.4feets.com/update"); -//// URLConnection conn = updateURL.openConnection(); -//// InputStream is = conn.getInputStream(); -//// BufferedInputStream bis = new BufferedInputStream(is); -//// ByteArrayBuffer baf = new ByteArrayBuffer(50); -//// -//// int current = 0; -//// while((current = bis.read()) != -1){ -//// baf.append((byte)current); -//// } -//// -//// /* Convert the Bytes read to a String. */ -//// html = new String(baf.toByteArray()); -//// mHandler.post(showUpdate); -//// } catch (Exception e) { -//// } -//// } -//// }; -//// -//// private Runnable showUpdate = new Runnable(){ -//// public void run(){ -//// Toast.makeText(Iconic.this, "HTML Code: " + html, Toast.LENGTH_SHORT).show(); -//// } -//// }; -////} \ No newline at end of file