calendar trigger
This commit is contained in:
parent
c61c5ba14c
commit
58ec35aae5
@ -51,6 +51,9 @@ public class ActivityManageTriggerCalendar extends Activity
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_calendar);
|
||||
|
||||
// TODO: calculateNextWakeup() muß neu ausgeführt werden, wenn die Regeln geändert werden.
|
||||
|
||||
|
||||
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
|
||||
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
|
||||
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);
|
||||
|
@ -257,7 +257,7 @@ public class Trigger
|
||||
result = false;
|
||||
break;
|
||||
case calendarEvent:
|
||||
if(!checkCalendarEvent())
|
||||
if(!checkCalendarEvent(false))
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
@ -617,7 +617,7 @@ public class Trigger
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean checkCalendarEvent()
|
||||
public boolean checkCalendarEvent(boolean ignoreActive)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -638,71 +638,8 @@ public class Trigger
|
||||
|
||||
for(CalendarReceiver.CalendarEvent event : calendarEvents)
|
||||
{
|
||||
boolean isActive = getTriggerParameter();
|
||||
if(isActive != event.isCurrentlyActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5);
|
||||
if(!checkCalendarEvent(event, ignoreActive))
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[1]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[0], conditions[1], event.title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Title does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[3]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[2], conditions[3], event.description))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Description does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[5]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[4], conditions[5], event.location))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Location does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(conditions[6]) != event.allDay)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "All day setting does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[7]))
|
||||
{
|
||||
String[] availabilities = conditions[7].split(ActivityManageTriggerCalendar.separator);
|
||||
if (availabilities.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Availability does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[8]))
|
||||
{
|
||||
String[] calendars = conditions[8].split(ActivityManageTriggerCalendar.separator);
|
||||
if (calendars.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Calendar does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No contradictions found
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event + " matches.", 4);
|
||||
@ -728,6 +665,95 @@ public class Trigger
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkCalendarEvent(CalendarReceiver.CalendarEvent event, boolean ignoreActive)
|
||||
{
|
||||
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
|
||||
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), false);
|
||||
|
||||
/*
|
||||
0 = titleDirection
|
||||
1 = title;
|
||||
2 = descriptionDirection
|
||||
3 = description
|
||||
4 = eventLocationDirection
|
||||
5 = eventLocation
|
||||
6 = all day event
|
||||
7 = availabilityList
|
||||
8 = calendarList
|
||||
*/
|
||||
|
||||
|
||||
boolean isActive = getTriggerParameter();
|
||||
if (!ignoreActive && isActive != event.isCurrentlyActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[1]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[0], conditions[1], event.title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Title does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[3]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[2], conditions[3], event.description))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Description does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[5]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[4], conditions[5], event.location))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Location does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(conditions[6]) != event.allDay)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "All day setting does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[7]))
|
||||
{
|
||||
String[] availabilities = conditions[7].split(ActivityManageTriggerCalendar.separator);
|
||||
if (availabilities.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Availability does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[8]))
|
||||
{
|
||||
String[] calendars = conditions[8].split(ActivityManageTriggerCalendar.separator);
|
||||
if (calendars.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Calendar does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: all-day abwählbar machen
|
||||
// No contradictions found
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event + " matches.", 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean checkBluetooth()
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Checking for bluetooth...", this.getParentRule().getName()), 4);
|
||||
|
@ -9,7 +9,6 @@ import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@ -20,6 +19,7 @@ import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@ -43,7 +43,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
|
||||
static TimerTask timerTask = null;
|
||||
static Calendar nextWakeup = null;
|
||||
static AlarmManager alarmManager = null;
|
||||
static boolean alarmHasChanged = false;
|
||||
static boolean wakeupNeedsToBeScheduled = false;
|
||||
|
||||
public static CalendarReceiver getInstance()
|
||||
{
|
||||
@ -68,7 +68,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
|
||||
}
|
||||
else if(intent.getAction().equalsIgnoreCase(calendarAlarmAction))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmReceiver", "Received alarm for calendar receiver.", 5);
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Received alarm for calendar receiver.", 5);
|
||||
routineAtAlarm();
|
||||
}
|
||||
}
|
||||
@ -326,7 +326,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
|
||||
}
|
||||
|
||||
// If it's now filled, go on
|
||||
if(nextWakeup != null)
|
||||
if(nextWakeup != null && wakeupNeedsToBeScheduled)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
@ -340,10 +340,9 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
|
||||
{
|
||||
|
||||
}
|
||||
Miscellaneous.logEvent("i", "armOrRearmTimer()", "Setting calendar alarm for " + nextWakeup.toString(), 5);
|
||||
Miscellaneous.logEvent("i", "armOrRearmTimer()", "Scheduling wakeup for calendar at " + Miscellaneous.formatDate(nextWakeup.getTime()), 5);
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
|
||||
//alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
wakeupNeedsToBeScheduled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -354,38 +353,58 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
|
||||
private static void calculateNextWakeup()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (nextWakeup != null && nextWakeup.getTimeInMillis() < now.getTimeInMillis())
|
||||
nextWakeup = null;
|
||||
|
||||
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), false);
|
||||
if (events.size() > 0)
|
||||
|
||||
if (events.size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
List<Long> wakeUpCandidatesList = new ArrayList<>();
|
||||
|
||||
for (CalendarEvent event : events)
|
||||
{
|
||||
if (event.isCurrentlyActive())
|
||||
for (Rule r : ruleCandidates)
|
||||
{
|
||||
if (nextWakeup == null || event.end.getTimeInMillis() < nextWakeup.getTimeInMillis())
|
||||
for (Trigger t : r.getTriggerSet())
|
||||
{
|
||||
nextWakeup = event.end;
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose end of event " + event.title + " as next wakeup.", 5);
|
||||
if(!alarmHasChanged)
|
||||
alarmHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextWakeup == null || event.start.getTimeInMillis() < nextWakeup.getTimeInMillis())
|
||||
{
|
||||
nextWakeup = event.start;
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose start of event " + event.title + " as next wakeup.", 5);
|
||||
if(!alarmHasChanged)
|
||||
alarmHasChanged = true;
|
||||
if (t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent) && t.checkCalendarEvent(event, true))
|
||||
{
|
||||
/*
|
||||
Device needs to wakeup at start AND end of events, no matter what is specified in triggers.
|
||||
This is because we also need to know when a trigger doesn't apply anymore to make it
|
||||
count for hasStateNotAppliedSinceLastRuleExecution().
|
||||
Otherwise the same rule would not get executed again even after calendar events have come and gone.
|
||||
*/
|
||||
|
||||
if(event.start.getTimeInMillis() > now.getTimeInMillis())
|
||||
wakeUpCandidatesList.add(event.start.getTimeInMillis());
|
||||
|
||||
if(event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
wakeUpCandidatesList.add(event.end.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(wakeUpCandidatesList);
|
||||
|
||||
if(nextWakeup == null || nextWakeup.getTimeInMillis() != wakeUpCandidatesList.get(0))
|
||||
{
|
||||
Calendar newAlarm = Miscellaneous.calendarFromLong(wakeUpCandidatesList.get(0));
|
||||
if(nextWakeup == null)
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was null.", 5);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was " + Miscellaneous.formatDate(nextWakeup.getTime()), 5);
|
||||
nextWakeup = newAlarm;
|
||||
if (!wakeupNeedsToBeScheduled)
|
||||
wakeupNeedsToBeScheduled = true;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Alarm " + Miscellaneous.formatDate(nextWakeup.getTime()) + " has been selected as next wakeup, but not rescheduling since this was not a change.", 5);
|
||||
}
|
||||
//else
|
||||
// we expect to be called byOnReceive() when new items exist
|
||||
}
|
||||
|
||||
public static void startCalendarReceiver(final AutomationService automationServiceRef)
|
||||
|
@ -175,6 +175,13 @@
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/careAboutAllDayEvent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/evaluate"
|
||||
android:checked="true"/>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
|
@ -933,4 +933,5 @@
|
||||
<string name="errorReadingCalendars">There was an error reading the calendars on your device.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Schedule exact alarms</string>
|
||||
<string name="alarmsPermissionHint">After clicking OK a window will open. Please select Automation there and allow the app to schedule exact alarms.</string>
|
||||
<string name="evaluate">Evaluate</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user