Calendar trigger

This commit is contained in:
jens 2024-01-06 17:25:27 +01:00
parent 223cca442d
commit ec62b91449
17 changed files with 264 additions and 169 deletions

View File

@ -139,6 +139,7 @@
</intent-filter>
</receiver>
<receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
@ -151,6 +152,7 @@
<receiver
android:name=".DeviceAdmin"
android:exported="true"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
@ -193,6 +195,7 @@
<activity
android:name=".ActivityMainTabLayout"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -242,6 +245,7 @@
<service
android:name=".receivers.NotificationListener"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>

View File

@ -10,9 +10,12 @@ import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.google.android.gms.location.DetectedActivity;
import com.jens.automation2.receivers.ActivityDetectionReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.CalendarReceiver;
import java.util.ArrayList;
import java.util.Calendar;
@ -376,6 +379,11 @@ public class Rule implements Comparable<Rule>
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " applies and has flipped since its last execution.", 4);
return true;
}
else if(hasTriggerOfType(Trigger.Trigger_Enum.calendarEvent) && CalendarReceiver.mayRuleStillBeActivatedForPendingCalendarEvents(this))
{
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " applies, has not flipped since its last execution, but may still be executed for other calendar events.", 4);
return true;
}
else
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " has not flipped since its last execution.", 4);
}
@ -384,7 +392,7 @@ public class Rule implements Comparable<Rule>
return false;
}
public boolean applies(Context context)
{
if(AutomationService.getInstance() == null)
@ -780,4 +788,32 @@ public class Rule implements Comparable<Rule>
return null;
}
@Override
public boolean equals(@Nullable Object obj)
{
return this.getName().equals(((Rule)obj).getName());
}
public boolean hasTriggerOfType(Trigger.Trigger_Enum queryType)
{
for(Trigger t : getTriggerSet())
{
if(t.getTriggerType().equals(queryType))
return true;
}
return false;
}
public boolean hasActionOfType(Action.Action_Enum queryType)
{
for(Action a : getActionSet())
{
if(a.getAction().equals(queryType))
return true;
}
return false;
}
}

View File

@ -136,6 +136,7 @@
</intent-filter>
</receiver>
<receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
@ -148,6 +149,7 @@
<receiver
android:name=".DeviceAdmin"
android:exported="true"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
@ -190,6 +192,7 @@
<activity
android:name=".ActivityMainTabLayout"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -239,6 +242,7 @@
<service
android:name=".receivers.NotificationListener"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>

View File

@ -344,7 +344,16 @@ public class Rule implements Comparable<Rule>
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
{
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
{
if(this.getLastExecution() != null)
{
Calendar now = Calendar.getInstance();
if (this.getLastExecution().getTimeInMillis() + oneTrigger.getTimeFrame().getRepetition() * 1000 <= now.getTimeInMillis())
return true;
}
else
return true;
}
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
@ -372,7 +381,7 @@ public class Rule implements Comparable<Rule>
return false;
}
public boolean applies(Context context)
{
if(AutomationService.getInstance() == null)

View File

@ -172,7 +172,6 @@
<activity android:name=".ActivityManageTriggerCheckVariable" />
<activity android:name=".ActivityManageActionCopyToClipboard" />
<activity android:name=".ActivityManageActionLocationService" />
<activity android:name=".ActivityManageTriggerCalendar" />
<activity
android:name=".ActivityMainTabLayout"
@ -222,6 +221,7 @@
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" />
<service
android:name=".receivers.NotificationListener"

View File

@ -347,7 +347,16 @@ public class Rule implements Comparable<Rule>
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
{
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
{
if(this.getLastExecution() != null)
{
Calendar now = Calendar.getInstance();
if (this.getLastExecution().getTimeInMillis() + oneTrigger.getTimeFrame().getRepetition() * 1000 <= now.getTimeInMillis())
return true;
}
else
return true;
}
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{

View File

@ -345,16 +345,33 @@ public class Action
if (this.getAction().equals(Action_Enum.triggerUrl))
{
String[] components = parameter2.split(";");
String[] components;
if(parameter2.contains(Action.actionParameter2Split))
components = parameter2.split(Action.actionParameter2Split);
else
components = parameter2.split(";");
if (components.length >= 3)
{
returnString.append(" (");
if(components.length >= 4)
returnString.append(components[3]);
else
returnString.append(ActivityManageActionTriggerUrl.methodGet);
returnString.append(")");
returnString.append(": " + components[2]);
if (parameter1)
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingAuthentication) + ".");
}
else
{
returnString.append(" (");
returnString.append(ActivityManageActionTriggerUrl.methodGet);;
returnString.append(")");
returnString.append(": " + components[0]);
}
}
else if (this.getAction().equals(Action_Enum.startOtherActivity))
{
@ -786,7 +803,7 @@ public class Action
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
else
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
try
{

View File

@ -1,6 +1,6 @@
package com.jens.automation2;
import static com.jens.automation2.ActivityManageActionTriggerUrl.edit;
//import static com.jens.automation2.ActivityManageActionTriggerUrl.edit;
import android.app.Activity;
import android.content.Intent;

View File

@ -3,6 +3,7 @@ package com.jens.automation2;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
@ -45,8 +46,8 @@ public class ActivityManageActionTriggerUrl extends Activity
public static final String methodGet = "GET";
public static final String methodPost = "POST";
public static boolean edit = false;
public static Action resultingAction = null;
// public static boolean edit = false;
// public static Action resultingAction = null;
@Override
protected void onCreate(Bundle savedInstanceState)
@ -95,11 +96,9 @@ public class ActivityManageActionTriggerUrl extends Activity
{
if(etTriggerUrl.getText().toString().length() > 0)
{
if(resultingAction == null)
resultingAction = new Action();
Intent returnIntent = new Intent();
resultingAction.setAction(Action_Enum.triggerUrl);
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter1, chkTriggerUrlUseAuthentication.isChecked());
String username = etTriggerUrlUsername.getText().toString();
String password = etTriggerUrlPassword.getText().toString();
@ -120,15 +119,16 @@ public class ActivityManageActionTriggerUrl extends Activity
if(httpParams.length() > 0)
httpParams = httpParams.substring(Action.actionParameters2SeparatorOuter.length());
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter2,
username + Action.actionParameter2Split +
password + Action.actionParameter2Split +
etTriggerUrl.getText().toString().trim() + Action.actionParameter2Split +
method + Action.actionParameter2Split +
httpParams
);
//TODO: Check if http params listview is scrollable
backToRuleManager();
setResult(RESULT_OK, returnIntent);
finish();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.urlTooShort), Toast.LENGTH_LONG).show();
@ -169,22 +169,21 @@ public class ActivityManageActionTriggerUrl extends Activity
}
});
updateListView();
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
if(edit)
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
{
// username,password,URL,etc.
String[] components;
if(ActivityManageActionTriggerUrl.resultingAction.getParameter2().contains(Action.actionParameter2Split))
components = ActivityManageActionTriggerUrl.resultingAction.getParameter2().split(Action.actionParameter2Split, -1);
if(getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).contains(Action.actionParameter2Split))
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split, -1);
else
components = ActivityManageActionTriggerUrl.resultingAction.getParameter2().split(";", -1);
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";", -1);
if(components.length >= 3)
{
etTriggerUrl.setText(components[2]);
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
etTriggerUrl.setText(components[2]);
chkTriggerUrlUseAuthentication.setChecked(getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, false));
etTriggerUrlUsername.setText(components[0]);
etTriggerUrlPassword.setText(components[1]);
@ -250,47 +249,7 @@ public class ActivityManageActionTriggerUrl extends Activity
}
});
}
private void backToRuleManager()
{
if(edit && resultingAction != null)
{
String username = etTriggerUrlUsername.getText().toString();
String password = etTriggerUrlPassword.getText().toString();
if(username == null)
username = "";
if(password == null)
password = "";
String method = methodGet;
if(rbTriggerUrlMethodPost.isChecked())
method = methodPost;
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
String httpParams = "";
for (String s : httpParamsList)
httpParams += Action.actionParameters2SeparatorOuter + s;
if(httpParams.length() > 0)
httpParams = httpParams.substring(Action.actionParameters2SeparatorOuter.length());
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
username + Action.actionParameter2Split +
password + Action.actionParameter2Split +
etTriggerUrl.getText().toString().trim() + Action.actionParameter2Split +
method + Action.actionParameter2Split +
httpParams
);
//TODO:Duplicate code in save routine in onCreate()
}
setResult(RESULT_OK);
this.finish();
}
private void updateListView()
{
Miscellaneous.logEvent("i", "ListView", "Attempting to update lvTriggerUrlPostParameters", 4);

View File

@ -396,9 +396,11 @@ public class ActivityManageRule extends Activity
break;
case triggerUrl:
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class);
ActivityManageActionTriggerUrl.resultingAction = a;
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
activityEditTriggerUrlIntent.putExtra("edit", true);
// ActivityManageActionTriggerUrl.resultingAction = a;
// ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
// activityEditTriggerUrlIntent.putExtra("edit", true);
activityEditTriggerUrlIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditTriggerUrlIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit);
break;
case speakText:
@ -1380,12 +1382,13 @@ public class ActivityManageRule extends Activity
if(requestCode == requestCodeActionTriggerUrlAdd)
{
//TODO: Transform into newer and cleaner handover method through intent data
if(resultCode == RESULT_OK)
{
//add TriggerUrl
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionTriggerUrl.resultingAction);
newAction.setParentRule(ruleToEdit);
newAction.setAction(Action_Enum.triggerUrl);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
@ -1393,7 +1396,14 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
//edit TriggerUrl
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
@ -2246,7 +2256,7 @@ public class ActivityManageRule extends Activity
{
//launch other activity to enter a url and parameters;
newAction.setAction(Action_Enum.triggerUrl);
ActivityManageActionTriggerUrl.resultingAction = null;
// ActivityManageActionTriggerUrl.resultingAction = null;
Intent editTriggerIntent = new Intent(context, ActivityManageActionTriggerUrl.class);
startActivityForResult(editTriggerIntent, requestCodeActionTriggerUrlAdd);
}

View File

@ -53,6 +53,8 @@ public class ActivityManageTriggerCalendar extends Activity
Miscellaneous.setDisplayLanguage(this);
setContentView(R.layout.activity_manage_trigger_calendar);
//TODO: Hint text about multiple rule execution
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);

View File

@ -223,7 +223,7 @@ public class Miscellaneous extends Service
return result.toString();
}
public static String downloadURLwithoutCertificateChecking(String url, String username, String password, String method, Map<String, String> httpParams)
public static String downloadUrlWithoutCertificateChecking(String url, String username, String password, String method, Map<String, String> httpParams)
{
try
{
@ -298,25 +298,9 @@ public class Miscellaneous extends Service
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
// public static void logEvent(String type, String header, String description)
// {
// if(type.equals("e"))
// Log.e(header, description);
//
// if(type.equals("w"))
// Log.w(header, description);
//
// if(type.equals("i"))
// Log.i(header, description);
//
// if(Settings.writeLogFile)
// writeToLogFile(type, header, description);
// }
public static void logEvent(String type, String header, String description, int logLevel)
{
try
@ -353,7 +337,6 @@ public class Miscellaneous extends Service
{
logCleanerRunning = true;
long maxSizeInBytes = (long)Settings.logFileMaxSize * 1024 * 1024;
if(logFile.exists() && logFile.length() > (maxSizeInBytes))
@ -1006,51 +989,45 @@ public class Miscellaneous extends Service
private static void disableSSLCertificateChecking()
{
try
{
SSLSocketFactory ssf = null;
try
{
SSLContext ctx = SSLContext.getInstance("TLS");
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
ssf = new MySSLSocketFactoryInsecure(trustStore);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ctx.init(null, null, null);
{
SSLSocketFactory ssf = null;
try
{
SSLContext ctx = SSLContext.getInstance("TLS");
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
ssf = new MySSLSocketFactoryInsecure(trustStore);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ctx.init(null, null, null);
// return new DefaultHttpClient(ccm, client.getParams());
}
catch (Exception ex)
{
ex.printStackTrace();
}
catch (Exception ex)
{
ex.printStackTrace();
// return null;
}
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, getInsecureTrustManager(), new java.security.SecureRandom());
}
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, getInsecureTrustManager(), new java.security.SecureRandom());
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// HttpsURLConnection.setDefaultSSLSocketFactory(ssf);
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(getInsecureHostnameVerifier());
HttpsURLConnection.setDefaultHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}
catch (KeyManagementException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(getInsecureHostnameVerifier());
HttpsURLConnection.setDefaultHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}
catch (KeyManagementException e)
{
Miscellaneous.logEvent("e", "SSL", Log.getStackTraceString(e), 4);
}
catch (NoSuchAlgorithmException e)
{
Miscellaneous.logEvent("e", "SSL", Log.getStackTraceString(e), 4);
}
}
public static TrustManager[] getInsecureTrustManager()

View File

@ -684,7 +684,6 @@ public class Trigger
9 = calendarList
*/
boolean isActive = getTriggerParameter();
if (!ignoreActive && isActive != event.isCurrentlyActive())
{
@ -756,6 +755,12 @@ public class Trigger
// No contradictions found
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event + " matches.", 4);
/*
At this point the rule will either get executed for this event or it already has been executed for it.
*/
CalendarReceiver.addUsedPair(new CalendarReceiver.RuleEventPair(getParentRule(), event));
return true;
}

View File

@ -272,29 +272,23 @@ public class CellLocationChangedReceiver extends PhoneStateListener
locationListenerArmed = false;
Miscellaneous.logEvent("i", "LocationListener", "Disarmed location listener, accuracy reached", 4);
}
// Miscellaneous.logEvent("i", "LocationListener", "Giving update to POI class");
// PointOfInterest.positionUpdate(up2DateLocation, parentLocationProvider.parentService);
}
@Override
public void onProviderDisabled(String provider)
{
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider)
{
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
// TODO Auto-generated method stub
}
}

View File

@ -9,8 +9,10 @@ import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
@ -29,7 +31,6 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
static CalendarReceiver calendarReceiverInstance = null;
static boolean calendarReceiverActive = false;
static IntentFilter calendarIntentFilter = null;
private static AutomationService automationServiceRef;
private static Intent calendarIntent = null;
public static final int AVAILABILITY_OUT_OF_OFFICE = 4;
@ -45,6 +46,30 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
static AlarmManager alarmManager = null;
static boolean wakeupNeedsToBeScheduled = false;
public static class RuleEventPair
{
Rule rule;
CalendarEvent event;
public RuleEventPair(Rule rule, CalendarEvent event)
{
this.rule = rule;
this.event = event;
}
}
static List<RuleEventPair> calendarEventsUsed = new ArrayList<>(); // To determine for which events which rules have been executed
public static void addUsedPair(RuleEventPair pair)
{
// Add pair only if it's not in the list already.
for(RuleEventPair usedPair : calendarEventsUsed)
{
if(usedPair.rule.equals(pair.rule) && usedPair.event.equals(pair.event))
return;
}
calendarEventsUsed.add(pair);
}
public static CalendarReceiver getInstance()
{
if(calendarReceiverInstance == null)
@ -73,9 +98,15 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
}
}
private static void checkForRules(Context context)
static void checkForRules(Context context)
{
//TODO: Overwrite notification
/*
Kann die selbe Regel mehrfach pro Termin ausgeführt werden? Nein, eh nicht, ne?
Am nächsten Tag ist es wieder ein anderer Termin.
Wenn zwei zeitgleiche Termine mit gleichen Inhalten in verschiedenen Kalendern sind,
würde die Regel so 2x ausgeführt werden.
*/
//TODO: Second appointment directly one after another or overlapping won't get executed
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
for (int i = 0; i < ruleCandidates.size(); i++)
@ -86,24 +117,9 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
}
@Override
public void startListener(AutomationService automationService)
public void startListener(AutomationService automationServiceRef)
{
if(!calendarReceiverActive)
{
if(calendarReceiverInstance == null)
calendarReceiverInstance = new CalendarReceiver();
if(calendarIntentFilter == null)
{
calendarIntentFilter = new IntentFilter();
calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED);
// calendarIntentFilter.addDataScheme("content");
}
AutomationService.getInstance().registerReceiver(calendarReceiverInstance, calendarIntentFilter);
calendarReceiverActive = true;
}
startCalendarReceiver(automationServiceRef);
}
@Override
@ -171,6 +187,37 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
{
return title;
}
@Override
public boolean equals(@Nullable Object obj)
{
try
{
CalendarEvent compareEvent = (CalendarEvent) obj;
return calendarId == compareEvent.calendarId
&&
eventId.equals(compareEvent.eventId)
&&
title.equals(compareEvent.title)
&&
description.equals(compareEvent.description)
&&
location.equals(compareEvent.location)
&&
availability.equals(compareEvent.availability)
&&
start.getTimeInMillis() == compareEvent.start.getTimeInMillis()
&&
end.getTimeInMillis() == compareEvent.end.getTimeInMillis()
&&
allDay == compareEvent.allDay;
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "CalendarReceiver compare()", Log.getStackTraceString(e), 5);
return false;
}
}
}
public static List<AndroidCalendar> readCalendars(Context context)
@ -394,22 +441,22 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
Collections.sort(wakeUpCandidatesList);
if(wakeUpCandidatesList.size() == 0)
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Not scheduling any calendar related wakeup as there are no future events that might match a configured trigger.", 5);
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Not scheduling any calendar related wakeup as there are no future events that might match a configured trigger.", 4);
else
{
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);
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was null.", 4);
else
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was " + Miscellaneous.formatDate(nextWakeup.getTime()), 5);
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was " + Miscellaneous.formatDate(nextWakeup.getTime()), 4);
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);
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Alarm " + Miscellaneous.formatDate(nextWakeup.getTime()) + " has been selected as next wakeup, but not rescheduling since this was not a change.", 4);
}
}
}
@ -418,8 +465,6 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
{
if (!calendarReceiverActive)
{
CalendarReceiver.automationServiceRef = automationServiceRef;
if (calendarReceiverInstance == null)
calendarReceiverInstance = new CalendarReceiver();
@ -438,4 +483,31 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
armOrRearmTimer();
}
}
public static boolean mayRuleStillBeActivatedForPendingCalendarEvents(Rule rule)
{
for(CalendarEvent event : readCalendarEvents(Miscellaneous.getAnyContext(), false))
{
for(Trigger t : rule.getTriggerSet())
{
if(t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent) && t.checkCalendarEvent(event, false))
{
if (!hasEventBeenUsedInRule(rule, event))
return true;
}
}
}
return false;
}
static boolean hasEventBeenUsedInRule(Rule rule, CalendarEvent event)
{
for (RuleEventPair executedPair : calendarEventsUsed)
{
if (executedPair.rule.equals(rule) && executedPair.event.equals(event))
return true;
}
return false;
}
}

View File

@ -26,8 +26,6 @@ import java.util.Calendar;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NotificationListener extends NotificationListenerService// implements AutomationListenerInterface
{
static Calendar lastResponseToNotification = null;
static boolean listenerRunning = false;
static NotificationListener instance;
static SimpleNotification lastNotification = null;
@ -43,8 +41,6 @@ public class NotificationListener extends NotificationListenerService// implemen
// a bitmap to be used instead of the small icon when showing the notification payload
public static final String EXTRA_LARGE_ICON = "android.largeIcon";
protected static IntentFilter notificationReceiverIntentFilter = null;
public static SimpleNotification getLastNotification()
{
return lastNotification;

View File

@ -2,6 +2,7 @@
* Fixed: Broadcast receiver trigger would not trigger anything, but crash
* Fixed: Bug in Android 14 (not in Automation!!!) required a change when dialing MMI codes containing a # character.
* Fixed: Storage permission might be displayed as not granted even if it was
* Fixed: Applied a very old bugfix also to F-Droid and Google-Play editions that had by mistake been implemented only in the APK edition (timeFrame trigger with repetitions)
* Added: new action -> take screenshot
* Added: Location service (GPS) can be toggled between states if WRITE_SECURE_SETTINGS has been granted from a computer
* Added: triggerUrl action can now be used with POST and parameters