From 0df53420369954155d7a68e7f7f50d32dc4ced23 Mon Sep 17 00:00:00 2001 From: Jens Date: Sat, 27 Mar 2021 22:52:42 +0100 Subject: [PATCH] Notification trigger. --- .../java/com/jens/automation2/Rule.java | 180 +++++++++--------- .../java/com/jens/automation2/Rule.java | 20 ++ .../java/com/jens/automation2/Rule.java | 20 ++ .../java/com/jens/automation2/Trigger.java | 65 ++++--- .../jens/automation2/XmlFileInterface.java | 2 + .../receivers/NotificationListener.java | 38 +++- app/src/main/res/values/strings.xml | 1 + 7 files changed, 196 insertions(+), 130 deletions(-) diff --git a/app/src/apkFlavor/java/com/jens/automation2/Rule.java b/app/src/apkFlavor/java/com/jens/automation2/Rule.java index e6e5801d..96531677 100644 --- a/app/src/apkFlavor/java/com/jens/automation2/Rule.java +++ b/app/src/apkFlavor/java/com/jens/automation2/Rule.java @@ -648,109 +648,69 @@ public class Rule implements Comparable else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.bluetoothConnection)) { Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4); - -// if( // connected / disconnected -// (oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACL_CONNECTED"))) -// | -// (!oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED") | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECTED"))) -// ) -// { -// if(oneTrigger.getBluetoothDeviceAddress() != null) -// { -// if(oneTrigger.getBluetoothDeviceAddress().equals("")) -// { -// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No bluetooth address specified, any will do.", 4); -// } -// else if(oneTrigger.getBluetoothDeviceAddress().equals("")) -// { -// // ??? -// } -// else -// { -// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address specified, checking that.", 4); -// if(!BluetoothReceiver.getLastAffectedDevice().getAddress().equals(oneTrigger.getBluetoothDeviceAddress())) -// { -// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectDeviceAddress), 3); -// return false; -// } -// else -// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address matches. Rule will apply.", 4); -// } -// } -// } -// else if(BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND)) -// { -// if(!oneTrigger.getTriggerParameter()) -// { -// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyDeviceInRangeButShouldNotBe), 3); -// return false; -// } -// } -// else // above only checks for last action, this checks for things in the past + + if(oneTrigger.getBluetoothDeviceAddress().equals("")) { - if(oneTrigger.getBluetoothDeviceAddress().equals("")) - { - if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) - { - if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter()) - return false; - } - else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) - { - if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter()) - return false; - } - else - { - // range - if(BluetoothReceiver.isAnyDeviceInRange() != oneTrigger.getTriggerParameter()) - return false; - } - } - else if(oneTrigger.getBluetoothDeviceAddress().equals("")) + if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { - if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) - { - if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter()) - return false; - } - else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) - { - if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter()) - return false; - } - else - { - // range - if(BluetoothReceiver.isAnyDeviceInRange() == oneTrigger.getTriggerParameter()) - return false; - } + if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter()) + return false; } - else if(oneTrigger.getBluetoothDeviceAddress().length() > 0) + else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) { - if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) - { - if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) - return false; - } - else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) - { - if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) - return false; - } - else - { - // range - if(BluetoothReceiver.isDeviceInRange(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) - return false; - } + if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter()) + return false; } else { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyStateNotCorrect), 3); - return false; + // range + if(BluetoothReceiver.isAnyDeviceInRange() != oneTrigger.getTriggerParameter()) + return false; } } + else if(oneTrigger.getBluetoothDeviceAddress().equals("")) + { + if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) + { + if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter()) + return false; + } + else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) + { + if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter()) + return false; + } + else + { + // range + if(BluetoothReceiver.isAnyDeviceInRange() == oneTrigger.getTriggerParameter()) + return false; + } + } + else if(oneTrigger.getBluetoothDeviceAddress().length() > 0) + { + if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) + { + if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) + return false; + } + else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) + { + if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) + return false; + } + else + { + // range + if(BluetoothReceiver.isDeviceInRange(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter()) + return false; + } + } + else + { + Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyStateNotCorrect), 3); + return false; + } } else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged)) { @@ -763,6 +723,18 @@ public class Rule implements Comparable return false; } } + else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification)) + { + k + if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter()) + return false; + else + if(oneTrigger.getHeadphoneType() != 2 && oneTrigger.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType()) + { + Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), 3); + return false; + } + } } return true; @@ -1279,6 +1251,26 @@ public class Rule implements Comparable return ruleCandidates; } + + public static ArrayList findRuleCandidates(Trigger.Trigger_Enum triggerType) + { + ArrayList ruleCandidates = new ArrayList(); + + for(Rule oneRule : ruleCollection) + { + innerloop: + for(Trigger oneTrigger : oneRule.getTriggerSet()) + { + if(oneTrigger.getTriggerType() == triggerType) + { + ruleCandidates.add(oneRule); + break innerloop; //we don't need to search the other triggers in the same rule + } + } + } + + return ruleCandidates; + } public static ArrayList findRuleCandidatesByActivityDetection() { diff --git a/app/src/fdroidFlavor/java/com/jens/automation2/Rule.java b/app/src/fdroidFlavor/java/com/jens/automation2/Rule.java index d2b7b0a8..e04d4a62 100644 --- a/app/src/fdroidFlavor/java/com/jens/automation2/Rule.java +++ b/app/src/fdroidFlavor/java/com/jens/automation2/Rule.java @@ -1248,6 +1248,26 @@ public class Rule implements Comparable return ruleCandidates; } + + public static ArrayList findRuleCandidates(Trigger.Trigger_Enum triggerType) + { + ArrayList ruleCandidates = new ArrayList(); + + for(Rule oneRule : ruleCollection) + { + innerloop: + for(Trigger oneTrigger : oneRule.getTriggerSet()) + { + if(oneTrigger.getTriggerType() == triggerType) + { + ruleCandidates.add(oneRule); + break innerloop; //we don't need to search the other triggers in the same rule + } + } + } + + return ruleCandidates; + } public static ArrayList findRuleCandidatesByActivityDetection() { diff --git a/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java b/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java index e6e5801d..291f6743 100644 --- a/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java +++ b/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java @@ -1279,6 +1279,26 @@ public class Rule implements Comparable return ruleCandidates; } + + public static ArrayList findRuleCandidates(Trigger.Trigger_Enum triggerType) + { + ArrayList ruleCandidates = new ArrayList(); + + for(Rule oneRule : ruleCollection) + { + innerloop: + for(Trigger oneTrigger : oneRule.getTriggerSet()) + { + if(oneTrigger.getTriggerType() == triggerType) + { + ruleCandidates.add(oneRule); + break innerloop; //we don't need to search the other triggers in the same rule + } + } + } + + return ruleCandidates; + } public static ArrayList findRuleCandidatesByActivityDetection() { diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index 9129ef19..4b9b1555 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -231,7 +231,6 @@ public class Trigger this.timeFrame = timeFrame; } - @RequiresApi(api = Build.VERSION_CODES.KITKAT) @SuppressWarnings("unused") @Override @@ -456,34 +455,44 @@ public class Trigger returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.headsetDisconnected), type)); break; case notification: - String[] params = getTriggerParameter2().split(triggerParameter2Split); - String app = params[0]; - String titleDir = params[1]; - String title = params[2]; - String textDir = params[3]; - String text; - if(params.length >=5) - text = params[4]; + if(this.getTriggerParameter2().contains(triggerParameter2Split)) + { + String[] params = getTriggerParameter2().split(triggerParameter2Split); + + String app = params[0]; + String titleDir = params[1]; + String title = params[2]; + String textDir = params[3]; + String text; + if (params.length >= 5) + text = params[4]; + else + text = ""; + StringBuilder triggerBuilder = new StringBuilder(); + + String appString; + if (app.equalsIgnoreCase("-1")) + appString = Miscellaneous.getAnyContext().getResources().getString(R.string.anyApp); + else + appString = "app " + app; + + if(triggerParameter) + triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.postsNotification), appString)); + else + triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.removedNotification), appString)); + + if (title.length() > 0) + triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.title) + " " + Trigger.getMatchString(titleDir) + " " + title); + + if (text.length() > 0) + triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.text) + " " + Trigger.getMatchString(textDir) + " " + text); + + returnString.append(triggerBuilder.toString()); + } else - text = ""; - StringBuilder triggerBuilder = new StringBuilder(); - - String appString; - if(app.equalsIgnoreCase("-1")) - appString = Miscellaneous.getAnyContext().getResources().getString(R.string.anyApp); - else - appString = "app " + app; - - triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.postsNotification), appString)); - - if(title.length() > 0) - triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.title) + " " + Trigger.getMatchString(titleDir) + " " + title); - - if(text.length() > 0) - triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.text) + " " + Trigger.getMatchString(textDir) + " " + text); - - returnString.append(triggerBuilder.toString()); - + { + setTriggerParameter2("-1" + triggerParameter2Split + directionEquals + triggerParameter2Split + triggerParameter2Split + directionEquals + triggerParameter2Split + triggerParameter2Split); + } break; default: returnString.append("error"); diff --git a/app/src/main/java/com/jens/automation2/XmlFileInterface.java b/app/src/main/java/com/jens/automation2/XmlFileInterface.java index 5f8f28ea..dab6d995 100644 --- a/app/src/main/java/com/jens/automation2/XmlFileInterface.java +++ b/app/src/main/java/com/jens/automation2/XmlFileInterface.java @@ -271,6 +271,8 @@ public class XmlFileInterface } else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.headsetPlugged) serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getHeadphoneType())); + else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.notification) + serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2())); serializer.endTag(null, "TriggerParameter2"); serializer.endTag(null, "Trigger"); } diff --git a/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java b/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java index cdade9cc..f295ea5e 100644 --- a/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java +++ b/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java @@ -10,6 +10,10 @@ import android.service.notification.StatusBarNotification; import androidx.annotation.RequiresApi; import com.jens.automation2.AutomationService; +import com.jens.automation2.Rule; +import com.jens.automation2.Trigger; + +import java.util.ArrayList; // See here for reference: http://gmariotti.blogspot.com/2013/11/notificationlistenerservice-and-kitkat.html @@ -47,17 +51,35 @@ public class NotificationListener extends NotificationListenerService String title = sbn.getNotification().extras.getString(EXTRA_TITLE); String text = sbn.getNotification().extras.getString(EXTRA_TEXT); - + checkNotification(true, app, title, text); } } -// @Override -// public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) -// { -// super.onNotificationPosted(sbn, rankingMap); -// sbn.getNotification().extras.getString(EXTRA_TITLE); -// sbn.getNotification().extras.getString(EXTRA_TEXT; -// } + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + @Override + public void onNotificationRemoved(StatusBarNotification sbn) + { + super.onNotificationRemoved(sbn); + + if(AutomationService.isMyServiceRunning(NotificationListener.this)) + { + String app = sbn.getPackageName(); + String title = sbn.getNotification().extras.getString(EXTRA_TITLE); + String text = sbn.getNotification().extras.getString(EXTRA_TEXT); + + checkNotification(true, app, title, text); + } + } + + void checkNotification(boolean created, String appName, String title, String text) + { + ArrayList ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification); + for(int i=0; iAny app This trigger will respond to other applications opening notifications in the notification area. You can specify another application from which the notification has to come from. If you don\'t the notifications from any other application will count.\nYou can also specify strings that must be or must not be in the notification title or notification body. %1$s posts notification + notification from %1$s removed Notification appears Notification disappears Direction