diff --git a/app/src/apkFlavor/java/com/jens/automation2/Rule.java b/app/src/apkFlavor/java/com/jens/automation2/Rule.java index 249a5370..bd5ee2b6 100644 --- a/app/src/apkFlavor/java/com/jens/automation2/Rule.java +++ b/app/src/apkFlavor/java/com/jens/automation2/Rule.java @@ -34,8 +34,6 @@ import java.util.Calendar; import java.util.Date; import static com.jens.automation2.Trigger.triggerParameter2Split; -import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT; -import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE; import androidx.core.app.NotificationCompat; @@ -371,344 +369,27 @@ public class Rule implements Comparable { for(Trigger oneTrigger : this.getTriggerSet()) { - if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.pointOfInterest)) + if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.activityDetection)) { - // Am I here? - PointOfInterest activePoi = PointOfInterest.getActivePoi(); - if(activePoi != null) //entering one - { - if(oneTrigger.getPointOfInterest() != null) - { - if(activePoi.equals(oneTrigger.getPointOfInterest())) - { - if(!oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're entering POI: " + oneTrigger.getPointOfInterest().getName() + ", not leaving it.", 4); - return false; - } - } - else - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. This is " + activePoi.getName() + ", not " + oneTrigger.getPointOfInterest().getName() + ".", 4); - return false; - } - } - else if(oneTrigger.getPointOfInterest() == null) - { - if(oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at a POI. Rule specifies not at none, so leaving any.", 4); - return false; - } - } - } - else //leaving one - { - // We are not at any POI. But if this trigger requires us NOT to be there, that may be fine. - if(oneTrigger.getPointOfInterest() != null) - { -// if(activePoi.equals(oneTrigger.getPointOfInterest())) -// { - if(!oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "We are not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\". But since that's required by this rule that's fine.", 4); - } - else - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\".", 3); - return false; - } -// } - } - else if(oneTrigger.getPointOfInterest() == null) - { - if(!oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at no POI. Rule specifies to be at anyone.", 5); - return false; - } - } - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame)) - { - Date now = new Date(); - String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds()); - Time nowTime = Time.valueOf(timeString); - Calendar calNow = Calendar.getInstance(); - - - if(oneTrigger.getTimeFrame().getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK))) - { - if( - // Regular case, start time is lower than end time - ( - Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0 - && - Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0 - ) - || - // Other case, start time higher than end time, timeframe goes over midnight - ( - Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0 - && - (Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0 - || - Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0) - ) - - ) - { - // We are in the timeframe - Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + "). Trigger of Rule " + this.getName() + " applies.", 3); - if(oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 3); - //return true; - } - else - { - Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 3); - return false; - } - } - else - { - Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the time. Trigger of Rule " + this.getName() + " doesn\'t apply..", 5); - if(!oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 5); - //return true; - } - else - { - Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 5); - return false; - } - // return false; - } - } - else - { - Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the day. Trigger of Rule " + this.getName() + " doesn\'t apply.", 5); - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.charging)) - { - if(BatteryReceiver.isDeviceCharging(context) == 0) - { - return false; // unknown charging state, can't activate rule under these conditions - } - else if(BatteryReceiver.isDeviceCharging(context) == 1) - { - if(oneTrigger.getTriggerParameter()) //rule says when charging, but we're currently discharging - return false; - } - else if(BatteryReceiver.isDeviceCharging(context) == 2) - { - if(!oneTrigger.getTriggerParameter()) //rule says when discharging, but we're currently charging - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.usb_host_connection)) - { - if(BatteryReceiver.isUsbHostConnected() != oneTrigger.getTriggerParameter()) - { - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.batteryLevel)) - { - if(oneTrigger.getTriggerParameter()) - { - if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3); - return false; - } - } - else - { - if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3); - return false; - } - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.speed)) - { - if(oneTrigger.getTriggerParameter()) - { - if(LocationProvider.getSpeed() < oneTrigger.getSpeed()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3); - return false; - } - } - else - { - if(LocationProvider.getSpeed() > oneTrigger.getSpeed()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3); - return false; - } - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.noiseLevel)) - { - if(oneTrigger.getTriggerParameter()) - { - if(NoiseListener.getNoiseLevelDb() < oneTrigger.getNoiseLevelDb()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsQuieterThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3); - return false; - } - } - else - { - if(NoiseListener.getNoiseLevelDb() > oneTrigger.getNoiseLevelDb()) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsLouderThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3); - return false; - } - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.wifiConnection)) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4); - if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected - { - if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4); - if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2())) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3); - return false; - } - else - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name matches. Rule will apply.", 4); - } - else - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No wifi name specified, any will do.", 4); - } - else - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi state not correct, demanded " + String.valueOf(oneTrigger.getTriggerParameter() + ", got " + String.valueOf(WifiBroadcastReceiver.lastConnectedState)), 4); - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.process_started_stopped)) - { - boolean running = ProcessListener.getRunningApps().contains(oneTrigger.getProcessName()); - - if(running) - Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is currently running.", 4); - else - Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is not running.", 4); - - if(running != oneTrigger.getTriggerParameter()) - { - Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger doesn't apply.", 4); - return false; - } - - Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger applies.", 4); - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.airplaneMode)) - { - if(ConnectivityReceiver.isAirplaneMode(context) != oneTrigger.getTriggerParameter()) - { - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.roaming)) - { - if(ConnectivityReceiver.isRoaming(context) != oneTrigger.getTriggerParameter()) - { - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall)) - { - String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split); - // state dir number - - if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2]))) - { - //if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter()) - if( - (elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING) - || - (elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK) - || - (elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE) - ) - { - if( - elements[1].equals(Trigger.triggerPhoneCallDirectionAny) - || - (elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1) - || - (elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2) - ) - { - // Trigger conditions are met - } - else - { - Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong direction. Demanded: " + String.valueOf(oneTrigger.getPhoneDirection()) + ", got: " + String.valueOf(PhoneStatusListener.getLastPhoneDirection()), 4); - return false; - } - } - else - { - Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong call status. Demanded: " + String.valueOf(oneTrigger.getTriggerParameter()) + ", got: " + String.valueOf(PhoneStatusListener.isInACall()), 4); - return false; - } - } - else - { - Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4); - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag)) - { - if(NfcReceiver.lastReadLabel == null) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNoTagLabel), 3); - return false; - } - else if(!NfcReceiver.lastReadLabel.equals(oneTrigger.getNfcTagId())) - { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongTagLabel) + " " + NfcReceiver.lastReadLabel + " / " + oneTrigger.getNfcTagId(), 3); - return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.activityDetection)) - { - if(ActivityDetectionReceiver.getActivityDetectionLastResult() != null) + if (ActivityDetectionReceiver.getActivityDetectionLastResult() != null) { boolean found = false; - for(DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities()) + for (DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities()) { - if(oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType()) + if (oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType()) found = true; } - if(!found) + if (!found) { Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityNotPresent), ActivityDetectionReceiver.getDescription(oneTrigger.getActivityDetectionType())), 3); return false; } else { - for(DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities()) - { - if(oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType() && oneDetectedActivity.getConfidence() < Settings.activityDetectionRequiredProbability) + for (DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities()) + { + if (oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType() && oneDetectedActivity.getConfidence() < Settings.activityDetectionRequiredProbability) { Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityGivenButTooLowProbability), ActivityDetectionReceiver.getDescription(oneDetectedActivity.getType()), String.valueOf(oneDetectedActivity.getConfidence()), String.valueOf(Settings.activityDetectionRequiredProbability)), 3); return false; @@ -717,220 +398,10 @@ public class Rule implements Comparable } } } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.bluetoothConnection)) + else { - Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4); - - 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(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); + if (!oneTrigger.applies(null, context)) return false; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged)) - { - 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; - } - } - else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification)) - { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) - { - String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split); - - String myApp = params[0]; - String myTitleDir = params[1]; - String requiredTitle = params[2]; - String myTextDir = params[3]; - String requiredText; - if (params.length >= 5) - requiredText = params[4]; - else - requiredText = ""; - - if(oneTrigger.getTriggerParameter()) - { - // Check an active notification that is still there - - boolean foundMatch = false; - - for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications()) - { - if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis()) - { - String notificationApp = sbn.getPackageName(); - String notificationTitle = null; - String notificationText = null; - - Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + notificationApp + ", title: " + notificationTitle + ", text: " + notificationText, 5); - - if (!myApp.equals("-1")) - { - if (!notificationApp.equalsIgnoreCase(myApp)) - { - Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5); - continue; - } - } - else - { - if(myApp.equals(BuildConfig.APPLICATION_ID)) - { - return false; - } - } - - /* - If there are multiple notifications ("stacked") title or text might be null: - https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications - */ - - Bundle extras = sbn.getNotification().extras; - - // T I T L E - if (extras.containsKey(EXTRA_TITLE)) - notificationTitle = sbn.getNotification().extras.getString(EXTRA_TITLE); - - if (!StringUtils.isEmpty(requiredTitle)) - { - if (!Miscellaneous.compare(myTitleDir, requiredTitle, notificationTitle)) - { - Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5); - continue; - } - } - else - Miscellaneous.logEvent("i", "NotificationCheck", "A required title for a notification trigger was not specified.", 5); - - // T E X T - - if (extras.containsKey(EXTRA_TEXT)) - notificationText = sbn.getNotification().extras.getString(EXTRA_TEXT); - - if (!StringUtils.isEmpty(requiredText)) - { - if (!Miscellaneous.compare(myTextDir, requiredText, notificationText)) - { - Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5); - continue; - } - } - else - Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5); - - foundMatch = true; - break; - } - } - - if(!foundMatch) - return false; - } - else - { - // check a notification that is gone - - if(NotificationListener.getLastNotification() != null) - { - if(!NotificationListener.getLastNotification().isCreated()) - { - String app = NotificationListener.getLastNotification().getApp(); - String title = NotificationListener.getLastNotification().getTitle(); - String text = NotificationListener.getLastNotification().getText(); - - if (!myApp.equals("-1")) - { - if (!app.equalsIgnoreCase(myApp)) - return false; - } - else - { - if(myApp.equals(BuildConfig.APPLICATION_ID)) - { - return false; - } - } - - if (requiredTitle.length() > 0) - { - if (!Miscellaneous.compare(myTitleDir, title, requiredTitle)) - return false; - } - - if (requiredText.length() > 0) - { - if (!Miscellaneous.compare(myTextDir, text, requiredText)) - return false; - } - } - else - return false; - } - } - } } } diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index 1c8064b4..209a4d6c 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -3,11 +3,28 @@ package com.jens.automation2; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.os.Build; +import android.os.Bundle; +import android.service.notification.StatusBarNotification; +import android.telephony.TelephonyManager; import android.util.Log; import androidx.annotation.RequiresApi; +import com.jens.automation2.location.LocationProvider; +import com.jens.automation2.location.WifiBroadcastReceiver; +import com.jens.automation2.receivers.BatteryReceiver; import com.jens.automation2.receivers.BluetoothReceiver; +import com.jens.automation2.receivers.ConnectivityReceiver; +import com.jens.automation2.receivers.HeadphoneJackListener; +import com.jens.automation2.receivers.NfcReceiver; +import com.jens.automation2.receivers.NoiseListener; +import com.jens.automation2.receivers.NotificationListener; +import com.jens.automation2.receivers.PhoneStatusListener; +import com.jens.automation2.receivers.ProcessListener; +import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT; +import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE; + +import org.apache.commons.lang3.StringUtils; import java.sql.Time; import java.util.ArrayList; @@ -30,7 +47,7 @@ public class Trigger this.hasFlipped = hasFlipped; } - public boolean applies(Object triggeringObject) + public boolean applies(Object triggeringObject, Context context) { try { @@ -40,6 +57,66 @@ public class Trigger if(!checkDateTime(triggeringObject, false)) return false; break; + case pointOfInterest: + if(!checkLocation()) + return false; + break; + case charging: + if(!checkCharging()) + return false; + break; + case usb_host_connection: + if(!checkUsbHostConnection()) + return false; + break; + case batteryLevel: + if(!checkBatteryLevel()) + return false; + break; + case speed: + if(!checkSpeed()) + return false; + break; + case noiseLevel: + if(!checkNoiseLevel()) + return false; + break; + case wifiConnection: + if(!checkWifiConnection()) + return false; + break; + case process_started_stopped: + if(!checkProcess()) + return false; + break; + case airplaneMode: + if(!checkAirplaneMode()) + return false; + break; + case roaming: + if(!checkRoaming()) + return false; + break; + case phoneCall: + if(!checkPhoneCall()) + return false; + break; + case nfcTag: + if(!checkNfc()) + return false; + break; + case bluetoothConnection: + if(!checkBluetooth()) + return false; + break; + case headsetPlugged: + if(!checkHeadsetPlugged()) + return false; + break; + case notification: + if(!checkNotification()) + return false; + break; default: break; } @@ -48,11 +125,504 @@ public class Trigger } catch(Exception e) { - Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1); + Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.getParentRule().toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1); return false; } } + boolean checkNotification() + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + { + String[] params = this.getTriggerParameter2().split(triggerParameter2Split); + + String myApp = params[0]; + String myTitleDir = params[1]; + String requiredTitle = params[2]; + String myTextDir = params[3]; + String requiredText; + if (params.length >= 5) + requiredText = params[4]; + else + requiredText = ""; + + if(this.getTriggerParameter()) + { + // Check an active notification that is still there + + boolean foundMatch = false; + + for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications()) + { + if(getParentRule().getLastExecution() == null || sbn.getPostTime() > this.getParentRule().getLastExecution().getTimeInMillis()) + { + String notificationApp = sbn.getPackageName(); + String notificationTitle = null; + String notificationText = null; + + Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getParentRule().getName() + ". App: " + notificationApp + ", title: " + notificationTitle + ", text: " + notificationText, 5); + + if (!myApp.equals("-1")) + { + if (!notificationApp.equalsIgnoreCase(myApp)) + { + Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5); + continue; + } + } + else + { + if(myApp.equals(BuildConfig.APPLICATION_ID)) + { + return false; + } + } + + /* + If there are multiple notifications ("stacked") title or text might be null: + https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications + */ + + Bundle extras = sbn.getNotification().extras; + + // T I T L E + if (extras.containsKey(EXTRA_TITLE)) + notificationTitle = sbn.getNotification().extras.getString(EXTRA_TITLE); + + if (!StringUtils.isEmpty(requiredTitle)) + { + if (!Miscellaneous.compare(myTitleDir, requiredTitle, notificationTitle)) + { + Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5); + continue; + } + } + else + Miscellaneous.logEvent("i", "NotificationCheck", "A required title for a notification trigger was not specified.", 5); + + // T E X T + + if (extras.containsKey(EXTRA_TEXT)) + notificationText = sbn.getNotification().extras.getString(EXTRA_TEXT); + + if (!StringUtils.isEmpty(requiredText)) + { + if (!Miscellaneous.compare(myTextDir, requiredText, notificationText)) + { + Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5); + continue; + } + } + else + Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5); + + foundMatch = true; + break; + } + } + + if(!foundMatch) + return false; + } + else + { + // check a notification that is gone + + if(NotificationListener.getLastNotification() != null) + { + if(!NotificationListener.getLastNotification().isCreated()) + { + String app = NotificationListener.getLastNotification().getApp(); + String title = NotificationListener.getLastNotification().getTitle(); + String text = NotificationListener.getLastNotification().getText(); + + if (!myApp.equals("-1")) + { + if (!app.equalsIgnoreCase(myApp)) + return false; + } + else + { + if(myApp.equals(BuildConfig.APPLICATION_ID)) + { + return false; + } + } + + if (requiredTitle.length() > 0) + { + if (!Miscellaneous.compare(myTitleDir, title, requiredTitle)) + return false; + } + + if (requiredText.length() > 0) + { + if (!Miscellaneous.compare(myTextDir, text, requiredText)) + return false; + } + } + else + return false; + } + } + } + + return true; + } + + boolean checkHeadsetPlugged() + { + if(HeadphoneJackListener.isHeadsetConnected() != this.getTriggerParameter()) + return false; + else + if(this.getHeadphoneType() != 2 && this.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), 3); + return false; + } + + return true; + } + + boolean checkBluetooth() + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Checking for bluetooth...", 4); + + if(this.getBluetoothDeviceAddress().equals("")) + { + if(this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) + { + if(BluetoothReceiver.isAnyDeviceConnected() != this.getTriggerParameter()) + return false; + } + else if((this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) + { + if(BluetoothReceiver.isAnyDeviceConnected() != this.getTriggerParameter()) + return false; + } + else + { + // range + if(BluetoothReceiver.isAnyDeviceInRange() != this.getTriggerParameter()) + return false; + } + } + else if(this.getBluetoothDeviceAddress().equals("")) + { + if(this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) + { + if(BluetoothReceiver.isAnyDeviceConnected() == this.getTriggerParameter()) + return false; + } + else if((this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) + { + if(BluetoothReceiver.isAnyDeviceConnected() == this.getTriggerParameter()) + return false; + } + else + { + // range + if(BluetoothReceiver.isAnyDeviceInRange() == this.getTriggerParameter()) + return false; + } + } + else if(this.getBluetoothDeviceAddress().length() > 0) + { + if(this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) + { + if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(this.getBluetoothDeviceAddress())) != this.getTriggerParameter()) + return false; + } + else if((this.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))) + { + if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(this.getBluetoothDeviceAddress())) != this.getTriggerParameter()) + return false; + } + else + { + // range + if(BluetoothReceiver.isDeviceInRange(BluetoothReceiver.getDeviceByAddress(this.getBluetoothDeviceAddress())) != this.getTriggerParameter()) + return false; + } + } + else + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyStateNotCorrect), 3); + return false; + } + + return true; + } + + boolean checkNfc() + { + if(NfcReceiver.lastReadLabel == null) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNoTagLabel), 3); + return false; + } + else if(!NfcReceiver.lastReadLabel.equals(this.getNfcTagId())) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWrongTagLabel) + " " + NfcReceiver.lastReadLabel + " / " + this.getNfcTagId(), 3); + return false; + } + + return true; + } + + boolean checkPhoneCall() + { + String[] elements = this.getTriggerParameter2().split(triggerParameter2Split); + // state dir number + + if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2]))) + { + //if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter()) + if( + (elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING) + || + (elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK) + || + (elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE) + ) + { + if( + elements[1].equals(Trigger.triggerPhoneCallDirectionAny) + || + (elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1) + || + (elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2) + ) + { + // Trigger conditions are met + } + else + { + Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong direction. Demanded: " + String.valueOf(this.getPhoneDirection()) + ", got: " + String.valueOf(PhoneStatusListener.getLastPhoneDirection()), 4); + return false; + } + } + else + { + Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong call status. Demanded: " + String.valueOf(this.getTriggerParameter()) + ", got: " + String.valueOf(PhoneStatusListener.isInACall()), 4); + return false; + } + } + else + { + Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + this.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4); + return false; + } + + return false; + } + + boolean checkRoaming() + { + if(ConnectivityReceiver.isRoaming(Miscellaneous.getAnyContext()) != this.getTriggerParameter()) + { + return false; + } + + return true; + } + + boolean checkAirplaneMode() + { + if(ConnectivityReceiver.isAirplaneMode(Miscellaneous.getAnyContext()) != this.getTriggerParameter()) + { + return false; + } + + return true; + } + + boolean checkProcess() + { + boolean running = ProcessListener.getRunningApps().contains(this.getProcessName()); + + if(running) + Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + this.getProcessName() + " is currently running.", 4); + else + Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + this.getProcessName() + " is not running.", 4); + + if(running != this.getTriggerParameter()) + { + Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger doesn't apply.", 4); + return false; + } + + Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger applies.", 4); + + return true; + } + + boolean checkWifiConnection() + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Checking for wifi state", 4); + if(this.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected + { + if(this.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Wifi name specified, checking that.", 4); + if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2())) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3); + return false; + } + else + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Wifi name matches. Rule will apply.", 4); + } + else + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "No wifi name specified, any will do.", 4); + } + else + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Wifi state not correct, demanded " + String.valueOf(this.getTriggerParameter() + ", got " + String.valueOf(WifiBroadcastReceiver.lastConnectedState)), 4); + return false; + } + + return true; + } + + boolean checkNoiseLevel() + { + if(this.getTriggerParameter()) + { + if(NoiseListener.getNoiseLevelDb() < this.getNoiseLevelDb()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyItsQuieterThan) + " " + String.valueOf(this.getNoiseLevelDb()), 3); + return false; + } + } + else + { + if(NoiseListener.getNoiseLevelDb() > this.getNoiseLevelDb()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyItsLouderThan) + " " + String.valueOf(this.getNoiseLevelDb()), 3); + return false; + } + } + + return true; + } + + boolean checkSpeed() + { + if(this.getTriggerParameter()) + { + if(LocationProvider.getSpeed() < this.getSpeed()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(this.getSpeed()), 3); + return false; + } + } + else + { + if(LocationProvider.getSpeed() > this.getSpeed()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(this.getSpeed()), 3); + return false; + } + } + + return true; + } + + boolean checkBatteryLevel() + { + if(this.getTriggerParameter()) + { + if(BatteryReceiver.getBatteryLevel() <= this.getBatteryLevel()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(this.getBatteryLevel()), 3); + return false; + } + } + else + { + if(this.getBatteryLevel() >= this.getBatteryLevel()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(this.getBatteryLevel()), 3); + return false; + } + } + + return true; + } + + boolean checkUsbHostConnection() + { + if(BatteryReceiver.isUsbHostConnected() != this.getTriggerParameter()) + { + return false; + } + + return true; + } + + boolean checkLocation() + { + // Am I here? + PointOfInterest activePoi = PointOfInterest.getActivePoi(); + if(activePoi != null) //entering one + { + if(this.getPointOfInterest() != null) + { + if(activePoi.equals(this.getPointOfInterest())) + { + if(!this.getTriggerParameter()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Rule doesn't apply. We're entering POI: " + this.getPointOfInterest().getName() + ", not leaving it.", 4); + return false; + } + } + else + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Rule doesn't apply. This is " + activePoi.getName() + ", not " + this.getPointOfInterest().getName() + ".", 4); + return false; + } + } + else if(this.getPointOfInterest() == null) + { + if(this.getTriggerParameter()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Rule doesn't apply. We're at a POI. Rule specifies not at none, so leaving any.", 4); + return false; + } + } + } + else //leaving one + { + // We are not at any POI. But if this trigger requires us NOT to be there, that may be fine. + if(this.getPointOfInterest() != null) + { +// if(activePoi.equals(oneTrigger.getPointOfInterest())) +// { + if(!this.getTriggerParameter()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "We are not at POI \"" + this.getPointOfInterest().getName() + "\". But since that's required by this rule that's fine.", 4); + } + else + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Rule doesn't apply. We're not at POI \"" + this.getPointOfInterest().getName() + "\".", 3); + return false; + } +// } + } + else if(this.getPointOfInterest() == null) + { + if(!this.getTriggerParameter()) + { + Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "Rule doesn't apply. We're at no POI. Rule specifies to be at anyone.", 5); + return false; + } + } + } + + return true; + } + public boolean hasStateRecentlyNotApplied(Object triggeringObject) { // nur mit einem Trigger? @@ -75,11 +645,31 @@ public class Trigger } catch(Exception e) { - Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1); + Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.getParentRule().toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1); return false; } } + boolean checkCharging() + { + if(BatteryReceiver.isDeviceCharging(Miscellaneous.getAnyContext()) == 0) + { + return false; // unknown charging state, can't activate rule under these conditions + } + else if(BatteryReceiver.isDeviceCharging(Miscellaneous.getAnyContext()) == 1) + { + if(this.getTriggerParameter()) //rule says when charging, but we're currently discharging + return false; + } + else if(BatteryReceiver.isDeviceCharging(Miscellaneous.getAnyContext()) == 2) + { + if(!this.getTriggerParameter()) //rule says when discharging, but we're currently charging + return false; + } + + return true; + } + public boolean checkDateTime(Object triggeringObject, boolean checkifStateChangedSinceLastRuleExecution) { /* diff --git a/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java b/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java index 3c4cfc1e..16ac40a0 100644 --- a/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java +++ b/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java @@ -215,7 +215,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis if(tf.getRepetition() > 0) { - if(oneTrigger.applies(calNow)) + if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext())) { Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow);