Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

can receive command from sms now

  • Loading branch information...
commit 1d7c901a0fcd92cca7242ed2776ff2d4c214ded5 1 parent e47219d
@ghk authored
View
7 AndroidManifest.xml
@@ -2,9 +2,11 @@
<manifest android:versionCode="1" android:versionName="1.0"
package="id.co.microvac.simamonit" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<supports-screens android:anyDensity="true"
android:largeScreens="true" android:normalScreens="true"
android:resizeable="true" android:smallScreens="true"/>
+<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<application android:icon="@drawable/sima"
android:label="@string/app_name" android:name="SimaMonit" android:theme="@android:style/Theme.Light">
<activity android:label="@string/app_name" android:name=".NodeListActivity" android:configChanges="orientation|keyboard|keyboardHidden">
@@ -16,5 +18,10 @@
<activity android:name=".NodeActivity" android:configChanges="orientation|keyboard|keyboardHidden"/>
<activity android:name=".ProcessActivity" android:configChanges="orientation|keyboard|keyboardHidden"/>
<activity android:name=".HostedCommandActivity" android:configChanges="orientation|keyboard|keyboardHidden"/>
+ <receiver android:name=".SmsListener" android:enabled="true">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.SMS_RECEIVED" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
View
96 src/id/co/microvac/simamonit/HostedCommandActivity.java
@@ -1,5 +1,6 @@
package id.co.microvac.simamonit;
+import id.co.microvac.simamonit.util.CommandRunner;
import id.co.microvac.simamonit.util.UiUtil;
import java.io.BufferedReader;
@@ -17,18 +18,20 @@
public class HostedCommandActivity extends Activity {
- private static final int OUTPUT_RECEIVED = 1000;
-
+ private CommandRunner commandRunner;
private String command;
- private Process process;
- private ProcessWaitingThread waitingThread;
private Handler handler = new Handler(){
public void dispatchMessage(Message msg) {
switch(msg.what){
- case OUTPUT_RECEIVED:
+ case CommandRunner.OUTPUT_RECEIVED:
String line = (String) msg.obj;
((TextView)findViewById(R.id.output)).append(line+"\n");
+ break;
+ case CommandRunner.PROCESS_EXIT:
+ int exitValue = (Integer) msg.obj;
+ ((Button)findViewById(R.id.status)).setText("Finished ("+exitValue+")");
+ break;
}
};
};
@@ -43,8 +46,8 @@ protected void onCreate(Bundle savedInstanceState) {
((Button)findViewById(R.id.status)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if(waitingThread != null && !waitingThread.isProcessFinished())
- process.destroy();
+ if(commandRunner != null && !commandRunner.isProcessFinished())
+ commandRunner.kill();
}
});
runCommand();
@@ -56,9 +59,9 @@ public void onClick(View v) {
@Override
protected void onDestroy() {
- if(process != null){
+ if(commandRunner != null){
try{
- process.destroy();
+ commandRunner.kill();
}
catch(Exception e){
}
@@ -67,79 +70,8 @@ protected void onDestroy() {
}
private void runCommand(){
- try{
- process = Runtime.getRuntime().exec(command);
- waitingThread = new ProcessWaitingThread(process);
- waitingThread.start();
- new OutputReadingThread(process.getInputStream()).start();
- new OutputReadingThread(process.getErrorStream()).start();
- }
- catch(Exception e){
- UiUtil.showException(e, this);
- }
- }
-
- private class OutputReadingThread extends Thread{
- private InputStream input;
-
- public OutputReadingThread(InputStream input) {
- this.input = input;
- }
-
- public void run() {
- BufferedReader reader = new BufferedReader(new InputStreamReader(input));
- try {
- String line = null;
- while ((line = reader.readLine()) != null) {
- handler.sendMessage(Message.obtain(handler, OUTPUT_RECEIVED, line));
- }
- } catch (IOException ioe) {
- } finally {
- try {
- reader.close();
- input.close();
- } catch (Exception e) {
- }
- }
- }
+ commandRunner = new CommandRunner(handler, this, command);
+ commandRunner.run(0);
}
- private class ProcessWaitingThread extends Thread{
-
- private Process process;
- private boolean processFinished = false;
- private int exitValue = 0;
-
- public ProcessWaitingThread(Process process) {
- this.process = process;
- }
-
- public void run() {
- while(!processFinished)
- {
- try{
- exitValue = process.exitValue();
- processFinished = true;
- }
- catch(Exception e){
- try{
- exitValue = process.waitFor();
- processFinished = true;
- }
- catch(InterruptedException ie){
- }
- }
- }
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ((Button)findViewById(R.id.status)).setText("Finished ("+exitValue+")");
- }
- });
- }
-
- public boolean isProcessFinished() {
- return processFinished;
- }
- }
}
View
115 src/id/co/microvac/simamonit/SmsListener.java
@@ -0,0 +1,115 @@
+package id.co.microvac.simamonit;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import id.co.microvac.simamonit.entity.Node;
+import id.co.microvac.simamonit.util.CommandBuilder;
+import id.co.microvac.simamonit.util.CommandRunner;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.widget.Toast;
+
+public class SmsListener extends BroadcastReceiver {
+
+ private static final String LOG_TAG = "SMSApp";
+ private static final String PREFIX = "#sima ";
+ private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
+ private static final long COMMAND_TIMEOUT = 30000;
+ private static final int MAX_REPLY_LENGTH = 300;
+
+
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTION)) {
+ Bundle bundle = intent.getExtras();
+ Object messages[] = (Object[]) bundle.get("pdus");
+ for (int n = 0; n < messages.length; n++) {
+ processMessage(context, SmsMessage.createFromPdu((byte[]) messages[n]));
+ }
+ }
+ }
+
+ private void processMessage(final Context context, final SmsMessage message){
+ String command = getCommand(message);
+ if(command != null){
+ Toast.makeText(context,
+ "Will run command: " + command, Toast.LENGTH_LONG).show();
+ final StringBuilder sb = new StringBuilder();
+ Handler handler = new Handler(){
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what){
+ case CommandRunner.OUTPUT_RECEIVED:
+ String line = (String) msg.obj;
+ sb.append(line+"\n");
+ break;
+ case CommandRunner.PROCESS_EXIT:
+ int exitValue = (Integer) msg.obj;
+ sendReply(context, message, sb, exitValue);
+ break;
+ }
+ }
+ };
+
+ try{
+ CommandRunner runner = new CommandRunner(handler, null, command);
+ runner.run(COMMAND_TIMEOUT);
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ Toast.makeText(context,
+ "Received SMS: " + message.getMessageBody(), Toast.LENGTH_LONG).show();
+ }
+
+ private void sendReply(Context context, SmsMessage received, StringBuilder output, int exitValue){
+ try{
+ String message = output.length() > MAX_REPLY_LENGTH ? output.toString() : output.substring(0, MAX_REPLY_LENGTH - 1);
+ message+= "\n["+exitValue+"]";
+ message = removeDuplicateWhitespace(message).toString();
+ Toast.makeText(context,
+ "Will reply, recipient: "+received.getOriginatingAddress()+" message: " + message, Toast.LENGTH_LONG).show();
+ SmsManager sm = SmsManager.getDefault();
+ ArrayList<String> multipart = sm.divideMessage(message);
+ sm.sendMultipartTextMessage(received.getOriginatingAddress(), null, multipart, null, null);
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+
+ }
+
+ public static CharSequence removeDuplicateWhitespace(CharSequence inputStr) {
+ String patternStr = "\\s+";
+ String replaceStr = " ";
+ Pattern pattern = Pattern.compile(patternStr);
+ Matcher matcher = pattern.matcher(inputStr);
+ return matcher.replaceAll(replaceStr);
+ }
+
+ private String getCommand(SmsMessage message){
+ String messageBody = message.getMessageBody();
+ if(messageBody.startsWith(PREFIX)){
+ messageBody = messageBody.substring(PREFIX.length());
+ int spaceIndex = messageBody.indexOf(' ');
+ if(spaceIndex != -1 && spaceIndex + 1 < messageBody.length()){
+ String nodeName = messageBody.substring(0, spaceIndex).trim();
+ String commandText = messageBody.substring(spaceIndex + 1);
+ if(nodeName.length() != 0){
+ Node node = new Node();
+ node.setName(nodeName);
+ return CommandBuilder.sshCommand(node, commandText);
+ }
+ }
+ }
+ return null;
+ }
+}
View
154 src/id/co/microvac/simamonit/util/CommandRunner.java
@@ -0,0 +1,154 @@
+package id.co.microvac.simamonit.util;
+
+import id.co.microvac.simamonit.R;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.widget.Button;
+
+public class CommandRunner {
+ public static final int OUTPUT_RECEIVED = 1000;
+ public static final int PROCESS_EXIT = 1001;
+
+ private Handler handler;
+ private Activity context;
+ private String command;
+ private Process process;
+ private boolean alreadyRunning = false;
+ private boolean processFinished = false;
+
+
+ public CommandRunner(Handler handler, Activity context, String command) {
+ this.handler = handler;
+ this.context = context;
+ this.command = command;
+ }
+
+ public void run(long timeout){
+ if(alreadyRunning)
+ throw new IllegalStateException("Process already running");
+
+ try{
+ process = Runtime.getRuntime().exec(command);
+ Thread waitingThread = new ProcessWaitingThread(process);
+ waitingThread.start();
+ new OutputReadingThread(process.getInputStream()).start();
+ new OutputReadingThread(process.getErrorStream()).start();
+ if(timeout > 0){
+ new ProcessKillingThread(process, timeout).start();
+ }
+ }
+ catch(Exception e){
+ if(context != null)
+ UiUtil.showException(e, context);
+ else
+ e.printStackTrace();
+ }
+ }
+
+ public boolean isProcessFinished(){
+ return processFinished;
+ }
+
+ public void kill(){
+ process.destroy();
+ }
+
+ private class OutputReadingThread extends Thread{
+ private InputStream input;
+
+ public OutputReadingThread(InputStream input) {
+ this.input = input;
+ }
+
+ public void run() {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ handler.sendMessage(Message.obtain(handler, OUTPUT_RECEIVED, line));
+ }
+ } catch (IOException ioe) {
+ } finally {
+ try {
+ reader.close();
+ input.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ private class ProcessWaitingThread extends Thread{
+
+ private Process process;
+ private int exitValue = 0;
+
+ public ProcessWaitingThread(Process process) {
+ this.process = process;
+ }
+
+ public void run() {
+ while(!processFinished)
+ {
+ try{
+ exitValue = process.exitValue();
+ processFinished = true;
+ }
+ catch(Exception e){
+ try{
+ exitValue = process.waitFor();
+ processFinished = true;
+ }
+ catch(InterruptedException ie){
+ }
+ }
+ }
+ handler.sendMessage(Message.obtain(handler, PROCESS_EXIT, exitValue));
+ }
+
+ public boolean isProcessFinished() {
+ return processFinished;
+ }
+ }
+
+ private class ProcessKillingThread extends Thread{
+
+ private Process process;
+ private long timeout = 0;
+
+ public ProcessKillingThread(Process process, long timeout) {
+ this.process = process;
+ this.timeout = timeout;
+ }
+
+ public void run() {
+ long startmillis = System.currentTimeMillis();
+ long spent = 0;
+ while(spent < timeout){
+ try{
+ Thread.sleep(timeout - spent);
+ }
+ catch(InterruptedException ie){
+ }
+ spent = System.currentTimeMillis() - startmillis;
+ }
+
+ try{
+ process.exitValue();
+ }
+ catch(Exception e){
+ process.destroy();
+ }
+ }
+
+ }
+}
View
1  src/id/co/microvac/simamonit/util/UiUtil.java
@@ -8,6 +8,7 @@
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.Context;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
Please sign in to comment.
Something went wrong with that request. Please try again.