Quellcode durchsuchen

refactor SMS + fixes required for the refactoring

David vor 9 Jahren
Ursprung
Commit
8e2a6d6d17

+ 6 - 1
app/src/main/AndroidManifest.xml

@@ -27,7 +27,12 @@
             </intent-filter>
         </activity>
 
-
+        <receiver android:name=".MainService$EventReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.CONFIGURATION_CHANGED" />
+                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
+            </intent-filter>
+        </receiver>
         <receiver android:name=".BootReceiver">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED" />

+ 6 - 2
app/src/main/java/com/example/david/libretasker/EventReducer.java

@@ -7,6 +7,7 @@ import android.provider.Telephony;
 import android.telephony.TelephonyManager;
 
 import com.example.david.libretasker.State.Network;
+import com.example.david.libretasker.State.SMS;
 import com.example.david.libretasker.State.Screen;
 import com.example.david.libretasker.State.Time;
 
@@ -17,12 +18,12 @@ import java.util.HashMap;
  */
 
 public class EventReducer {
-    public static HashMap<String, Object> reduce(HashMap<String, Object> oldState, HashMap<String, Object> action, Context context) {
+    public static HashMap<String, Object> reduce(HashMap<String, Object> oldState, HashMap<String, Object> action, Context context, Intent intent) {
         String type = (String)action.get("type");
         //HashMap<String, Object> payload = (HashMap<String, Object>)action.get("payload");
 
         HashMap<String, Object> newState = new HashMap<>(oldState);
-        //FIXME: Reducer might be part of the store
+        //FIXME: Should reducer be part of the store?
         switch (type) {
             case ConnectivityManager.CONNECTIVITY_ACTION:
                 Network n = new Network(context);
@@ -44,6 +45,9 @@ public class EventReducer {
                 newState.put("LastEventType", "Screen");
                 break;
             case Telephony.Sms.Intents.SMS_RECEIVED_ACTION:
+                SMS sms = new SMS(intent, context);
+                newState.put("SMS", sms);
+                newState.put("LastEventType", "SMS");
                 break;
             case TelephonyManager.ACTION_PHONE_STATE_CHANGED:
                 break;

+ 0 - 22
app/src/main/java/com/example/david/libretasker/Events/Events.java

@@ -1,22 +0,0 @@
-package com.example.david.libretasker.Events;
-
-import java.util.ArrayList;
-
-/**
- * Created by david on 02/01/17.
- */
-
-public class Events {
-    public static ArrayList<String> list() {
-        ArrayList<String> ret = new ArrayList<>();
-        ret.add("Network");
-        ret.add("Date/Time");
-        ret.add("Screen on/off");
-        /*
-         * Display Unlocked
-         * Missed Call, Phone ringing, received text
-         * Power: Battery charged, low, full ??
-         */
-        return ret;
-    }
-}

+ 0 - 32
app/src/main/java/com/example/david/libretasker/Events/NetworkEvent.java

@@ -1,32 +0,0 @@
-package com.example.david.libretasker.Events;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.widget.Toast;
-
-import com.example.david.libretasker.State.Network;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Created by david on 01/01/17.
- */
-public class NetworkEvent implements Event {
-    private String failureReason = "";
-    @Override
-    public String getFailureReason() {
-        return failureReason;
-    }
-    @Override
-    public boolean trigger(Context context, HashMap<String, Object> data) {
-
-        Network target = new Network(data);
-        Network state = new Network(context);
-
-        return (target.equals(state));
-    }
-}

+ 0 - 105
app/src/main/java/com/example/david/libretasker/Events/SMSEvent.java

@@ -1,105 +0,0 @@
-package com.example.david.libretasker.Events;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.Telephony;
-import android.telephony.SmsMessage;
-
-import java.util.HashMap;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import static com.example.david.libretasker.Helpers.getContactName;
-
-/**
- * Created by david on 03/01/17.
- */
-
-public class SMSEvent implements Event {
-    private String failureReason = "";
-
-    @Override
-    public boolean trigger(Context ctx, HashMap<String, Object> hm) {
-        failureReason = "";
-        Intent intent = (Intent)hm.get("Intent");
-        SmsMessage[] messages = getIntentMessagesCompat(intent);
-
-        if ( messages == null ) {
-            failureReason = "Messages is null?";
-            return false;
-        }
-
-        if ( hm.get("NameRegex") == null )
-            hm.put("NameRegex", ".*");
-
-        if ( hm.get("BodyRegex") == null )
-            hm.put("BodyRegex", ".*");
-
-        String bregex = (String)hm.get("BodyRegex");
-        String nregex = (String)hm.get("NameRegex");
-        Pattern b,n;
-        try {
-            b = Pattern.compile(bregex);
-            n = Pattern.compile(nregex);
-        } catch (PatternSyntaxException ex) {
-            failureReason = "Failed to compile regex(es)";
-            return false;
-        }
-
-        for (SmsMessage s : messages) {
-            String number = s.getOriginatingAddress();
-
-            if ((String)hm.get("Sender") != null )
-                if ( ! number.equals((String)hm.get("Sender")) )
-                    continue;
-
-            if (!b.matcher(s.getMessageBody()).matches())
-                continue;
-
-            if (!n.matcher(getContactName(ctx, number)).matches())
-                continue;
-
-            return true;
-        }
-
-        failureReason = "Couldn't match Sender nor body";
-        return false;
-    }
-
-    @Override
-    public String getFailureReason() {
-        return failureReason;
-    }
-
-    private SmsMessage[] getIntentMessagesCompat(Intent intent){
-        SmsMessage[] messages = null;
-
-        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
-            for (SmsMessage smsMessage : messages) {
-                String messageBody = smsMessage.getMessageBody();
-            }
-        } else { //FIXME: Never tested
-            Bundle bundle = intent.getExtras();
-            if (bundle != null) {
-                try {
-                    Object[] pdus = (Object[]) bundle.get("pdus");
-                    messages  = new SmsMessage[pdus.length];
-                    for (int i = 0; i < messages .length; i++) {
-                        messages [i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
-                    }
-                } catch (Exception ex) {
-                    ex.printStackTrace();
-                }
-            }
-        }
-
-        return messages;
-    }
-}

+ 1 - 2
app/src/main/java/com/example/david/libretasker/Helpers.java

@@ -23,9 +23,8 @@ public class Helpers {
             contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
         }
 
-        if(cursor != null && !cursor.isClosed()) {
+        if( !cursor.isClosed() )
             cursor.close();
-        }
 
         return contactName;
     }

+ 7 - 5
app/src/main/java/com/example/david/libretasker/MainService.java

@@ -14,6 +14,7 @@ import android.util.Log;
 import com.example.david.libretasker.Actions.Actions;
 import com.example.david.libretasker.Events.Event;
 import com.example.david.libretasker.State.Network;
+import com.example.david.libretasker.State.SMS;
 import com.example.david.libretasker.Store.Store;
 
 import java.util.ArrayList;
@@ -65,9 +66,10 @@ public class MainService extends Service {
         HashMap<String, Object> net = new HashMap<>();
         HashMap<String, Object> conditions = new HashMap<>();
 
-        net.put("ValidSSIDs", Arrays.asList("Cueva"));
-        Network n = new Network(net);
-        conditions.put("Network", n);
+        net.put("NameRegex","Android.*");
+
+        SMS n = new SMS(net);
+        conditions.put("SMS", n);
 
         Store.subscribe(createRunnable(conditions, new ArrayList<HashMap<String, Object>>()));
 
@@ -102,12 +104,12 @@ public class MainService extends Service {
         return null;
     }
 
-    class EventReceiver extends BroadcastReceiver {
+    public static class EventReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
             HashMap<String, Object> action = new HashMap<>();
             action.put("type", intent.getAction());
-            Store.dispatch(action, context);
+            Store.dispatch(action, context, intent);
         }
     }
 

+ 102 - 0
app/src/main/java/com/example/david/libretasker/State/SMS.java

@@ -0,0 +1,102 @@
+package com.example.david.libretasker.State;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Telephony;
+import android.telephony.SmsMessage;
+
+import java.util.HashMap;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import static com.example.david.libretasker.Helpers.getContactName;
+
+/**
+ * Created by david on 04/01/17.
+ */
+
+public class SMS {
+    private SmsMessage[] messages;
+    private String name = null;
+    private String body = null;
+    private String number = null;
+
+    private Context context;
+    private Pattern bregex;
+    private Pattern nregex;
+
+    public SMS(Intent intent, Context c) {
+        messages = getIntentMessagesCompat(intent);
+        context = c;
+    }
+
+    public SMS(HashMap<String, Object> hm) {
+        name = (String)hm.get("NameRegex");
+        body = (String)hm.get("BodyRegex");
+        number = (String)hm.get("Sender");
+
+        try {
+            bregex = Pattern.compile(body == null ? ".*" : body);
+            nregex = Pattern.compile(name == null ? ".*" : name );
+        } catch (PatternSyntaxException ex) {
+            //failureReason = "Failed to compile regex(es)";
+
+        }
+    }
+
+    public boolean equals(Object o) {
+        //FIXME: What to do with multiple messages? Now having 1 match is enough.
+        if ( o.getClass() != SMS.class )
+            return false;
+        SMS currentState = (SMS)o;
+        int matches = 0;
+
+        for (SmsMessage s : currentState.messages) {
+            String cnumber = s.getOriginatingAddress();
+
+            if ( number != null )
+                if ( ! number.equals(cnumber) )
+                    continue;
+
+            if (!bregex.matcher(s.getMessageBody()).matches())
+                continue;
+
+            String cname = getContactName(currentState.context, cnumber);
+            if ( cname == null && name != null)
+                continue;
+
+            if ( cname == null || !nregex.matcher(cname).matches())
+                continue;
+
+            matches++;
+        }
+
+        return (matches > 0);
+    }
+
+    private SmsMessage[] getIntentMessagesCompat(Intent intent){
+        SmsMessage[] messages = null;
+
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
+        } else { //FIXME: Never tested
+            Bundle bundle = intent.getExtras();
+            if (bundle != null) {
+                try {
+                    Object[] pdus = (Object[]) bundle.get("pdus");
+                    messages  = new SmsMessage[pdus.length];
+                    for (int i = 0; i < messages .length; i++) {
+                        //noinspection deprecation
+                        messages [i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
+                    }
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                }
+            }
+        }
+
+        return messages;
+    }
+}

+ 3 - 8
app/src/main/java/com/example/david/libretasker/Store/Store.java

@@ -1,6 +1,7 @@
 package com.example.david.libretasker.Store;
 
 import android.content.Context;
+import android.content.Intent;
 
 import com.example.david.libretasker.EventReducer;
 
@@ -19,18 +20,12 @@ public class Store {
         return state.get(key);
     }
 
-    public static void dispatch(HashMap<String, Object> val, Context context) {
+    public static void dispatch(HashMap<String, Object> val, Context context, Intent intent) {
         String key = (String)val.get("type");
         if( key == null )
             return;
 
-        state = EventReducer.reduce(state, val, context);
-        /*
-        HashMap<String, Object> newState = EventReducer.reduce(state, val, context);
-        if (newState.equals(state))
-            return;
-        //FIXME: ?? these values should never be equal
-        */
+        state = EventReducer.reduce(state, val, context, intent);
 
         for ( Runnable r : listeners )
             r.run();