calendar trigger

This commit is contained in:
jens 2023-12-28 17:17:08 +01:00
parent 2ba25a9e65
commit cd47b33449
7 changed files with 210 additions and 107 deletions

View File

@ -144,7 +144,12 @@
<receiver android:name=".receivers.DateTimeListener" /> <receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" /> <receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" /> <receiver android:name=".receivers.TimeZoneListener" />
<receiver android:name=".receivers.CalendarReceiver" /> <receiver android:name=".receivers.CalendarReceiver">
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED"/>
<data android:scheme="content"/>
<data android:host="com.android.calendar"/>
</intent-filter> </receiver>
<receiver <receiver
android:name=".DeviceAdmin" android:name=".DeviceAdmin"

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest> </manifest>

View File

@ -18,13 +18,14 @@ import androidx.annotation.Nullable;
import com.jens.automation2.receivers.CalendarReceiver; import com.jens.automation2.receivers.CalendarReceiver;
import java.sql.Array; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ActivityManageTriggerCalendar extends Activity public class ActivityManageTriggerCalendar extends Activity
{ {
CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere; CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent;
Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection; Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection;
EditText etCalendarTitle, etCalendarLocation, etCalendarDescription; EditText etCalendarTitle, etCalendarLocation, etCalendarDescription;
LinearLayout llCalendarSelection; LinearLayout llCalendarSelection;
@ -47,6 +48,7 @@ public class ActivityManageTriggerCalendar extends Activity
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection); spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection); spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);
spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection); spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection);
chkCalendarAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarAllDayEvent);
chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy); chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy);
chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree); chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree);
chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative); chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative);
@ -80,7 +82,7 @@ public class ActivityManageTriggerCalendar extends Activity
for(CalendarReceiver.AndroidCalendar cal : CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this)) for(CalendarReceiver.AndroidCalendar cal : CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this))
{ {
CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this); CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this);
oneCalCheckbox.setText(cal.displayName); oneCalCheckbox.setText(cal.toString());
oneCalCheckbox.setTag(cal); oneCalCheckbox.setTag(cal);
llCalendarSelection.addView(oneCalCheckbox); llCalendarSelection.addView(oneCalCheckbox);
checkboxesCalendars.add(oneCalCheckbox); checkboxesCalendars.add(oneCalCheckbox);
@ -98,6 +100,18 @@ public class ActivityManageTriggerCalendar extends Activity
} }
}); });
chkCalendarAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
{
if(checked)
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventTrue));
else
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventFalse));
}
});
bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener() bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener()
{ {
@Override @Override
@ -140,6 +154,7 @@ public class ActivityManageTriggerCalendar extends Activity
titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split + titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split +
descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split + descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split +
locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split + locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split +
String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split + Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split +
Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()])); Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()]));
@ -174,8 +189,9 @@ public class ActivityManageTriggerCalendar extends Activity
3 = description 3 = description
4 = locationDir 4 = locationDir
5 = location 5 = location
6 = availability list 6 = all day event
7 = calendars list 7 = availability list
8 = calendars list
*/ */
for(int i = 0; i < directions.length; i++) for(int i = 0; i < directions.length; i++)
@ -194,9 +210,18 @@ public class ActivityManageTriggerCalendar extends Activity
etCalendarDescription.setText(input[3]); etCalendarDescription.setText(input[3]);
etCalendarLocation.setText(input[5]); etCalendarLocation.setText(input[5]);
String[] availabilities = input[6].split(separator); chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[6]));
String[] calendars = input[7].split(separator);
String[] availabilities = null;
if(!StringUtils.isEmpty(input[7]))
availabilities = input[7].split(separator);
String[] calendars = null;
if(!StringUtils.isEmpty(input[8]))
calendars = input[8].split(separator);
if(availabilities != null)
{
for (String avail : availabilities) for (String avail : availabilities)
{ {
if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY) if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY)
@ -210,7 +235,10 @@ public class ActivityManageTriggerCalendar extends Activity
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE) else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE)
chkCalendarAvailabilityWorkingElsewhere.setChecked(true); chkCalendarAvailabilityWorkingElsewhere.setChecked(true);
} }
}
if(calendars != null)
{
List<String> usedCalendarIDs = new ArrayList<>(); List<String> usedCalendarIDs = new ArrayList<>();
List<String> unusedCalendarIDs = new ArrayList<>(); List<String> unusedCalendarIDs = new ArrayList<>();
for (CheckBox checkbox : checkboxesCalendars) for (CheckBox checkbox : checkboxesCalendars)
@ -244,3 +272,4 @@ public class ActivityManageTriggerCalendar extends Activity
} }
} }
} }
}

View File

@ -631,8 +631,9 @@ public class Trigger
3 = description 3 = description
4 = eventLocationDirection 4 = eventLocationDirection
5 = eventLocation 5 = eventLocation
6 = availabilityDirection 6 = all day event
7 = availability 7 = availabilityList
8 = calendarList
*/ */
for(CalendarReceiver.CalendarEvent event : calendarEvents) for(CalendarReceiver.CalendarEvent event : calendarEvents)
@ -641,7 +642,7 @@ public class Trigger
if(isActive != event.isCurrentlyActive()) if(isActive != event.isCurrentlyActive())
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Event has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Event has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5);
break; continue;
} }
if(!StringUtils.isEmpty(conditions[1])) if(!StringUtils.isEmpty(conditions[1]))
@ -649,7 +650,7 @@ public class Trigger
if (!Miscellaneous.compare(conditions[0], conditions[1], event.title)) if (!Miscellaneous.compare(conditions[0], conditions[1], event.title))
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Title does not match.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Title does not match.", 5);
break; continue;
} }
} }
@ -658,7 +659,7 @@ public class Trigger
if (!Miscellaneous.compare(conditions[2], conditions[3], event.description)) if (!Miscellaneous.compare(conditions[2], conditions[3], event.description))
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Description does not match.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Description does not match.", 5);
break; continue;
} }
} }
@ -667,27 +668,39 @@ public class Trigger
if (!Miscellaneous.compare(conditions[4], conditions[5], event.location)) if (!Miscellaneous.compare(conditions[4], conditions[5], event.location))
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Location does not match.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Location does not match.", 5);
break; continue;
} }
} }
String[] availabilities = conditions[6].split(ActivityManageTriggerCalendar.separator); 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 (availabilities.length > 0)
{ {
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true)) if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Availability does not match.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Availability does not match.", 5);
break; continue;
}
} }
} }
String[] calendars = conditions[7].split(ActivityManageTriggerCalendar.separator); if(!StringUtils.isEmpty(conditions[8]))
if(availabilities.length > 0) {
String[] calendars = conditions[8].split(ActivityManageTriggerCalendar.separator);
if (calendars.length > 0)
{ {
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true)) if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Calendar does not match.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Calendar does not match.", 5);
break; continue;
}
} }
} }
@ -698,7 +711,14 @@ public class Trigger
// At this point none of the calendar items matches this trigger // At this point none of the calendar items matches this trigger
//TODO: If trigger demands no calendar event and there is absolutely no future event, we'll need to check for that. // If trigger demands no calendar event and there is absolutely no future event, we'll need to check for that.
if(calendarEvents.size() == 0)
{
if(getTriggerParameter() == false)
return true;
// Further criteria don't matter if there are no events to check
}
} }
catch(Exception e) catch(Exception e)
{ {
@ -1927,9 +1947,9 @@ public class Trigger
|| ||
!StringUtils.isEmpty(conditions[5]) !StringUtils.isEmpty(conditions[5])
|| ||
!StringUtils.isEmpty(conditions[6]) !StringUtils.isEmpty(conditions[7])
|| ||
!StringUtils.isEmpty(conditions[7])) !StringUtils.isEmpty(conditions[8]))
{ {
returnString.append(" ("); returnString.append(" (");
@ -1940,11 +1960,16 @@ public class Trigger
if (!StringUtils.isEmpty(conditions[5])) if (!StringUtils.isEmpty(conditions[5]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", "); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", ");
if (!StringUtils.isEmpty(conditions[6])) if(Boolean.parseBoolean(conditions[6]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[6] + ", "); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventTrue) + ", ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", ");
if (!StringUtils.isEmpty(conditions[7])) if (!StringUtils.isEmpty(conditions[7]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[7]); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[7] + ", ");
if (!StringUtils.isEmpty(conditions[8]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[8]);
if (returnString.toString().endsWith(", ")) if (returnString.toString().endsWith(", "))
returnString.delete(returnString.length() - 2, returnString.length()); returnString.delete(returnString.length() - 2, returnString.length());

View File

@ -30,6 +30,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
public static final int AVAILABILITY_WORKING_ELSEWHERE = 5; public static final int AVAILABILITY_WORKING_ELSEWHERE = 5;
static List<AndroidCalendar> calendarsCache = null; static List<AndroidCalendar> calendarsCache = null;
static List<CalendarEvent> calendarEventsCache = null;
public static CalendarReceiver getInstance() public static CalendarReceiver getInstance()
{ {
@ -44,6 +45,9 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
{ {
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED)) if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED))
{ {
calendarsCache = null;
calendarEventsCache = null;
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
for(int i = 0; i < ruleCandidates.size(); i++) for(int i = 0; i < ruleCandidates.size(); i++)
{ {
@ -65,6 +69,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
{ {
calendarIntentFilter = new IntentFilter(); calendarIntentFilter = new IntentFilter();
calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED); calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED);
// calendarIntentFilter.addDataScheme("content");
} }
AutomationService.getInstance().registerReceiver(calendarReceiverInstance, calendarIntentFilter); AutomationService.getInstance().registerReceiver(calendarReceiverInstance, calendarIntentFilter);
@ -104,6 +109,14 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
{ {
public int calendarId; public int calendarId;
public String displayName; public String displayName;
public String accountString;
@NonNull
@Override
public String toString()
{
return displayName + " (" + accountString + ")";
}
} }
public static class CalendarEvent public static class CalendarEvent
@ -142,7 +155,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
cursor = context.getContentResolver().query( cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/calendars"), Uri.parse("content://com.android.calendar/calendars"),
new String[]{"_id", "calendar_displayName"}, new String[]{ "_id", "calendar_displayName", "ownerAccount", },
null, null, null); null, null, null);
cursor.moveToFirst(); cursor.moveToFirst();
@ -158,6 +171,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
AndroidCalendar calendar = new AndroidCalendar(); AndroidCalendar calendar = new AndroidCalendar();
calendar.calendarId = Integer.parseInt(cursor.getString(0)); calendar.calendarId = Integer.parseInt(cursor.getString(0));
calendar.displayName = cursor.getString(1); calendar.displayName = cursor.getString(1);
calendar.accountString = cursor.getString(2);
calendarsCache.add(calendar); calendarsCache.add(calendar);
} }
@ -176,6 +190,10 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
public static List<CalendarEvent> readCalendarEvents(Context context, boolean includePastEvents) public static List<CalendarEvent> readCalendarEvents(Context context, boolean includePastEvents)
{ {
if(calendarEventsCache == null)
{
calendarEventsCache = new ArrayList<>();
Cursor cursor; Cursor cursor;
cursor = context.getContentResolver().query( cursor = context.getContentResolver().query(
@ -187,8 +205,6 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
// fetching calendars name // fetching calendars name
String CNames[] = new String[cursor.getCount()]; String CNames[] = new String[cursor.getCount()];
List<CalendarEvent> eventlist = new ArrayList<>();
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
for (int i = 0; i < CNames.length; i++) for (int i = 0; i < CNames.length; i++)
@ -217,7 +233,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
event.availability = cursor.getString(8); event.availability = cursor.getString(8);
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis()) if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
eventlist.add(event); calendarEventsCache.add(event);
} }
catch (Exception e) catch (Exception e)
{} {}
@ -226,8 +242,9 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
if(cursor != null) if(cursor != null)
cursor.close(); cursor.close();
}
return eventlist; return calendarEventsCache;
} }
public static void startCalendarReceiver(final AutomationService automationServiceRef) public static void startCalendarReceiver(final AutomationService automationServiceRef)

View File

@ -168,6 +168,30 @@
</TableRow> </TableRow>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/allDayEvent" />
<CheckBox
android:id="@+id/chkCalendarAllDayEvent"
android:checked="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"

View File

@ -924,4 +924,8 @@
<string name="anyCalendar">any calender</string> <string name="anyCalendar">any calender</string>
<string name="availabilities">availabilities</string> <string name="availabilities">availabilities</string>
<string name="calendarsMissingHint">In this trigger calendars with IDs %1$s have been previously configured, but have been deleted since. With the next save those will be removed from this trigger. Until then this trigger/condition will never be met.</string> <string name="calendarsMissingHint">In this trigger calendars with IDs %1$s have been previously configured, but have been deleted since. With the next save those will be removed from this trigger. Until then this trigger/condition will never be met.</string>
<string name="account">account</string>
<string name="allDayEvent">All day event</string>
<string name="allDayEventTrue">event is an all day event</string>
<string name="allDayEventFalse">event is not an all day event</string>
</resources> </resources>