Compare commits
97 Commits
v1.7.13
...
17b3b8fafc
Author | SHA1 | Date | |
---|---|---|---|
17b3b8fafc | |||
0d38c8bbe0 | |||
f7ff8a38e1 | |||
b7677bdcce | |||
1ff4a15818 | |||
bd42507521 | |||
fe924f6fe9 | |||
dfe8594f06 | |||
553d14b05f | |||
b38ca31df5 | |||
6e566c664d | |||
8c4b75232e | |||
4521bc7d4e | |||
eaecf63724 | |||
ec62b91449 | |||
223cca442d | |||
f3613f8eb0 | |||
8b193aa89c | |||
58ec35aae5 | |||
c61c5ba14c | |||
d75cf137ba | |||
5e3d268815 | |||
3bcf90277f | |||
81a205a8db | |||
97a3344e81 | |||
cd47b33449 | |||
2ba25a9e65 | |||
d2606b72cd | |||
584495ef61 | |||
9b28aeef8b | |||
b6bf31589a | |||
67238bd2f0 | |||
5f278a6ba0 | |||
a21f90acb5 | |||
5f8ed5765a | |||
605f85d215 | |||
21f4a7fd5c | |||
2219164869 | |||
a8646ef61d | |||
f641de9893 | |||
bca8b44ad6 | |||
c34dfa4af4 | |||
38644cee28 | |||
47898e84ea | |||
ac74b52aed | |||
3f76813e80 | |||
1b8dc5de5f | |||
3c8c0f14f2 | |||
9ead47bdf7 | |||
e4828a9720 | |||
4f971e8a1b | |||
34fbc1d005 | |||
b72049defc | |||
54f3cc84c4 | |||
7884358564 | |||
f24c9f99dc | |||
64b97c650d | |||
9daf4c4747 | |||
94f7936c4a | |||
02f7b642cf | |||
8d10bf05af | |||
8c0cee9589 | |||
6b23bd6733 | |||
1a60c88f35 | |||
3312d99177 | |||
ea01806915 | |||
36173f2fcb | |||
4c66fe906e | |||
60cfa150b5 | |||
bd2231b075 | |||
158f5f2e04 | |||
f1315dc742 | |||
28aa0c3e4b | |||
6b9dbca7ab | |||
291e0c41af | |||
c9eedd5d87 | |||
2470321e15 | |||
d85a199117 | |||
b047cde4ea | |||
9a1796f2eb | |||
7e8a6b121e | |||
810c7488c4 | |||
8af24695fd | |||
533a9bf54d | |||
8653e4853b | |||
c464a9d71f | |||
26e4851c0d | |||
11f0ee25bf | |||
a76cafc6e2 | |||
bd2920e6d9 | |||
5caf33b45d | |||
6a74d070eb | |||
eba02ade08 | |||
394effea36 | |||
4d51f1890a | |||
d1c6abaa91 | |||
587ed5803e |
@ -8,11 +8,11 @@ android {
|
||||
defaultConfig {
|
||||
applicationId "com.jens.automation2"
|
||||
minSdkVersion 16
|
||||
compileSdkVersion 31
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 129
|
||||
versionName "1.7.13"
|
||||
versionCode 138
|
||||
versionName "1.8"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -36,9 +36,15 @@ android {
|
||||
{
|
||||
dimension "version"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 31
|
||||
targetSdkVersion 33
|
||||
}
|
||||
|
||||
/*
|
||||
targetSdkVersion is kept at 28 for as long as possible.
|
||||
If raised wifi cannot be switched on or off anymore without root permissions.
|
||||
In the Google version I'm forced to raise the value regularly.
|
||||
*/
|
||||
|
||||
fdroidFlavor
|
||||
{
|
||||
dimension "version"
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -50,7 +52,6 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@ -70,6 +71,14 @@
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -87,7 +96,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -130,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" />
|
||||
@ -138,9 +148,11 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
android:exported="true"
|
||||
android:description="@string/app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
|
||||
@ -179,9 +191,11 @@
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -227,9 +241,11 @@
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
@ -261,6 +277,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -18,7 +18,7 @@ public class MyGoogleApiClient
|
||||
public com.google.android.gms.appindexing.Action getIndexApiAction()
|
||||
{
|
||||
Thing object = new Thing.Builder()
|
||||
.setName("ActivityMainScreen Page") // TODO: Define a title for the content shown.
|
||||
.setName("ActivityMainScreen Page")
|
||||
// TODO: Make sure this auto-generated URL is correct.
|
||||
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
|
||||
.build();
|
||||
|
@ -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;
|
||||
@ -373,14 +376,19 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(hasNotAppliedSinceLastExecution())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " applies and has flipped since its last execution.", 4);
|
||||
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);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" has not flipped since its last execution.", 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " does not apply.", 4);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" does not apply.", 4);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -389,7 +397,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(AutomationService.getInstance() == null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule " + getName() + " cannot apply.", 3);
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule \"" + getName() + "\" cannot apply.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -401,7 +409,7 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule \"%1$s\" generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -507,7 +515,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
boolean isActuallyToggleable = isActuallyToggable();
|
||||
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggleable;
|
||||
|
||||
String message;
|
||||
@ -521,6 +529,29 @@ public class Rule implements Comparable<Rule>
|
||||
if(Settings.startNewThreadForRuleActivation)
|
||||
publishProgress(message);
|
||||
|
||||
/*
|
||||
Make a note of Rule/CalendarEvent executed combinations
|
||||
*/
|
||||
if(Rule.this.hasTriggerOfType(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
for(CalendarReceiver.CalendarEvent event : CalendarReceiver.getApplyingCalendarEvents(Rule.this))
|
||||
{
|
||||
if(!CalendarReceiver.hasEventBeenUsedInRule(Rule.this, event))
|
||||
{
|
||||
/*
|
||||
Record only the first calendar event that matched because the rule may
|
||||
be executed once for every matching event.
|
||||
*/
|
||||
Miscellaneous.logEvent("i", "Rule", "Executing this rule run for calender event: " + event, 5);
|
||||
CalendarReceiver.addUsedPair(new CalendarReceiver.RuleEventPair(Rule.this, event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Run actions one after another
|
||||
*/
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
@ -780,4 +811,58 @@ 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;
|
||||
}
|
||||
|
||||
public int getAmountOfTriggersForType(Trigger.Trigger_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Trigger t : getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getAmountOfActionsForType(Action.Action_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Action a : getActionSet())
|
||||
{
|
||||
if(a.getAction().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -50,7 +52,6 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@ -68,6 +69,13 @@
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -85,7 +93,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -128,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" />
|
||||
@ -136,9 +145,11 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
android:exported="true"
|
||||
android:description="@string/app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
|
||||
@ -173,12 +184,15 @@
|
||||
<activity android:name=".ActivityManageTriggerTethering" />
|
||||
<activity android:name=".ActivityManageActionWakeLock" />
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -224,9 +238,11 @@
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
@ -246,6 +262,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -10,7 +10,10 @@ import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.jens.automation2.receivers.BroadcastListener;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -344,8 +347,17 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
|
||||
{
|
||||
if(oneTrigger.getTimeFrame().repetition > 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
|
||||
@ -361,14 +373,19 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(hasNotAppliedSinceLastExecution())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " applies and has flipped since its last execution.", 4);
|
||||
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);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" has not flipped since its last execution.", 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " does not apply.", 4);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" does not apply.", 4);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -377,7 +394,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(AutomationService.getInstance() == null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule " + getName() + " cannot apply.", 3);
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule \"" + getName() + "\" cannot apply.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -389,7 +406,7 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule \"%1$s\" generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -471,7 +488,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
boolean isActuallyToggleable = isActuallyToggable();
|
||||
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggleable;
|
||||
|
||||
String message;
|
||||
@ -485,6 +502,29 @@ public class Rule implements Comparable<Rule>
|
||||
if(Settings.startNewThreadForRuleActivation)
|
||||
publishProgress(message);
|
||||
|
||||
/*
|
||||
Make a note of Rule/CalendarEvent executed combinations
|
||||
*/
|
||||
if(Rule.this.hasTriggerOfType(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
for(CalendarReceiver.CalendarEvent event : CalendarReceiver.getApplyingCalendarEvents(Rule.this))
|
||||
{
|
||||
if(!CalendarReceiver.hasEventBeenUsedInRule(Rule.this, event))
|
||||
{
|
||||
/*
|
||||
Record only the first calendar event that matched because the rule may
|
||||
be executed once for every matching event.
|
||||
*/
|
||||
Miscellaneous.logEvent("i", "Rule", "Executing this rule run for calender event: " + event, 5);
|
||||
CalendarReceiver.addUsedPair(new CalendarReceiver.RuleEventPair(Rule.this, event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Run actions one after another
|
||||
*/
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
@ -744,4 +784,58 @@ 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;
|
||||
}
|
||||
|
||||
public int getAmountOfTriggersForType(Trigger.Trigger_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Trigger t : getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getAmountOfActionsForType(Action.Action_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Action a : getActionSet())
|
||||
{
|
||||
if(a.getAction().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -49,7 +51,6 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@ -65,12 +66,19 @@
|
||||
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/crane"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -100,7 +108,9 @@
|
||||
android:exported="false"
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<receiver android:name=".receivers.StartupIntentReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
@ -122,6 +132,7 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
@ -163,6 +174,8 @@
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
@ -203,7 +216,6 @@
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
@ -211,6 +223,7 @@
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
@ -223,8 +236,6 @@
|
||||
|
||||
</service>
|
||||
|
||||
<activity android:name=".ActivityPermissions" />
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
@ -246,6 +257,18 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -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;
|
||||
@ -347,8 +350,17 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
|
||||
{
|
||||
if(oneTrigger.getTimeFrame().repetition > 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
|
||||
@ -364,14 +376,19 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(hasNotAppliedSinceLastExecution())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " applies and has flipped since its last execution.", 4);
|
||||
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);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" has not flipped since its last execution.", 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule " + getName() + " does not apply.", 4);
|
||||
Miscellaneous.logEvent("i", "getsGreenLight()", "Rule \"" + getName() + "\" does not apply.", 4);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -380,7 +397,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(AutomationService.getInstance() == null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule " + getName() + " cannot apply.", 3);
|
||||
Miscellaneous.logEvent("i", "RuleCheck", "Automation service not running. Rule \"" + getName() + "\" cannot apply.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -392,7 +409,7 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule \"%1$s\" generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -498,7 +515,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
boolean isActuallyToggleable = isActuallyToggable();
|
||||
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggleable;
|
||||
|
||||
String message;
|
||||
@ -512,6 +529,29 @@ public class Rule implements Comparable<Rule>
|
||||
if(Settings.startNewThreadForRuleActivation)
|
||||
publishProgress(message);
|
||||
|
||||
/*
|
||||
Make a note of Rule/CalendarEvent executed combinations
|
||||
*/
|
||||
if(Rule.this.hasTriggerOfType(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
for(CalendarReceiver.CalendarEvent event : CalendarReceiver.getApplyingCalendarEvents(Rule.this))
|
||||
{
|
||||
if(!CalendarReceiver.hasEventBeenUsedInRule(Rule.this, event))
|
||||
{
|
||||
/*
|
||||
Record only the first calendar event that matched because the rule may
|
||||
be executed once for every matching event.
|
||||
*/
|
||||
Miscellaneous.logEvent("i", "Rule", "Executing this rule run for calender event: " + event, 5);
|
||||
CalendarReceiver.addUsedPair(new CalendarReceiver.RuleEventPair(Rule.this, event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Run actions one after another
|
||||
*/
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
@ -771,4 +811,58 @@ 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;
|
||||
}
|
||||
|
||||
public int getAmountOfTriggersForType(Trigger.Trigger_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Trigger t : getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getAmountOfActionsForType(Action.Action_Enum type)
|
||||
{
|
||||
int amount = 0;
|
||||
|
||||
for(Action a : getActionSet())
|
||||
{
|
||||
if(a.getAction().equals(type))
|
||||
amount++;
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
@ -7,10 +7,11 @@ import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Action
|
||||
@ -19,7 +20,10 @@ public class Action
|
||||
|
||||
public static final String actionParameter2Split = "ap2split";
|
||||
public static final String intentPairSeparator = "intPairSplit";
|
||||
public static final String actionParameters2SeparatorInner = "a2splitInner";
|
||||
public static final String actionParameters2SeparatorOuter = "a2splitOuter";
|
||||
public static final String vibrateSeparator = ",";
|
||||
public static final String httpErrorDefaultText = "HTTP_ERROR";
|
||||
|
||||
public enum Action_Enum
|
||||
{
|
||||
@ -56,6 +60,8 @@ public class Action
|
||||
startPhoneCall,
|
||||
stopPhoneCall,
|
||||
copyToClipboard,
|
||||
takeScreenshot,
|
||||
setLocationService,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -140,6 +146,10 @@ public class Action
|
||||
return context.getResources().getString(R.string.endPhoneCall);
|
||||
case copyToClipboard:
|
||||
return context.getResources().getString(R.string.copyTextToClipboard);
|
||||
case takeScreenshot:
|
||||
return context.getResources().getString(R.string.takeScreenshot);
|
||||
case setLocationService:
|
||||
return context.getResources().getString(R.string.setLocationServiceCapital);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -307,23 +317,62 @@ public class Action
|
||||
break;
|
||||
case copyToClipboard:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.copyTextToClipboard));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.takeScreenshot));
|
||||
break;
|
||||
case setLocationService:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setLocationService) + ": " );
|
||||
switch(Integer.parseInt(getParameter2()))
|
||||
{
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_OFF:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.off));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_SENSOR_ONLY));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_BATTERY_SAVING));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_HIGH_ACCURACY));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
returnString.append(action.toString());
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.intentPairSeparator, "/"));
|
||||
@ -414,7 +463,7 @@ public class Action
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; ").replace(Action.intentPairSeparator, "/"));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard))
|
||||
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard) || this.getAction().equals(Action_Enum.setLocationService))
|
||||
; // it's completed further above already
|
||||
else if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
|
||||
@ -632,6 +681,12 @@ public class Action
|
||||
case copyToClipboard:
|
||||
Actions.copyToClipboard(context, Miscellaneous.replaceVariablesInText(this.getParameter2(), context));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
Actions.takeScreenshot();
|
||||
break;
|
||||
case setLocationService:
|
||||
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
@ -646,33 +701,54 @@ public class Action
|
||||
|
||||
private void triggerUrl(Context context)
|
||||
{
|
||||
//TODO: Check if data needs to be escaped
|
||||
String username = null;
|
||||
String password = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
String url;
|
||||
String params = null;
|
||||
|
||||
String[] components = getParameter2().split(";");
|
||||
String[] components;
|
||||
if(getParameter2().contains(Action.actionParameter2Split))
|
||||
components = getParameter2().split(Action.actionParameter2Split, -1);
|
||||
else
|
||||
components = getParameter2().split(";", -1);
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
username = components[0];
|
||||
password = components[1];
|
||||
url = components[2];
|
||||
|
||||
if(components.length >= 4)
|
||||
method = components[3];
|
||||
|
||||
if(components.length >= 5)
|
||||
{
|
||||
params = components[4];
|
||||
}
|
||||
else
|
||||
}
|
||||
else // compatibility for very old versions which haven't upgraded, yet.
|
||||
url = components[0];
|
||||
|
||||
try
|
||||
{
|
||||
url = Miscellaneous.replaceVariablesInText(url, context);
|
||||
if(!StringUtils.isEmpty(params))
|
||||
params = Miscellaneous.replaceVariablesInText(params, context);
|
||||
|
||||
Actions myAction = new Actions();
|
||||
|
||||
Miscellaneous.logEvent("i", "HTTP", "Attempting download of " + url, 4); //getResources().getString("attemptingDownloadOf");
|
||||
|
||||
/*
|
||||
Theoretically credentials could be saved, but authentication has been turned off afterwards.
|
||||
The following if clause is there to force username and password to be null.
|
||||
*/
|
||||
if(this.getParameter1()) // use authentication
|
||||
new DownloadTask().execute(url, username, password);
|
||||
new DownloadTask().execute(url, username, password, method, params);
|
||||
else
|
||||
new DownloadTask().execute(url, null, null);
|
||||
new DownloadTask().execute(url, null, null, method, params);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -687,32 +763,49 @@ public class Action
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.uncaughtExceptionHandler);
|
||||
|
||||
int attempts=1;
|
||||
int attempts = 1;
|
||||
String urlString=parameters[0];
|
||||
|
||||
String urlUsername = null;
|
||||
String urlPassword = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
Map<String,String> httpParams = new HashMap<>();
|
||||
|
||||
if(parameters.length >= 3)
|
||||
{
|
||||
urlUsername=parameters[1];
|
||||
urlPassword=parameters[2];
|
||||
urlUsername = parameters[1];
|
||||
urlPassword = parameters[2];
|
||||
|
||||
if(parameters.length >= 4)
|
||||
method = parameters[3];
|
||||
|
||||
if(parameters.length >= 5 && parameters[4] != null)
|
||||
{
|
||||
// has params
|
||||
String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter);
|
||||
for(String pair : paramPairs)
|
||||
{
|
||||
String[] pieces = pair.split(Action.actionParameters2SeparatorInner);
|
||||
httpParams.put(pieces[0], pieces[1]);
|
||||
}
|
||||
}
|
||||
|
||||
String response = "httpError";
|
||||
HttpGet post;
|
||||
}
|
||||
|
||||
String response = httpErrorDefaultText;
|
||||
|
||||
if(Settings.httpAttempts < 1)
|
||||
Miscellaneous.logEvent("w", "HTTP Request", Miscellaneous.getAnyContext().getResources().getString(R.string.cantDownloadTooFewRequestsInSettings), 3);
|
||||
|
||||
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
|
||||
while(attempts <= Settings.httpAttempts && response.equals(httpErrorDefaultText))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
|
||||
|
||||
// Either thorough checking or no encryption
|
||||
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
|
||||
else
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
|
||||
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.NotificationManager;
|
||||
@ -10,8 +11,7 @@ import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
@ -95,6 +95,7 @@ public class Actions
|
||||
|
||||
Miscellaneous.logEvent("w", "createNotification", "Creating notification with title " + elements[0] + " and text " + elements[1], 3);
|
||||
|
||||
// Create a new notification ID each time
|
||||
int notificationId = Math.round(Calendar.getInstance().getTimeInMillis()/1000);
|
||||
|
||||
try
|
||||
@ -113,8 +114,8 @@ public class Actions
|
||||
public static void closeNotification(Action action)
|
||||
{
|
||||
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
for(StatusBarNotification n : nm.getActiveNotifications())
|
||||
{
|
||||
// for(StatusBarNotification n : nm.getActiveNotifications())
|
||||
// {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = action.getParameter2().split(Action.actionParameter2Split);
|
||||
@ -194,7 +195,7 @@ public class Actions
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "NotificationListener instance is null. Can\'t close notification.", 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public static void sendBroadcast(Context context, String action)
|
||||
@ -225,7 +226,16 @@ public class Actions
|
||||
Map<String,String> map = AutomationService.getInstance().getVariableMap();
|
||||
|
||||
if(parts.length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
map.put(parts[0], Miscellaneous.replaceVariablesInText(parts[1], Miscellaneous.getAnyContext()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
map.put(parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
map.remove(parts[0]);
|
||||
}
|
||||
@ -725,7 +735,6 @@ public class Actions
|
||||
if (method == null)
|
||||
throw new NoSuchMethodException();
|
||||
|
||||
|
||||
/*
|
||||
* For some reason this doesn't work, throws NoSuchMethodExpection even if the method is present.
|
||||
*/
|
||||
@ -985,6 +994,7 @@ public class Actions
|
||||
public void useDownloadedWebpage(String result)
|
||||
{
|
||||
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
|
||||
Actions.setVariable("last_triggerurl_result" + Action.actionParameter2Split + result);
|
||||
}
|
||||
|
||||
public static HttpClient getInsecureSslClient(HttpClient client)
|
||||
@ -1043,11 +1053,16 @@ public class Actions
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherActivity", "Starting other Activity...", 4);
|
||||
|
||||
String params[] = param.split(";");
|
||||
String params[];
|
||||
|
||||
if(param.contains(Action.actionParameter2Split))
|
||||
params = param.split(Action.actionParameter2Split);
|
||||
else
|
||||
params = param.split(";");
|
||||
|
||||
try
|
||||
{
|
||||
Intent externalActivityIntent;
|
||||
Intent externalApplicationIntent;
|
||||
|
||||
if (!startByAction)
|
||||
{
|
||||
@ -1060,15 +1075,15 @@ public class Actions
|
||||
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by activity: " + packageName + " " + className, 3);
|
||||
|
||||
externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
externalApplicationIntent = new Intent(Intent.ACTION_MAIN);
|
||||
externalApplicationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
// if(packageName.equals("dummyPkg"))
|
||||
// externalActivityIntent.setAction(className);
|
||||
// else
|
||||
externalActivityIntent.setClassName(packageName, className);
|
||||
if(packageName.equals("dummyPkg"))
|
||||
externalApplicationIntent.setAction(className);
|
||||
|
||||
if (!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext()))
|
||||
externalApplicationIntent.setClassName(packageName, className);
|
||||
|
||||
if (!Miscellaneous.doesActivityExist(externalApplicationIntent, Miscellaneous.getAnyContext()))
|
||||
Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2);
|
||||
}
|
||||
else
|
||||
@ -1076,25 +1091,32 @@ public class Actions
|
||||
// selected by action
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by action: " + param, 3);
|
||||
|
||||
externalActivityIntent = new Intent();
|
||||
externalApplicationIntent = new Intent();
|
||||
|
||||
if (!params[0].equals(dummyPackageString))
|
||||
externalActivityIntent.setPackage(params[0]);
|
||||
externalApplicationIntent.setPackage(params[0]);
|
||||
|
||||
externalActivityIntent.setAction(params[1]);
|
||||
externalApplicationIntent.setAction(params[1]);
|
||||
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString) || params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString))
|
||||
{
|
||||
externalApplicationIntent.setComponent(new ComponentName(params[0], params[2]));
|
||||
}
|
||||
}
|
||||
|
||||
externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
externalApplicationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
// Pack intents
|
||||
externalActivityIntent = packParametersIntoIntent(externalActivityIntent, params, 3);
|
||||
externalApplicationIntent = packParametersIntoIntent(externalApplicationIntent, params, 3);
|
||||
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
|
||||
automationServerRef.startActivity(externalActivityIntent);
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
|
||||
automationServerRef.startService(externalActivityIntent);
|
||||
automationServerRef.startActivity(externalApplicationIntent);
|
||||
else if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
|
||||
automationServerRef.startService(externalApplicationIntent);
|
||||
else if (params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString) && Build.VERSION.SDK_INT >= 26)
|
||||
automationServerRef.startForegroundService(externalApplicationIntent);
|
||||
else
|
||||
automationServerRef.sendBroadcast(externalActivityIntent);
|
||||
automationServerRef.sendBroadcast(externalApplicationIntent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -1165,23 +1187,38 @@ public class Actions
|
||||
intent.putExtra(singleParam[1], Short.parseShort(singleParam[2]));
|
||||
}
|
||||
else if (singleParam[0].equals("Uri"))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (singleParam[1].equalsIgnoreCase("IntentData"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
|
||||
intent.setData(Uri.parse(singleParam[2]));
|
||||
intent.setData(Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
intent.putExtra(singleParam[1], Uri.parse(singleParam[2]));
|
||||
intent.putExtra(singleParam[1], Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
else if (singleParam[0].equals("String"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
try
|
||||
{
|
||||
intent.putExtra(singleParam[1], Miscellaneous.replaceVariablesInText(singleParam[2], context));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
intent.putExtra(singleParam[1], singleParam[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
}
|
||||
@ -1955,7 +1992,6 @@ public class Actions
|
||||
boolean suAvailable = false;
|
||||
String suVersion = null;
|
||||
String suVersionInternal = null;
|
||||
// List<String> suResult = null;
|
||||
int suResult;
|
||||
|
||||
boolean success = false;
|
||||
@ -1969,12 +2005,15 @@ public class Actions
|
||||
suVersionInternal = Shell.SU.version(true);
|
||||
|
||||
Miscellaneous.logEvent("i", "executeCommandViaSu()", "suVersion: " + suVersion + ", suVersionInternal: " + suVersionInternal, 5);
|
||||
Miscellaneous.logEvent("i", "executeCommandViaSu()", "calling method: " + Miscellaneous.getCallingMethodName(), 5);
|
||||
|
||||
// suResult = Shell.SU.run(commands);
|
||||
suResult = Shell.Pool.SU.run(commands);
|
||||
|
||||
// if (suResult != null)
|
||||
// success = true;
|
||||
if(Miscellaneous.getCallingMethodName().equals("runExecutable"))
|
||||
{
|
||||
Actions.setVariable("last_run_executable_exit_code" + Action.actionParameter2Split + String.valueOf(suResult));
|
||||
// Actions.setVariable("last_run_executable_output" + Action.actionParameter2Split + (String) result[1]);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "executeCommandViaSu()", "RC=" + String.valueOf(suResult), 3);
|
||||
|
||||
@ -2038,7 +2077,10 @@ public class Actions
|
||||
else
|
||||
result = runExternalApplication(path, 0, workingDir, null);
|
||||
|
||||
boolean execResult = (boolean) result[0];
|
||||
boolean execResult = ((int) result[0] == 0);
|
||||
|
||||
Actions.setVariable("last_run_executable_exit_code" + Action.actionParameter2Split + String.valueOf((int) result[0]));
|
||||
Actions.setVariable("last_run_executable_output" + Action.actionParameter2Split + (String) result[1]);
|
||||
|
||||
return execResult;
|
||||
}
|
||||
@ -2086,19 +2128,6 @@ public class Actions
|
||||
stderr = process.getErrorStream ();
|
||||
stdout = process.getInputStream ();
|
||||
|
||||
// "write" the parms into stdin
|
||||
/*line = "param1" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param2" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param3" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();*/
|
||||
|
||||
stdin.close();
|
||||
|
||||
// clean up if any output in stdout
|
||||
@ -2163,10 +2192,6 @@ public class Actions
|
||||
|
||||
Miscellaneous.logEvent("i", "Running executable", "Error running external application.", 1);
|
||||
|
||||
// if(slotMap != null)
|
||||
// for(String key : slotMap.keySet())
|
||||
// System.clearProperty(key);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -2259,7 +2284,18 @@ public class Actions
|
||||
|
||||
public static void startPhoneCall(Context context, String phoneNumber)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
|
||||
Intent intent;
|
||||
|
||||
/*
|
||||
Bug in Android 14 makes it necessary to add double quotes around MMI code.
|
||||
More precisely it's required for codes containing the # character.
|
||||
*/
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 34)
|
||||
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode("\"" + phoneNumber + "\"")));
|
||||
else
|
||||
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
|
||||
|
||||
// intent.setClassName("com.android.phone","com.android.phone.OutgoingCallBroadcaster");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
|
||||
@ -2312,4 +2348,26 @@ public class Actions
|
||||
clipboard.setPrimaryClip(clip);
|
||||
}
|
||||
}
|
||||
|
||||
public static void takeScreenshot()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||
{
|
||||
MyAccessibilityService.getInstance().performGlobalAction(AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setLocationService(int desiredState, Context context)
|
||||
{
|
||||
// if(desiredState)
|
||||
// {
|
||||
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY).toString());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_OFF).toString());
|
||||
// }
|
||||
android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState));
|
||||
}
|
||||
|
||||
}
|
@ -39,8 +39,10 @@ public class ActivityControlCenter extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_control_center);
|
||||
|
||||
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@ -384,6 +386,7 @@ public class ActivityControlCenter extends Activity
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if (folder != null && folder.length() > 0)
|
||||
|
@ -21,6 +21,7 @@ public class ActivityDisplayLongMessage extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_display_long_message);
|
||||
|
||||
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
|
||||
|
@ -13,6 +13,7 @@ public class ActivityHelp extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(layout.activity_help_text);
|
||||
|
||||
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
|
||||
|
@ -44,7 +44,7 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(ActivityMainPoi.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_poi_layout);
|
||||
|
||||
instance = this;
|
||||
@ -108,6 +108,13 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private void buttonAddPoi()
|
||||
{
|
||||
poiToEdit = null;
|
||||
|
@ -40,7 +40,7 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(ActivityMainProfiles.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_profile_layout);
|
||||
|
||||
instance = this;
|
||||
@ -155,6 +155,13 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private AlertDialog getProfileDialog(final Profile profile)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
|
@ -48,7 +48,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(ActivityMainRules.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_rule_layout);
|
||||
|
||||
instance = this;
|
||||
@ -155,6 +155,13 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(ActivityMainScreen.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_overview_layout);
|
||||
|
||||
activityMainScreenInstance = this;
|
||||
@ -434,7 +434,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
else
|
||||
activityMainScreenInstance.checkForNews();
|
||||
|
||||
if(BuildConfig.FLAVOR.equals("apkFlavor") && Settings.automaticUpdateCheck)
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk) && Settings.automaticUpdateCheck)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (Settings.lastUpdateCheck == Settings.default_lastUpdateCheck || now.getTimeInMillis() >= Settings.lastUpdateCheck + (long)(Settings.updateCheckFrequencyDays * 24 * 60 * 60 * 1000))
|
||||
@ -571,6 +571,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
|
||||
Miscellaneous.setDisplayLanguage(ActivityMainTabLayout.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
if(Settings.tabsPlacement == 1)
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
|
||||
@ -65,6 +65,7 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
|
||||
NfcReceiver.checkIntentForNFC(this, getIntent());
|
||||
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass()));
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageActionBrightnessSetting extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
setContentView(R.layout.activity_manage_action_brightness_settings);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
|
||||
|
@ -259,6 +259,7 @@ public class ActivityManageActionCloseNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_close_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
|
@ -19,6 +19,7 @@ public class ActivityManageActionControlMedia extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_control_media);
|
||||
|
||||
rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause);
|
||||
|
@ -19,6 +19,7 @@ public class ActivityManageActionCopyToClipboard extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_copy_to_clipboard);
|
||||
|
||||
bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard);
|
||||
|
@ -24,6 +24,7 @@ public class ActivityManageActionCreateNotification extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_create_notification);
|
||||
|
||||
etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle);
|
||||
|
@ -0,0 +1,75 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageActionLocationService extends Activity
|
||||
{
|
||||
RadioButton rbActionLocationServiceOff, rbActionLocationServiceSensorsOnly, rbActionLocationServiceBatterySaving, rbActionLocationServiceHighAccuracy;
|
||||
Button bActionSetLocationServiceSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_location_service);
|
||||
|
||||
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
|
||||
rbActionLocationServiceSensorsOnly = (RadioButton)findViewById(R.id.rbActionLocationServiceSensorsOnly);
|
||||
rbActionLocationServiceBatterySaving = (RadioButton)findViewById(R.id.rbActionLocationServiceBatterySaving);
|
||||
rbActionLocationServiceHighAccuracy = (RadioButton)findViewById(R.id.rbActionLocationServiceHighAccuracy);
|
||||
bActionSetLocationServiceSave = (Button) findViewById(R.id.bActionSetLocationServiceSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
int desiredState = Integer.parseInt(params[0]);
|
||||
|
||||
switch(desiredState)
|
||||
{
|
||||
case Settings.Secure.LOCATION_MODE_OFF:
|
||||
rbActionLocationServiceOff.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
rbActionLocationServiceSensorsOnly.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
rbActionLocationServiceBatterySaving.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
rbActionLocationServiceHighAccuracy.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bActionSetLocationServiceSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
if(rbActionLocationServiceOff.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_OFF));
|
||||
else if(rbActionLocationServiceSensorsOnly.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_SENSORS_ONLY));
|
||||
else if(rbActionLocationServiceBatterySaving.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_BATTERY_SAVING));
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ public class ActivityManageActionMakePhoneCall extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_make_phone_call);
|
||||
|
||||
etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber);
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageActionPlaySound extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_play_sound);
|
||||
|
||||
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
|
||||
|
@ -28,6 +28,7 @@ public class ActivityManageActionRunExecutable extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_run_executable);
|
||||
|
||||
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
|
||||
@ -57,6 +58,15 @@ public class ActivityManageActionRunExecutable extends Activity
|
||||
saveExecSettings();
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] parts = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
etRunExecutablePath.setText(parts[0]);
|
||||
|
||||
if(parts.length > 1)
|
||||
etRunExecutableParameters.setText(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void saveExecSettings()
|
||||
|
@ -37,6 +37,7 @@ public class ActivityManageActionSendBroadcast extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_send_broadcast);
|
||||
|
||||
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
|
||||
@ -235,8 +236,6 @@ public class ActivityManageActionSendBroadcast extends Activity
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_send_textmessage);
|
||||
|
||||
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
|
||||
|
@ -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;
|
||||
@ -24,6 +24,7 @@ public class ActivityManageActionSetVariable extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_set_variable);
|
||||
|
||||
etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey);
|
||||
|
@ -22,6 +22,7 @@ public class ActivityManageActionSpeakText extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_speak_text);
|
||||
|
||||
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
|
||||
|
@ -29,6 +29,7 @@ import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -48,17 +49,19 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
*/
|
||||
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath, etClassName;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
|
||||
Spinner spinnerParameterType;
|
||||
RadioGroup rgAppStartupType;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService;
|
||||
|
||||
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
|
||||
final static String startByActivityString = "0";
|
||||
final static String startByBroadcastString = "1";
|
||||
final static String startByServiceString = "2";
|
||||
public final static String startByActivityString = "0";
|
||||
public final static String startByBroadcastString = "1";
|
||||
public final static String startByServiceString = "2";
|
||||
public final static String startByForegroundServiceString = "3";
|
||||
|
||||
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
|
||||
|
||||
@ -66,11 +69,13 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
etClassName = (EditText)findViewById(R.id.etClassName);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
@ -83,13 +88,16 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
|
||||
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
|
||||
rbStartAppByService = (RadioButton)findViewById(R.id.rbStartAppByService);
|
||||
rbStartAppByForegroundService = (RadioButton)findViewById(R.id.rbStartAppByForegroundService);
|
||||
rgAppStartupType = (RadioGroup)findViewById(R.id.rgAppStartupType);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
etClassName.setEnabled(false);
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -226,23 +234,28 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
String parameter2 = "";
|
||||
|
||||
if (rbStartAppSelectByActivity.isChecked())
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
else {
|
||||
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
|
||||
{
|
||||
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 += Actions.dummyPackageString + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
|
||||
parameter2 += Action.actionParameter2Split + etClassName.getText().toString();
|
||||
}
|
||||
|
||||
if (rbStartAppByActivity.isChecked())
|
||||
parameter2 += ";" + startByActivityString;
|
||||
parameter2 += Action.actionParameter2Split + startByActivityString;
|
||||
else if(rbStartAppByService.isChecked())
|
||||
parameter2 += ";" + startByServiceString;
|
||||
parameter2 += Action.actionParameter2Split + startByServiceString;
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
parameter2 += Action.actionParameter2Split + startByForegroundServiceString;
|
||||
else
|
||||
parameter2 += ";" + startByBroadcastString;
|
||||
parameter2 += Action.actionParameter2Split + startByBroadcastString;
|
||||
|
||||
for (String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
parameter2 += Action.actionParameter2Split + s;
|
||||
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, parameter2);
|
||||
|
||||
@ -278,8 +291,6 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@ -289,8 +300,10 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
bSelectApp.setEnabled(isChecked);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rbStartAppSelectByAction.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
@ -303,6 +316,23 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
rgAppStartupType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int i)
|
||||
{
|
||||
if(rbStartAppByActivity.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if (rbStartAppByBroadcast.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if(rbStartAppByService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
loadValuesIntoGui(i);
|
||||
@ -595,11 +625,27 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
rbStartAppSelectByActivity.setChecked(!selectionByAction);
|
||||
rbStartAppSelectByAction.setChecked(selectionByAction);
|
||||
|
||||
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";");
|
||||
String[] params;
|
||||
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
|
||||
if(partsString.contains(Action.actionParameter2Split))
|
||||
params = partsString.split(Action.actionParameter2Split);
|
||||
else
|
||||
params = partsString.split(";");
|
||||
|
||||
if(Miscellaneous.isNumeric(params[2])) // old configuration file
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[2].equals(startByServiceString));
|
||||
}
|
||||
else
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[3].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[3].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[3].equals(startByServiceString));
|
||||
rbStartAppByForegroundService.setChecked(params[3].equals(startByForegroundServiceString));
|
||||
}
|
||||
|
||||
int startIndex = -1;
|
||||
|
||||
@ -614,10 +660,11 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
etPackageName.setText(params[0]);
|
||||
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
etClassName.setText(params[2]);
|
||||
}
|
||||
|
||||
if (params.length >= 3)
|
||||
startIndex = 3;
|
||||
if (params.length >= 4)
|
||||
startIndex = 4;
|
||||
|
||||
if(startIndex > -1 && params.length > startIndex)
|
||||
{
|
||||
|
@ -1,6 +1,10 @@
|
||||
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;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -13,32 +17,43 @@ import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
public class ActivityManageActionTriggerUrl extends Activity
|
||||
{
|
||||
Button bSaveTriggerUrl;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
|
||||
Button bSaveTriggerUrl, bAddHttpParam;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword, etParameterName, etParameterValue;
|
||||
ListView lvTriggerUrlPostParameters;
|
||||
CheckBox chkTriggerUrlUseAuthentication;
|
||||
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
|
||||
TableLayout tlTriggerUrlAuthentication;
|
||||
ArrayAdapter<String> httpParametersAdapter;
|
||||
|
||||
private ArrayList<String> httpParamsList = new ArrayList<>();
|
||||
ArrayAdapter<Map<String,String>> lvTriggerUrlPostParametersAdapter;
|
||||
|
||||
// private String existingUrl = "";
|
||||
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)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_trigger_url);
|
||||
|
||||
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
|
||||
@ -48,6 +63,32 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
|
||||
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
|
||||
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveSpeakText);
|
||||
rbTriggerUrlMethodGet = (RadioButton) findViewById(R.id.rbTriggerUrlMethodGet);
|
||||
rbTriggerUrlMethodPost = (RadioButton) findViewById(R.id.rbTriggerUrlMethodPost);
|
||||
etTriggerUrl = (EditText) findViewById(R.id.etTriggerUrl);
|
||||
etParameterName = (EditText) findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam);
|
||||
|
||||
etParameterName.setEnabled(false);
|
||||
etParameterValue.setEnabled(false);
|
||||
bAddHttpParam.setEnabled(false);
|
||||
|
||||
rbTriggerUrlMethodPost.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
etParameterName.setEnabled(checked);
|
||||
etParameterValue.setEnabled(checked);
|
||||
bAddHttpParam.setEnabled(checked);
|
||||
if(checked)
|
||||
lvTriggerUrlPostParameters.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList);
|
||||
|
||||
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -55,11 +96,9 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
{
|
||||
if(etTriggerUrl.getText().toString().length() > 0)
|
||||
{
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.triggerUrl);
|
||||
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
Intent returnIntent = new Intent();
|
||||
|
||||
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter1, chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
@ -70,29 +109,51 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString().trim()
|
||||
String method = methodGet;
|
||||
if(rbTriggerUrlMethodPost.isChecked())
|
||||
method = methodPost;
|
||||
|
||||
String httpParams = "";
|
||||
for (String s : httpParamsList)
|
||||
httpParams += Action.actionParameters2SeparatorOuter + s;
|
||||
if(httpParams.length() > 0)
|
||||
httpParams = httpParams.substring(Action.actionParameters2SeparatorOuter.length());
|
||||
|
||||
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter2,
|
||||
username + Action.actionParameter2Split +
|
||||
password + Action.actionParameter2Split +
|
||||
etTriggerUrl.getText().toString().trim() + Action.actionParameter2Split +
|
||||
method + Action.actionParameter2Split +
|
||||
httpParams
|
||||
);
|
||||
}
|
||||
backToRuleManager();
|
||||
|
||||
setResult(RESULT_OK, returnIntent);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.urlTooShort), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chkTriggerUrlUseAuthentication.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.VISIBLE);
|
||||
rbTriggerUrlMethodGet.setChecked(false);
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
rbTriggerUrlMethodGet.setEnabled(false);
|
||||
rbTriggerUrlMethodPost.setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.GONE);
|
||||
rbTriggerUrlMethodGet.setEnabled(true);
|
||||
rbTriggerUrlMethodPost.setEnabled(true);
|
||||
}
|
||||
|
||||
etTriggerUrlUsername.setEnabled(isChecked);
|
||||
etTriggerUrlPassword.setEnabled(isChecked);
|
||||
@ -109,50 +170,84 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
});
|
||||
updateListView();
|
||||
|
||||
|
||||
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
// username,password,URL
|
||||
String[] components = ActivityManageActionTriggerUrl.resultingAction.getParameter2().split(";");
|
||||
// username,password,URL,etc.
|
||||
String[] components;
|
||||
|
||||
if(getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).contains(Action.actionParameter2Split))
|
||||
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split, -1);
|
||||
else
|
||||
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";", -1);
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
etTriggerUrl.setText(components[2]);
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
|
||||
chkTriggerUrlUseAuthentication.setChecked(getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, false));
|
||||
etTriggerUrlUsername.setText(components[0]);
|
||||
etTriggerUrlPassword.setText(components[1]);
|
||||
|
||||
if(components.length >= 4)
|
||||
{
|
||||
switch(components[3])
|
||||
{
|
||||
case methodPost:
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
break;
|
||||
case methodGet:
|
||||
default:
|
||||
rbTriggerUrlMethodGet.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(components.length >= 5)
|
||||
{
|
||||
if(!StringUtils.isEmpty(components[4]) && components[4].contains(Action.actionParameters2SeparatorInner))
|
||||
{
|
||||
String httpParams[] = components[4].split(Action.actionParameters2SeparatorOuter);
|
||||
for (String paramPair : httpParams)
|
||||
httpParamsList.add(paramPair);
|
||||
|
||||
updateHttpParamsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
etTriggerUrl.setText(components[0]);
|
||||
}
|
||||
|
||||
bAddHttpParam.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(StringUtils.isEmpty(etParameterName.getText()) || StringUtils.isEmpty(etParameterValue.getText()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionTriggerUrl.this, getResources().getString(R.string.enterValidDataIntoParametersFields), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
httpParamsList.add(etParameterName.getText() + Action.actionParameters2SeparatorInner + etParameterValue.getText());
|
||||
|
||||
if(username == null)
|
||||
username = "";
|
||||
updateHttpParamsList();
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString()
|
||||
);
|
||||
if(lvTriggerUrlPostParameters.getVisibility() != View.VISIBLE)
|
||||
lvTriggerUrlPostParameters.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
||||
this.finish();
|
||||
lvTriggerUrlPostParameters.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getHttpParamsDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateListView()
|
||||
@ -168,4 +263,30 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
}
|
||||
|
||||
private void updateHttpParamsList()
|
||||
{
|
||||
if(lvTriggerUrlPostParameters.getAdapter() == null)
|
||||
lvTriggerUrlPostParameters.setAdapter(httpParametersAdapter);
|
||||
|
||||
httpParametersAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private AlertDialog getHttpParamsDialog(final int itemPosition)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageActionTriggerUrl.this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
|
||||
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// Only 1 choice at the moment, no need to check
|
||||
ActivityManageActionTriggerUrl.this.httpParamsList.remove(itemPosition);
|
||||
updateHttpParamsList();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
return alertDialog;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public class ActivityManageActionVibrate extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_vibrate);
|
||||
|
||||
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
|
||||
|
@ -27,6 +27,7 @@ public class ActivityManageActionWakeLock extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wakelock);
|
||||
|
||||
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
|
||||
|
@ -23,6 +23,7 @@ public class ActivityManageActionWifi extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wifi);
|
||||
|
||||
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
|
||||
|
@ -59,6 +59,7 @@ public class ActivityManagePoi extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_poi);
|
||||
|
||||
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
@ -410,22 +411,16 @@ public class ActivityManagePoi extends Activity
|
||||
@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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,22 +448,16 @@ public class ActivityManagePoi extends Activity
|
||||
@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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@ public class ActivityManageProfile extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_profile);
|
||||
|
||||
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
|
||||
|
@ -141,6 +141,10 @@ public class ActivityManageRule extends Activity
|
||||
final static int requestCodeTriggerCheckVariableEdit = 828;
|
||||
final static int requestCodeActionCopyTextToClipboardAdd = 829;
|
||||
final static int requestCodeActionCopyTextToClipboardEdit = 830;
|
||||
final static int requestCodeActionSetLocationServiceAdd = 831;
|
||||
final static int requestCodeActionSetLocationServiceEdit = 832;
|
||||
final static int requestCodeTriggerCalendarEventAdd = 833;
|
||||
final static int requestCodeTriggerCalendarEventEdit = 834;
|
||||
|
||||
public static ActivityManageRule getInstance()
|
||||
{
|
||||
@ -154,6 +158,7 @@ public class ActivityManageRule extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_specific_rule);
|
||||
|
||||
context = this;
|
||||
@ -344,6 +349,12 @@ public class ActivityManageRule extends Activity
|
||||
variableStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
|
||||
startActivityForResult(variableStateEditor, requestCodeTriggerCheckVariableEdit);
|
||||
break;
|
||||
case calendarEvent:
|
||||
Intent calendarStateEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerCalendar.class);
|
||||
calendarStateEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
|
||||
calendarStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
|
||||
startActivityForResult(calendarStateEditor, requestCodeTriggerCalendarEventEdit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -385,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:
|
||||
@ -477,6 +490,12 @@ public class ActivityManageRule extends Activity
|
||||
actionCopyToClipboardIntent.putExtra(intentNameActionParameter2, a.getParameter2());
|
||||
startActivityForResult(actionCopyToClipboardIntent, requestCodeActionCopyTextToClipboardEdit);
|
||||
break;
|
||||
case setLocationService:
|
||||
Intent actionSetLocationServiceIntent = new Intent(context, ActivityManageActionLocationService.class);
|
||||
// actionSetLocationServiceIntent.putExtra(intentNameActionParameter1, a.getParameter1());
|
||||
actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2());
|
||||
startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit);
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
|
||||
break;
|
||||
@ -627,6 +646,10 @@ public class ActivityManageRule extends Activity
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.router));
|
||||
else if(types[i].toString().equals(Trigger_Enum.subSystemState.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.subsystemstate));
|
||||
else if(types[i].toString().equals(Trigger_Enum.checkVariable.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
||||
else if(types[i].toString().equals(Trigger_Enum.calendarEvent.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.calendar));
|
||||
else
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
@ -635,15 +658,15 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
//User super class to create the View
|
||||
// User super class to create the View
|
||||
View v = super.getView(position, convertView, parent);
|
||||
|
||||
TextView tv = (TextView)v.findViewById(android.R.id.text1);
|
||||
|
||||
//Put the image on the TextView
|
||||
// Put the image on the TextView
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
|
||||
|
||||
//Add margin between image and text (support various screen densities)
|
||||
// Add margin between image and text (support various screen densities)
|
||||
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
|
||||
tv.setCompoundDrawablePadding(dp5);
|
||||
|
||||
@ -852,6 +875,13 @@ public class ActivityManageRule extends Activity
|
||||
startActivityForResult(variableTriggerEditor, requestCodeTriggerCheckVariableAdd);
|
||||
return;
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.calendarEvent)
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.calendarEvent);
|
||||
Intent calendarTriggerEditor = new Intent(myContext, ActivityManageTriggerCalendar.class);
|
||||
startActivityForResult(calendarTriggerEditor, requestCodeTriggerCalendarEventAdd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
getTriggerParameterDialog(context, booleanChoices).show();
|
||||
|
||||
@ -1354,9 +1384,11 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -1364,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();
|
||||
}
|
||||
}
|
||||
@ -1985,6 +2024,17 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerCalendarEventAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
|
||||
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
|
||||
newTrigger.setParentRule(ruleToEdit);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerTetheringEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
@ -2024,6 +2074,19 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerCalendarEventEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Trigger editedTrigger = new Trigger();
|
||||
editedTrigger.setTriggerType(Trigger_Enum.calendarEvent);
|
||||
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
|
||||
editedTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
|
||||
editedTrigger.setParentRule(ruleToEdit);
|
||||
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionCopyTextToClipboardAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
@ -2046,6 +2109,32 @@ public class ActivityManageRule extends Activity
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
}
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSetLocationServiceAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction.setParentRule(ruleToEdit);
|
||||
// newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
|
||||
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSetLocationServiceEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
|
||||
// ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
|
||||
|
||||
if(data.hasExtra(intentNameActionParameter2))
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
}
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
@ -2125,6 +2214,12 @@ public class ActivityManageRule extends Activity
|
||||
}
|
||||
else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.clipboard));
|
||||
else if(types[i].toString().equals(Action_Enum.takeScreenshot.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.copier));
|
||||
else if(types[i].toString().equals(Action_Enum.setVariable.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
||||
else if(types[i].toString().equals(Action_Enum.setLocationService.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.compass_small));
|
||||
else
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
@ -2161,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);
|
||||
}
|
||||
@ -2351,6 +2446,18 @@ public class ActivityManageRule extends Activity
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
|
||||
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.takeScreenshot.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.takeScreenshot);
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
refreshActionList();
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setLocationService.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setLocationService);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class);
|
||||
startActivityForResult(intent, requestCodeActionSetLocationServiceAdd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -32,6 +32,7 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_bluetooth);
|
||||
|
||||
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
|
||||
|
@ -28,6 +28,7 @@ public class ActivityManageTriggerBroadcast extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_broadcasts);
|
||||
|
||||
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
|
||||
|
@ -0,0 +1,404 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageTriggerCalendar extends Activity
|
||||
{
|
||||
CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent, chkCalendarEvaluateAllDayEvent, chkCalendarEvaluateReoccurring, chkCalendarReoccurring;
|
||||
Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection;
|
||||
EditText etCalendarTitle, etCalendarLocation, etCalendarDescription;
|
||||
LinearLayout llCalendarSelection;
|
||||
Button bSaveTriggerCalendar;
|
||||
List<CheckBox> checkboxesCalendars = new ArrayList<>();
|
||||
final static String separator = ",";
|
||||
TextView tvMissingCalendarHint;
|
||||
|
||||
private static String[] directions;
|
||||
ArrayAdapter<String> directionSpinnerAdapter;
|
||||
public static int requestCodePermissionReadCalendar = 815;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_calendar);
|
||||
|
||||
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
|
||||
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
|
||||
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);
|
||||
spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection);
|
||||
chkCalendarAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarAllDayEvent);
|
||||
chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy);
|
||||
chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree);
|
||||
chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative);
|
||||
chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice);
|
||||
chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere);
|
||||
chkCalendarEvaluateAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarEvaluateAllDayEvent);
|
||||
chkCalendarEvaluateReoccurring = (CheckBox)findViewById(R.id.chkCalendarEvaluateReoccurring);
|
||||
chkCalendarReoccurring = (CheckBox)findViewById(R.id.chkCalendarReoccurring);
|
||||
|
||||
tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint);
|
||||
|
||||
llCalendarSelection = (LinearLayout)findViewById(R.id.llCalendarSelection);
|
||||
|
||||
etCalendarTitle = (EditText)findViewById(R.id.etCalendarTitle);
|
||||
etCalendarLocation = (EditText)findViewById(R.id.etCalendarLocation);
|
||||
etCalendarDescription = (EditText)findViewById(R.id.etCalendarDescription);
|
||||
|
||||
bSaveTriggerCalendar = (Button)findViewById(R.id.bSaveTriggerCalendar);
|
||||
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringDoesNotContain),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
};
|
||||
directionSpinnerAdapter = new ArrayAdapter<>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageTriggerCalendar.directions);
|
||||
spinnerCalendarTitleDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarLocationDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter);
|
||||
directionSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
chkCalendarEvaluateAllDayEvent.setChecked(false);
|
||||
chkCalendarAllDayEvent.setEnabled(false);
|
||||
chkCalendarEvaluateAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
chkCalendarAllDayEvent.setEnabled(checked);
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarEvaluateReoccurring.setChecked(false);
|
||||
chkCalendarReoccurring.setEnabled(false);
|
||||
chkCalendarEvaluateReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
chkCalendarReoccurring.setEnabled(checked);
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this))
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerCalendar.this);
|
||||
builder.setTitle(getResources().getString(R.string.info));
|
||||
builder.setMessage(getResources().getString(R.string.permissionCalendarRequired));
|
||||
builder.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
ActivityManageTriggerCalendar.this.finish();
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
requestPermissions(new String[]{ Manifest.permission.READ_CALENDAR } , requestCodePermissionReadCalendar);
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
else
|
||||
populateCalenderCheckboxes();
|
||||
|
||||
chkCalendarEventActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyHappening);
|
||||
else
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyNotHappening);
|
||||
}
|
||||
});
|
||||
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarReoccurring.setText(R.string.reoccurringTrue);
|
||||
else
|
||||
chkCalendarReoccurring.setText(R.string.reoccurringFalse);
|
||||
}
|
||||
});
|
||||
|
||||
bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
String titleDir = Trigger.getMatchCode(spinnerCalendarTitleDirection.getSelectedItem().toString());
|
||||
String title = etCalendarTitle.getText().toString();
|
||||
String descriptionDir = Trigger.getMatchCode(spinnerCalendarDescriptionDirection.getSelectedItem().toString());
|
||||
String description = etCalendarDescription.getText().toString();
|
||||
String locationDir = Trigger.getMatchCode(spinnerCalendarLocationDirection.getSelectedItem().toString());
|
||||
String location = etCalendarLocation.getText().toString();
|
||||
|
||||
List<String> availabilityList = new ArrayList<>();
|
||||
if(chkCalendarAvailabilityBusy.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_BUSY));
|
||||
|
||||
if(chkCalendarAvailabilityFree.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_FREE));
|
||||
|
||||
if(chkCalendarAvailabilityTentative.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_TENTATIVE));
|
||||
|
||||
if(chkCalendarAvailabilityOutOfOffice.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE));
|
||||
|
||||
if(chkCalendarAvailabilityWorkingElsewhere.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE));
|
||||
|
||||
List<CalendarReceiver.AndroidCalendar> selectedCalendarsList = new ArrayList<>();
|
||||
for(CheckBox calCheckbox : checkboxesCalendars)
|
||||
{
|
||||
if(calCheckbox.isChecked())
|
||||
selectedCalendarsList.add((CalendarReceiver.AndroidCalendar) calCheckbox.getTag());
|
||||
}
|
||||
List<String> selectedCalendarsIdArray = new ArrayList<>();
|
||||
for(CalendarReceiver.AndroidCalendar cal : selectedCalendarsList)
|
||||
selectedCalendarsIdArray.add(String.valueOf(cal.calendarId));
|
||||
|
||||
String returnString =
|
||||
titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split +
|
||||
descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split +
|
||||
locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarEvaluateAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarEvaluateReoccurring.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarReoccurring.isChecked()) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()]));
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkCalendarEventActive.isChecked());
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, returnString);
|
||||
ActivityManageTriggerCalendar.this.setResult(RESULT_OK, data);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Intent inputIntent = getIntent();
|
||||
if(inputIntent.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
loadValuesIntoGui(inputIntent);
|
||||
}
|
||||
|
||||
private void populateCalenderCheckboxes()
|
||||
{
|
||||
List<CalendarReceiver.AndroidCalendar> calList = CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this);
|
||||
|
||||
if(calList != null)
|
||||
{
|
||||
if(calList.size() > 0)
|
||||
{
|
||||
for (CalendarReceiver.AndroidCalendar cal : calList)
|
||||
{
|
||||
CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this);
|
||||
oneCalCheckbox.setText(cal.toString());
|
||||
oneCalCheckbox.setTag(cal);
|
||||
llCalendarSelection.addView(oneCalCheckbox);
|
||||
checkboxesCalendars.add(oneCalCheckbox);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.noCalendarsOnYourDevice), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.errorReadingCalendars), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
|
||||
void loadValuesIntoGui(Intent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
chkCalendarEventActive.setChecked(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
|
||||
if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split, -1);
|
||||
/*
|
||||
0 = titleDir
|
||||
1 = title
|
||||
2 = descriptionDir
|
||||
3 = description
|
||||
4 = locationDir
|
||||
5 = location
|
||||
6 = evaluate all day event
|
||||
7 = all day event
|
||||
8 = evaluate reoccurring
|
||||
9 = reoccurring
|
||||
10 = availability list
|
||||
11 = calendars list
|
||||
*/
|
||||
|
||||
for (int i = 0; i < directions.length; i++)
|
||||
{
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[0]))
|
||||
spinnerCalendarTitleDirection.setSelection(i);
|
||||
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[2]))
|
||||
spinnerCalendarDescriptionDirection.setSelection(i);
|
||||
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[4]))
|
||||
spinnerCalendarLocationDirection.setSelection(i);
|
||||
}
|
||||
|
||||
etCalendarTitle.setText(input[1]);
|
||||
etCalendarDescription.setText(input[3]);
|
||||
etCalendarLocation.setText(input[5]);
|
||||
|
||||
chkCalendarEvaluateAllDayEvent.setChecked(Boolean.parseBoolean(input[6]));
|
||||
chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[7]));
|
||||
|
||||
chkCalendarEvaluateReoccurring.setChecked(Boolean.parseBoolean(input[8]));
|
||||
chkCalendarReoccurring.setChecked(Boolean.parseBoolean(input[9]));
|
||||
|
||||
String[] availabilities = null;
|
||||
if (!StringUtils.isEmpty(input[10]))
|
||||
availabilities = input[10].split(separator);
|
||||
|
||||
if (availabilities != null)
|
||||
{
|
||||
for (String avail : availabilities)
|
||||
{
|
||||
if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY)
|
||||
chkCalendarAvailabilityBusy.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_FREE)
|
||||
chkCalendarAvailabilityFree.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_TENTATIVE)
|
||||
chkCalendarAvailabilityTentative.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE)
|
||||
chkCalendarAvailabilityOutOfOffice.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE)
|
||||
chkCalendarAvailabilityWorkingElsewhere.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
String[] calendars = null;
|
||||
if (!StringUtils.isEmpty(input[11]))
|
||||
calendars = input[11].split(separator);
|
||||
|
||||
if (calendars != null)
|
||||
{
|
||||
List<String> usedCalendarIDs = new ArrayList<>();
|
||||
List<String> unusedCalendarIDs = new ArrayList<>();
|
||||
for (CheckBox checkbox : checkboxesCalendars)
|
||||
{
|
||||
int id = ((CalendarReceiver.AndroidCalendar) checkbox.getTag()).calendarId;
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (calId.equals(String.valueOf(id)))
|
||||
{
|
||||
usedCalendarIDs.add(String.valueOf(id));
|
||||
checkbox.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch((ArrayList<String>) usedCalendarIDs, calId, false, true))
|
||||
unusedCalendarIDs.add(calId);
|
||||
}
|
||||
if (unusedCalendarIDs.size() > 0)
|
||||
{
|
||||
/*
|
||||
A calendar has been configured that has been deleted since. We cannot resolve it.
|
||||
It will be removed with the next save, but we should inform this user
|
||||
of these circumstances.
|
||||
*/
|
||||
|
||||
tvMissingCalendarHint.setText(String.format(getResources().getString(R.string.calendarsMissingHint), Miscellaneous.explode(", ", (ArrayList<String>) unusedCalendarIDs)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActivityManagerTriggerCalender", "Error loading values into GUI: " + Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(ActivityManageTriggerCalendar.this, getResources().getString(R.string.errorLoadingValues), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
if(requestCode == requestCodePermissionReadCalendar)
|
||||
{
|
||||
if(
|
||||
permissions[0].equals(Manifest.permission.READ_CALENDAR)
|
||||
||
|
||||
permissions[0].equals(Manifest.permission.WRITE_CALENDAR)
|
||||
)
|
||||
{
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ public class ActivityManageTriggerCheckVariable extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_check_variable);
|
||||
|
||||
etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger);
|
||||
|
@ -104,6 +104,7 @@ public class ActivityManageTriggerDeviceOrientation extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_device_orientation);
|
||||
|
||||
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
|
||||
|
@ -39,6 +39,7 @@ public class ActivityManageTriggerNfc extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_nfc);
|
||||
|
||||
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
|
||||
|
@ -258,6 +258,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
|
@ -35,6 +35,7 @@ public class ActivityManageTriggerPhoneCall extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_phone_call);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
|
||||
|
@ -31,6 +31,7 @@ public class ActivityManageTriggerProfile extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_profile);
|
||||
|
||||
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile);
|
||||
|
@ -21,6 +21,7 @@ public class ActivityManageTriggerSubSystemState extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_subsystemstate);
|
||||
|
||||
rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi);
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageTriggerTethering extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_tethering);
|
||||
|
||||
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
|
||||
|
@ -35,6 +35,7 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_timeframe);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
|
@ -12,11 +12,15 @@ import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
@ -43,12 +47,13 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
List<String> wifiList = new ArrayList<>();
|
||||
ArrayAdapter<String> wifiSpinnerAdapter;
|
||||
private final static int requestCodeLocationPermission = 124;
|
||||
TextView tvWifiTriggerNameLocationNotice;
|
||||
TextView tvWifiTriggerNameLocationNotice, tvWifiTriggerDisconnectionHint;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_wifi);
|
||||
|
||||
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
|
||||
@ -58,6 +63,9 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
bTriggerWifiSave = (Button) findViewById(R.id.bTriggerWifiSave);
|
||||
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
|
||||
tvWifiTriggerNameLocationNotice = (TextView)findViewById(R.id.tvWifiTriggerNameLocationNotice);
|
||||
tvWifiTriggerDisconnectionHint = (TextView)findViewById(R.id.tvWifiTriggerDisconnectionHint);
|
||||
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
|
||||
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
|
||||
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
|
||||
@ -100,6 +108,11 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
etTriggerWifiName.setText(wifiList.get(position));
|
||||
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,6 +130,41 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
loadWifis();
|
||||
}
|
||||
});
|
||||
|
||||
rbTriggerWifiDisconnected.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && b)
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
etTriggerWifiName.addTextChangedListener(new TextWatcher()
|
||||
{
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadWifis()
|
||||
|
@ -18,6 +18,8 @@ import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
@ -51,12 +53,14 @@ public class ActivityPermissions extends Activity
|
||||
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
|
||||
private static final int requestCodeForPermissionNotificationAccessAndroid13 = 12049;
|
||||
private static final int requestCodeForPermissionsManageOverlay = 12050;
|
||||
private static final int requestCodeForPermissionsAccessibility = 12051;
|
||||
private static final int requestCodeForPermissionsScheduleExactAlarms = 12052;
|
||||
protected String[] specificPermissionsToRequest = null;
|
||||
|
||||
public static String intentExtraName = "permissionsToBeRequested";
|
||||
|
||||
Button bCancelPermissions, bRequestPermissions;
|
||||
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong;
|
||||
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong, tvRestrictionPermissionsNotice;
|
||||
static ActivityPermissions instance = null;
|
||||
|
||||
public final static String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
|
||||
@ -79,6 +83,7 @@ public class ActivityPermissions extends Activity
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.permissions_activity);
|
||||
|
||||
bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions);
|
||||
@ -86,6 +91,7 @@ public class ActivityPermissions extends Activity
|
||||
tvPermissionsExplanation = (TextView)findViewById(R.id.tvPermissionsExplanation);
|
||||
tvPermissionsExplanationSystemSettings = (TextView)findViewById(R.id.tvPermissionsExplanationSystemSettings);
|
||||
tvPermissionsExplanationLong = (TextView)findViewById(R.id.tvPermissionsExplanationLong);
|
||||
tvRestrictionPermissionsNotice = (TextView)findViewById(R.id.tvRestrictionPermissionsNotice);
|
||||
|
||||
bCancelPermissions.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@ -160,7 +166,7 @@ public class ActivityPermissions extends Activity
|
||||
/*
|
||||
Filter location permission and only name it once
|
||||
*/
|
||||
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) | s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
|
||||
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) || s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
|
||||
{
|
||||
if(!locationPermissionExplained)
|
||||
{
|
||||
@ -304,6 +310,10 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
return android.provider.Settings.canDrawOverlays(Miscellaneous.getAnyContext());
|
||||
}
|
||||
else if(s.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
return haveAccessibilityAccess(Miscellaneous.getAnyContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = context.checkCallingOrSelfPermission(s);
|
||||
@ -322,11 +332,59 @@ public class ActivityPermissions extends Activity
|
||||
return active;
|
||||
}
|
||||
|
||||
public static boolean haveAccessibilityAccess(Context mContext)
|
||||
{
|
||||
int accessibilityEnabled = 0;
|
||||
|
||||
final String service = mContext.getPackageName() + "/" + BuildConfig.APPLICATION_ID + ".MyAccessibilityService";
|
||||
|
||||
boolean accessibilityFound = false;
|
||||
try
|
||||
{
|
||||
accessibilityEnabled = Settings.Secure.getInt(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
// Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled);
|
||||
}
|
||||
catch (Settings.SettingNotFoundException e)
|
||||
{
|
||||
// Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage());
|
||||
}
|
||||
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
|
||||
|
||||
if (accessibilityEnabled == 1)
|
||||
{
|
||||
String settingValue = Settings.Secure.getString(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
if (settingValue != null)
|
||||
{
|
||||
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
|
||||
splitter.setString(settingValue);
|
||||
while (splitter.hasNext())
|
||||
{
|
||||
String accessibilityService = splitter.next();
|
||||
|
||||
if (accessibilityService.equalsIgnoreCase(service))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return accessibilityFound;
|
||||
}
|
||||
|
||||
public static void requestOverlay()
|
||||
{
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsManageOverlay);
|
||||
}
|
||||
|
||||
public static void requestBindAccessibilityService()
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsAccessibility);
|
||||
}
|
||||
|
||||
public static void requestDeviceAdmin()
|
||||
{
|
||||
if(!haveDeviceAdmin())
|
||||
@ -369,11 +427,20 @@ public class ActivityPermissions extends Activity
|
||||
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
|
||||
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
|
||||
|
||||
for(Profile p : Profile.getProfileCollection())
|
||||
if(Build.VERSION.SDK_INT >= 33 && BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
{
|
||||
if(p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
if (!havePermission(android.Manifest.permission.POST_NOTIFICATIONS, workingContext))
|
||||
addToArrayListUnique(android.Manifest.permission.POST_NOTIFICATIONS, requiredPermissions);
|
||||
}
|
||||
|
||||
if(!havePermission(Manifest.permission.READ_EXTERNAL_STORAGE, workingContext))
|
||||
{
|
||||
for (Profile p : Profile.getProfileCollection())
|
||||
{
|
||||
if (p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyGeneral)
|
||||
{
|
||||
@ -406,27 +473,6 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Not all permissions need to be asked for.
|
||||
*/
|
||||
|
||||
/*if(shouldShowRequestPermissionRationale("android.permission.RECORD_AUDIO"))
|
||||
Toast.makeText(ActivityMainScreen.this, "shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toast.makeText(ActivityMainScreen.this, "not shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();*/
|
||||
|
||||
// addToArrayListUnique("Manifest.permission.RECORD_AUDIO", requiredPermissions);
|
||||
/*int hasPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
|
||||
if (hasPermission == PackageManager.PERMISSION_DENIED)
|
||||
{
|
||||
Toast.makeText(ActivityMainScreen.this, "Don't have record_audio. Requesting...", Toast.LENGTH_LONG).show();
|
||||
// requestPermissions(new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
|
||||
ActivityCompat.requestPermissions(ActivityMainScreen.this, new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMainScreen.this, "Have record_audio.", Toast.LENGTH_LONG).show();*/
|
||||
|
||||
}
|
||||
|
||||
return requiredPermissions.toArray(new String[requiredPermissions.size()]);
|
||||
@ -455,6 +501,7 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
case activityDetection:
|
||||
addToArrayListUnique(permissionNameGoogleActivityDetection, requiredPermissions);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
addToArrayListUnique(Manifest.permission.ACTIVITY_RECOGNITION, requiredPermissions);
|
||||
break;
|
||||
case airplaneMode:
|
||||
@ -518,6 +565,8 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
|
||||
break;
|
||||
case timeFrame:
|
||||
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
|
||||
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
|
||||
break;
|
||||
case usb_host_connection:
|
||||
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
|
||||
@ -540,6 +589,11 @@ public class ActivityPermissions extends Activity
|
||||
case notification:
|
||||
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
|
||||
break;
|
||||
case calendarEvent:
|
||||
addToArrayListUnique(Manifest.permission.READ_CALENDAR, requiredPermissions);
|
||||
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
|
||||
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -648,7 +702,18 @@ public class ActivityPermissions extends Activity
|
||||
// )
|
||||
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
|
||||
if(Build.VERSION.SDK_INT >= 29)
|
||||
{
|
||||
String parts[];
|
||||
if(action.getParameter2().contains(Action.actionParameter2Split))
|
||||
parts = action.getParameter2().split(Action.actionParameter2Split);
|
||||
else
|
||||
parts = action.getParameter2().split(";");
|
||||
|
||||
// Permission only required for starts of activity, not broadcasts or services
|
||||
|
||||
if(parts[2].equals(ActivityManageActionStartActivity.startByActivityString))
|
||||
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
}
|
||||
break;
|
||||
case triggerUrl:
|
||||
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
|
||||
@ -704,11 +769,17 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case startPhoneCall:
|
||||
addToArrayListUnique(Manifest.permission.CALL_PHONE, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
break;
|
||||
case stopPhoneCall:
|
||||
addToArrayListUnique(Manifest.permission.ANSWER_PHONE_CALLS, requiredPermissions);
|
||||
break;
|
||||
case takeScreenshot:
|
||||
addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions);
|
||||
break;
|
||||
case setLocationService:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -771,14 +842,19 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.WRITE_EXTERNAL_STORAGE:
|
||||
usingElements.add(getResources().getString(R.string.storeSettings));
|
||||
break;
|
||||
case Manifest.permission.SCHEDULE_EXACT_ALARM:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.timeFrame))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.notification))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case permissionNameGoogleActivityDetection:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.closeNotification))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case permissionNameGoogleActivityDetection:
|
||||
case Manifest.permission.ACTIVITY_RECOGNITION:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
@ -909,6 +985,8 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.SYSTEM_ALERT_WINDOW:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.startOtherActivity))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.ANSWER_PHONE_CALLS:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.stopPhoneCall))
|
||||
@ -957,6 +1035,18 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.QUERY_ALL_PACKAGES:
|
||||
usingElements.add(getResources().getString(R.string.queryAllPackages));
|
||||
break;
|
||||
case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.takeScreenshot))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.WRITE_SECURE_SETTINGS:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.setLocationService))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.READ_CALENDAR:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
}
|
||||
|
||||
return usingElements;
|
||||
@ -965,6 +1055,15 @@ public class ActivityPermissions extends Activity
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
/*
|
||||
All of the following permissions need to be "manually" activated by the user in some
|
||||
buried system menu.
|
||||
In my opinion by mistake the function will be called when the user has just landed
|
||||
on one of those screens, not when he exits it again. To compensate for that onResume()
|
||||
is overridden. This enables the permission screen to automatically close after all
|
||||
required permissions have been granted.
|
||||
*/
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
@ -1012,6 +1111,14 @@ public class ActivityPermissions extends Activity
|
||||
if (requestCode == requestCodeForPermissionsManageOverlay)
|
||||
if(havePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsAccessibility)
|
||||
if(havePermission(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsScheduleExactAlarms)
|
||||
if(havePermission(Manifest.permission.SCHEDULE_EXACT_ALARM, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,10 +1178,14 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.noticeRestrictedPermissions), ActivityPermissions.this).show();
|
||||
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.SYSTEM_ALERT_WINDOW))
|
||||
@ -1093,6 +1204,22 @@ public class ActivityPermissions extends Activity
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.accessibilityApiPermissionHint), ActivityPermissions.this);
|
||||
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestBindAccessibilityService();
|
||||
}
|
||||
});
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= 33)
|
||||
@ -1119,6 +1246,22 @@ public class ActivityPermissions extends Activity
|
||||
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.SCHEDULE_EXACT_ALARM))
|
||||
{
|
||||
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.alarmsPermissionHint), ActivityPermissions.this);
|
||||
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestScheduleExactAlarms();
|
||||
}
|
||||
});
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if(s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
@ -1148,6 +1291,13 @@ public class ActivityPermissions extends Activity
|
||||
|
||||
return;
|
||||
}
|
||||
else if(s.equalsIgnoreCase(Manifest.permission.WRITE_SECURE_SETTINGS))
|
||||
{
|
||||
AlertDialog diaglog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.writeSecureSettingsNotice), ActivityPermissions.this);
|
||||
diaglog.show();
|
||||
Linkify.addLinks((TextView) diaglog.findViewById(android.R.id.message), Linkify.ALL);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1197,6 +1347,14 @@ public class ActivityPermissions extends Activity
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotifications);
|
||||
}
|
||||
|
||||
|
||||
void requestScheduleExactAlarms()
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
|
||||
startActivityForResult(intent, requestCodeForPermissionsScheduleExactAlarms);
|
||||
}
|
||||
|
||||
|
||||
protected void applyChanges()
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
@ -1575,4 +1733,47 @@ public class ActivityPermissions extends Activity
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 33 && BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
{
|
||||
for (String p : getRequiredPermissions(false))
|
||||
{
|
||||
if (p.equals(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE) || p.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
tvRestrictionPermissionsNotice.setText(getResources().getString(R.string.noticeRestrictedPermissions));
|
||||
|
||||
/*
|
||||
Opening the app's settings directly does not work because the
|
||||
mentioned 3 dots are only displayed when you went there the hard way.
|
||||
*/
|
||||
/*
|
||||
tvRestrictionPermissionsNotice.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
})*/;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String p : getRequiredPermissions(false))
|
||||
{
|
||||
if(!havePermission(p, this))
|
||||
return;
|
||||
}
|
||||
|
||||
// have all
|
||||
setHaveAllPermissions();
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ public class ActivitySettings extends PreferenceActivity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
addPreferencesFromResource(layout.activity_settings);
|
||||
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
@ -24,4 +25,11 @@ public class ActivitySettings extends PreferenceActivity
|
||||
chkPrefUpdateCheck.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ public class ActivityVolumeTest extends Activity
|
||||
instance = this;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_volume_calibration);
|
||||
|
||||
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
|
||||
@ -48,20 +49,15 @@ public class ActivityVolumeTest extends Activity
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||
boolean fromUser)
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
||||
{
|
||||
etReferenceValue.setText(String.valueOf(sbReferenceValue.getProgress()));
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AsyncTasks
|
||||
@ -23,7 +22,7 @@ public class AsyncTasks
|
||||
|
||||
try
|
||||
{
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null).trim();
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null, ActivityManageActionTriggerUrl.methodGet, null).trim();
|
||||
int latestVersion = Integer.parseInt(result);
|
||||
|
||||
// At this point the update check itself has already been successful.
|
||||
|
@ -12,8 +12,6 @@ import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
@ -22,7 +20,6 @@ import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnInitListener;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -31,6 +28,7 @@ import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.DateTimeListener;
|
||||
import com.jens.automation2.receivers.PackageReplacedReceiver;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
@ -39,7 +37,6 @@ import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class AutomationService extends Service implements OnInitListener
|
||||
@ -131,8 +128,19 @@ public class AutomationService extends Service implements OnInitListener
|
||||
// Store a reference to myself. Other classes often need a context or something, this can provide that.
|
||||
centralInstance = this;
|
||||
|
||||
/*
|
||||
This has been reported to throw a NullPointerException under
|
||||
rare circumstances. The root cause remains unknown.
|
||||
*/
|
||||
try
|
||||
{
|
||||
Miscellaneous.setDisplayLanguage(AutomationService.this);
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "setDisplayLanguage()", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
|
||||
{
|
||||
@ -227,6 +235,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
startUpRoutine();
|
||||
|
||||
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
|
||||
if(getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_MUTABLE);
|
||||
else
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
notificationBuilder = createServiceNotificationBuilder();
|
||||
|
||||
@ -310,6 +321,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
ReceiverCoordinator.applySettingsAndRules();
|
||||
|
||||
DateTimeListener.reloadAlarms();
|
||||
CalendarReceiver.armOrRearmTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -522,7 +534,12 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setContentTitle("Automation");
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
@ -530,7 +547,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
Notification defaultNotification = builder.build();
|
||||
|
||||
defaultNotification.icon = R.drawable.ic_launcher;
|
||||
defaultNotification.icon = R.drawable.crane;
|
||||
defaultNotification.when = System.currentTimeMillis();
|
||||
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
@ -577,7 +594,12 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
// builder.setContentText(textToDisplay);
|
||||
// builder.setSmallIcon(icon);
|
||||
@ -670,8 +692,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
@Override
|
||||
public void onInit(int status)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,16 +37,22 @@ import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
@ -69,7 +75,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@ -77,6 +85,8 @@ import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
@ -91,6 +101,7 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@ -110,6 +121,8 @@ import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
|
||||
public class Miscellaneous extends Service
|
||||
{
|
||||
protected static String writeableFolderStringCache = null;
|
||||
@ -117,7 +130,7 @@ public class Miscellaneous extends Service
|
||||
|
||||
public static final String lineSeparator = System.getProperty("line.separator");
|
||||
|
||||
public static String downloadURL(String url, String username, String password)
|
||||
public static String downloadURL(String url, String username, String password, String method, Map<String, String> httpParams)
|
||||
{
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
StringBuilder responseBody = new StringBuilder();
|
||||
@ -145,6 +158,26 @@ public class Miscellaneous extends Service
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty ("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
if(httpParams.size() > 0)
|
||||
{
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
|
||||
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
||||
|
||||
for(String key : httpParams.keySet())
|
||||
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
||||
|
||||
OutputStream os = connection.getOutputStream();
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
|
||||
writer.write(getQuery(paramPairs));
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
InputStream content = (InputStream)connection.getInputStream();
|
||||
BufferedReader in = new BufferedReader (new InputStreamReader (content));
|
||||
@ -171,12 +204,28 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
}
|
||||
|
||||
public static String downloadURLwithoutCertificateChecking(String url, String username, String password)
|
||||
private static String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException
|
||||
{
|
||||
// HttpClient httpclient = new DefaultHttpClient();
|
||||
// StringBuilder responseBody = new StringBuilder();
|
||||
boolean errorFound = false;
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean first = true;
|
||||
|
||||
for (NameValuePair pair : params)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
result.append("&");
|
||||
|
||||
result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
|
||||
result.append("=");
|
||||
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String downloadUrlWithoutCertificateChecking(String url, String username, String password, String method, Map<String, String> httpParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpParams params = new BasicHttpParams();
|
||||
@ -185,19 +234,36 @@ public class Miscellaneous extends Service
|
||||
HttpClient httpclient = new DefaultHttpClient(params);
|
||||
httpclient = Actions.getInsecureSslClient(httpclient);
|
||||
|
||||
HttpPost httppost = new HttpPost(url);
|
||||
HttpRequestBase httpRequest;
|
||||
if(
|
||||
method.equals(ActivityManageActionTriggerUrl.methodPost)
|
||||
||
|
||||
(username != null && password != null)
|
||||
||
|
||||
httpParams.size() > 0
|
||||
)
|
||||
httpRequest = new HttpPost(url);
|
||||
else
|
||||
httpRequest = new HttpGet(url);
|
||||
|
||||
// Add http simple authentication if specified
|
||||
if(username != null && password != null)
|
||||
{
|
||||
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
||||
// List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
|
||||
httppost.addHeader("Authorization", "Basic " + encodedCredentials);
|
||||
// nameValuePairs.add(new BasicNameValuePair("Authorization", "Basic " + encodedCredentials));
|
||||
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
|
||||
httpRequest.addHeader("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
if(httpParams.size() > 0)
|
||||
{
|
||||
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
||||
|
||||
for(String key : httpParams.keySet())
|
||||
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
||||
|
||||
((HttpPost)httpRequest).setEntity(new UrlEncodedFormEntity(paramPairs, "UTF-8"));
|
||||
}
|
||||
|
||||
HttpResponse response = httpclient.execute(httpRequest);
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (entity != null)
|
||||
{
|
||||
@ -208,7 +274,6 @@ public class Miscellaneous extends Service
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
||||
errorFound = true;
|
||||
return "httpError";
|
||||
}
|
||||
// finally
|
||||
@ -234,25 +299,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
|
||||
@ -289,7 +338,6 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
logCleanerRunning = true;
|
||||
|
||||
|
||||
long maxSizeInBytes = (long)Settings.logFileMaxSize * 1024 * 1024;
|
||||
|
||||
if(logFile.exists() && logFile.length() > (maxSizeInBytes))
|
||||
@ -692,7 +740,7 @@ public class Miscellaneous extends Service
|
||||
if(result.length() < 2)
|
||||
result = "0" + result;
|
||||
|
||||
source = source.replace("[s]", String.valueOf(cal.get(Calendar.SECOND)));
|
||||
source = source.replace("[s]", result);
|
||||
}
|
||||
|
||||
if(source.contains("[ms]"))
|
||||
@ -708,7 +756,7 @@ public class Miscellaneous extends Service
|
||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||
|
||||
if (notificationTitle != null && notificationTitle.length() > 0)
|
||||
source = source.replace("[notificationTitle]", notificationTitle);
|
||||
source = source.replace("[notificationTitle]", escapeStringForUrl(notificationTitle));
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationTitle]", "notificationTitle unknown");
|
||||
@ -729,7 +777,7 @@ public class Miscellaneous extends Service
|
||||
String notificationText = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if (notificationText != null && notificationText.length() > 0)
|
||||
source = source.replace("[notificationText]", notificationText);
|
||||
source = source.replace("[notificationText]", escapeStringForUrl(notificationText));
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationText]", "notificationText unknown");
|
||||
@ -743,6 +791,78 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_trigger_url_result]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_trigger_url_result]", AutomationService.getInstance().getVariableMap().get("last_trigger_url_result"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_trigger_url_result.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_run_executable_exit_code]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_run_executable_exit_code]", AutomationService.getInstance().getVariableMap().get("last_run_executable_exit_code"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_run_executable_exit_code.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_run_executable_output]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_run_executable_output]", AutomationService.getInstance().getVariableMap().get("last_run_executable_output"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_run_executable_output.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_calendar_title]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_calendar_title]", CalendarReceiver.getLastTriggeringEvent().title);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_calendar_title.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_calendar_description]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_calendar_description]", CalendarReceiver.getLastTriggeringEvent().description);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_calendar_description.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[last_calendar_location]"))
|
||||
{
|
||||
try
|
||||
{
|
||||
source = source.replace("[last_calendar_location]", CalendarReceiver.getLastTriggeringEvent().location);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_calendar_location.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
while(source.contains("[variable-"))
|
||||
{
|
||||
int pos1 = source.indexOf("[variable-");
|
||||
@ -760,7 +880,7 @@ public class Miscellaneous extends Service
|
||||
else
|
||||
replacement = "unknownVariable";
|
||||
|
||||
source = source.substring(0, pos1) + replacement + source.substring(pos2);
|
||||
source = source.substring(0, pos1) + escapeStringForUrl(replacement) + source.substring(pos2 +1);
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "URL after replace", source);
|
||||
@ -789,7 +909,7 @@ public class Miscellaneous extends Service
|
||||
alertDialog.setTitle(title);
|
||||
alertDialog.setMessage(message);
|
||||
|
||||
alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener()
|
||||
alertDialog.setPositiveButton(context.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int whichButton)
|
||||
{
|
||||
@ -825,9 +945,12 @@ public class Miscellaneous extends Service
|
||||
*/
|
||||
public static boolean isPhoneRooted()
|
||||
{
|
||||
// if(true)
|
||||
// return true;
|
||||
|
||||
try
|
||||
{
|
||||
return Shell.SU.available();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// get from build info
|
||||
String buildTags = Build.TAGS;
|
||||
if (buildTags != null && buildTags.contains("test-keys"))
|
||||
@ -856,6 +979,7 @@ public class Miscellaneous extends Service
|
||||
||
|
||||
canExecuteCommand("which su");
|
||||
}
|
||||
}
|
||||
|
||||
// executes a command on the system
|
||||
private static boolean canExecuteCommand(String command)
|
||||
@ -935,17 +1059,11 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
catch (KeyManagementException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "SSL", Log.getStackTraceString(e), 4);
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Miscellaneous.logEvent("e", "SSL", Log.getStackTraceString(e), 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1164,7 +1282,12 @@ public class Miscellaneous extends Service
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
else if(!notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
builder.setSmallIcon(R.drawable.info);
|
||||
|
||||
@ -2014,7 +2137,16 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
|
||||
{
|
||||
Locale myLocale = new Locale(Settings.displayLanguage);
|
||||
Locale myLocale;
|
||||
|
||||
if(Settings.displayLanguage.contains("_"))
|
||||
{
|
||||
String[] parts = Settings.displayLanguage.split("_");
|
||||
myLocale = new Locale(parts[0], parts[1]);
|
||||
}
|
||||
else
|
||||
myLocale = new Locale(Settings.displayLanguage);
|
||||
|
||||
Resources res = context.getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
Configuration conf = res.getConfiguration();
|
||||
@ -2025,4 +2157,34 @@ public class Miscellaneous extends Service
|
||||
//startActivity(refresh);
|
||||
}
|
||||
}
|
||||
|
||||
public static String escapeStringForUrl(String input)
|
||||
{
|
||||
String output;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
try
|
||||
{
|
||||
output = URLEncoder.encode(input, String.valueOf(StandardCharsets.UTF_8));
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "URLEncoder", "Error encoding string for URL. Leaving as it is. Error details: " + Log.getStackTraceString(e), 3);
|
||||
output = input;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = Uri.encode(input);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static String getCallingMethodName()
|
||||
{
|
||||
StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
|
||||
return callingFrame.getMethodName();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class MyAccessibilityService extends AccessibilityService
|
||||
{
|
||||
static MyAccessibilityService instance;
|
||||
|
||||
public static MyAccessibilityService getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
{
|
||||
instance = new MyAccessibilityService();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceConnected()
|
||||
{
|
||||
super.onServiceConnected();
|
||||
Miscellaneous.logEvent("i", "Accessibility service", "Service started.", 4);
|
||||
}
|
||||
}
|
@ -79,7 +79,7 @@ public class News
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
String newsUrl = "https://server47.de/automation/appNews.php";
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null, ActivityManageActionTriggerUrl.methodGet, null);
|
||||
|
||||
// Cache content to local storage
|
||||
if(Miscellaneous.writeStringToFile(filePath, newsContent))
|
||||
|
@ -694,22 +694,16 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
@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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||
import com.jens.automation2.location.CellLocationChangedReceiver;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.BroadcastListener;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.DateTimeListener;
|
||||
import com.jens.automation2.receivers.AutomationListenerInterface;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
@ -145,6 +146,7 @@ public class ReceiverCoordinator
|
||||
}
|
||||
|
||||
// startPhoneStateListener
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
@ -209,6 +211,9 @@ public class ReceiverCoordinator
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
|
||||
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
CalendarReceiver.startCalendarReceiver(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
public static void stopAllReceivers()
|
||||
@ -242,6 +247,7 @@ public class ReceiverCoordinator
|
||||
BluetoothReceiver.stopBluetoothReceiver();
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
CalendarReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -395,7 +401,7 @@ public class ReceiverCoordinator
|
||||
{
|
||||
if(!HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
if(HeadphoneJackListener.getInstance().haveAllPermission())
|
||||
HeadphoneJackListener.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
@ -404,7 +410,7 @@ public class ReceiverCoordinator
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
|
@ -149,56 +149,45 @@ public class Settings implements SharedPreferences
|
||||
@Override
|
||||
public Editor edit()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Map<String, ?> getAll()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean getBoolean(String arg0, boolean arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public float getFloat(String arg0, float arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getInt(String arg0, int arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public long getLong(String arg0, long arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public String getString(String arg0, String arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public static void readFromPersistentStorage(Context context)
|
||||
@ -619,7 +608,6 @@ public class Settings implements SharedPreferences
|
||||
@Override
|
||||
public Set<String> getStringSet(String arg0, Set<String> arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
import com.jens.automation2.receivers.BroadcastListener;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.DeviceOrientationListener;
|
||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
||||
@ -31,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Trigger
|
||||
@ -63,6 +65,7 @@ public class Trigger
|
||||
tethering,
|
||||
subSystemState,
|
||||
checkVariable,
|
||||
calendarEvent,
|
||||
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -123,6 +126,8 @@ public class Trigger
|
||||
return context.getResources().getString(R.string.subSystemState);
|
||||
case checkVariable:
|
||||
return context.getResources().getString(R.string.checkVariable);
|
||||
case calendarEvent:
|
||||
return context.getResources().getString(R.string.calendarEventCapital);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -247,11 +252,14 @@ public class Trigger
|
||||
case subSystemState:
|
||||
if(!checkSubSystemState())
|
||||
result = false;
|
||||
break;
|
||||
case checkVariable:
|
||||
if(!checkVariable())
|
||||
result = false;
|
||||
break;
|
||||
case calendarEvent:
|
||||
if(!checkCalendarEvent(false))
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -358,6 +366,14 @@ public class Trigger
|
||||
else
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5);
|
||||
|
||||
/*
|
||||
We can only get here through the startup routine of the main service.
|
||||
Because the notification did not come in at runtime, but was there
|
||||
before we started, w need to take a record of it.
|
||||
*/
|
||||
if(NotificationListener.getLastNotification() == null)
|
||||
NotificationListener.setLastNotification(sn);
|
||||
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
@ -609,6 +625,141 @@ public class Trigger
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkCalendarEvent(boolean ignoreActive)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
|
||||
|
||||
for(CalendarReceiver.CalendarEvent event : calendarEvents)
|
||||
{
|
||||
if(!checkCalendarEvent(event, ignoreActive))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// At this point none of the calendar items match this trigger
|
||||
|
||||
/*
|
||||
If trigger demands no calendar event and there is absolutely no future event,
|
||||
further criteria don't matter if there are no events to check.
|
||||
*/
|
||||
if(calendarEvents.size() == 0 && getTriggerParameter() == false)
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "checkCalendarEvent()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
|
||||
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(), true,false);
|
||||
|
||||
/*
|
||||
0 = titleDir
|
||||
1 = title
|
||||
2 = descriptionDir
|
||||
3 = description
|
||||
4 = locationDir
|
||||
5 = location
|
||||
6 = evaluate all day event
|
||||
7 = all day event
|
||||
8 = evaluate reoccurring
|
||||
9 = reoccurring
|
||||
10 = availability list
|
||||
11 = calendars list
|
||||
*/
|
||||
|
||||
boolean isActive = getTriggerParameter();
|
||||
if (!ignoreActive && isActive != event.isCurrentlyActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event.title + " 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 of event " + event.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 " + event.title + " 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 " + event.title + " does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(conditions[6]))
|
||||
{
|
||||
if (Boolean.parseBoolean(conditions[7]) != event.allDay)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "All day setting " + event.title + " does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(conditions[8]))
|
||||
{
|
||||
if (Boolean.parseBoolean(conditions[9]) != event.reoccurring)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Reoccurring setting " + event.title + " does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[10]))
|
||||
{
|
||||
String[] availabilities = conditions[10].split(ActivityManageTriggerCalendar.separator);
|
||||
if (availabilities.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Availability of event " + event.title + " does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[11]))
|
||||
{
|
||||
String[] calendars = conditions[11].split(ActivityManageTriggerCalendar.separator);
|
||||
if (calendars.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Calendar of event " + event.title + " does not match.", 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
@ -803,14 +954,30 @@ public class Trigger
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name specified, checking that.", this.getParentRule().getName()), 4);
|
||||
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
|
||||
if(WifiBroadcastReceiver.lastConnectedState) //when connected
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()),this.getParentRule().getName()), 3);
|
||||
if (!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), this.getParentRule().getName()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name matches. Rule will apply.", this.getParentRule().getName()), 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (
|
||||
!Settings.serviceStartDone
|
||||
||
|
||||
(!WifiBroadcastReceiver.getLastWifiSsidReal().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsidReal().matches(this.getTriggerParameter2()))))
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsidReal()), this.getParentRule().getName()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name matches. Rule will apply.", this.getParentRule().getName()), 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("No wifi name specified, any will do.", this.getParentRule().getName()), 4);
|
||||
}
|
||||
@ -932,13 +1099,13 @@ public class Trigger
|
||||
{
|
||||
if(!this.getTriggerParameter())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule %1$s doesn't apply. We're entering POI: " + this.getPointOfInterest().getName() + ", not leaving it.", getParentRule().getName()), 4);
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule \"%1$s\" doesn't apply. We're entering POI: " + this.getPointOfInterest().getName() + ", not leaving it.", getParentRule().getName()), 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule %1$s doesn't apply. This is " + activePoi.getName() + ", not " + this.getPointOfInterest().getName() + ".", getParentRule().getName()), 4);
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule \"%1$s\" doesn't apply. This is " + activePoi.getName() + ", not " + this.getPointOfInterest().getName() + ".", getParentRule().getName()), 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -964,7 +1131,7 @@ public class Trigger
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule %1$s doesn't apply. We're not at POI \"" + this.getPointOfInterest().getName() + "\".", getParentRule().getName()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule \"%1$s\" doesn't apply. We're not at POI \"" + this.getPointOfInterest().getName() + "\".", getParentRule().getName()), 3);
|
||||
return false;
|
||||
}
|
||||
// }
|
||||
@ -973,7 +1140,7 @@ public class Trigger
|
||||
{
|
||||
if(!this.getTriggerParameter())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule %1$s doesn't apply. We're at no POI. Rule specifies to be at anyone.", getParentRule().getName()), 5);
|
||||
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), String.format("Rule \"%1$s\" doesn't apply. We're at no POI. Rule specifies to be at anyone.", getParentRule().getName()), 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1797,6 +1964,55 @@ public class Trigger
|
||||
else
|
||||
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2));
|
||||
break;
|
||||
case calendarEvent:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent));
|
||||
|
||||
returnString.append(" (");
|
||||
|
||||
if(triggerParameter)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyHappening));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyNotHappening));
|
||||
|
||||
returnString.append( ", ");
|
||||
|
||||
String[] conditions = triggerParameter2.split(triggerParameter2Split, -1);
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[1]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.title) + " " + conditions[0] + " " + conditions[1] + ", ");
|
||||
if (!StringUtils.isEmpty(conditions[3]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.location) + " " + conditions[2] + " " + conditions[3] + ", ");
|
||||
if (!StringUtils.isEmpty(conditions[5]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", ");
|
||||
|
||||
if(Boolean.parseBoolean(conditions[6]))
|
||||
{
|
||||
if (Boolean.parseBoolean(conditions[7]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventTrue) + ", ");
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", ");
|
||||
}
|
||||
|
||||
if(Boolean.parseBoolean(conditions[8]))
|
||||
{
|
||||
if (Boolean.parseBoolean(conditions[9]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.reoccurringTrue) + ", ");
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.reoccurringFalse) + ", ");
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[10]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[10] + ", ");
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[11]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[11]);
|
||||
|
||||
if (returnString.toString().endsWith(", "))
|
||||
returnString.delete(returnString.length() - 2, returnString.length());
|
||||
|
||||
returnString.append(")");
|
||||
|
||||
break;
|
||||
default:
|
||||
returnString.append("error");
|
||||
break;
|
||||
|
@ -1286,20 +1286,24 @@ public class XmlFileInterface
|
||||
else
|
||||
newTag = tag.replace("/", Action.intentPairSeparator);
|
||||
|
||||
String[] newTagPieces = newTag.split(";");
|
||||
String[] newTagPieces = new String[0];
|
||||
if(newTag.contains(Action.actionParameter2Split))
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
else
|
||||
newTag.split(";");
|
||||
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeparator)))
|
||||
{
|
||||
newTag = Actions.dummyPackageString + ";" + newTag;
|
||||
newTagPieces = newTag.split(";");
|
||||
newTag = Actions.dummyPackageString + Action.actionParameter2Split + newTag;
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
}
|
||||
|
||||
if(newTagPieces.length < 3)
|
||||
newTag += ";" + ActivityManageActionStartActivity.startByActivityString;
|
||||
newTag += Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString;
|
||||
else if(newTagPieces.length >= 3)
|
||||
{
|
||||
if(newTagPieces[2].contains(Action.intentPairSeparator))
|
||||
newTag = newTagPieces[0] + ";" + newTagPieces[1] + ";" + ActivityManageActionStartActivity.startByActivityString + ";" + newTagPieces[2];
|
||||
newTag = newTagPieces[0] + Action.actionParameter2Split + newTagPieces[1] + Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString + Action.actionParameter2Split + newTagPieces[2];
|
||||
}
|
||||
|
||||
newAction.setParameter2(newTag);
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
|
||||
import com.jens.automation2.ActivityMainScreen;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.BuildConfig;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.PointOfInterest;
|
||||
import com.jens.automation2.R;
|
||||
@ -232,6 +233,7 @@ public class LocationProvider
|
||||
public void startLocationService()
|
||||
{
|
||||
// startPhoneStateListener
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(parentService); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
@ -400,12 +402,12 @@ public class LocationProvider
|
||||
Miscellaneous.logEvent("i", "LocationProvider", this.getParentService().getResources().getString(R.string.applyingSettingsAndRules), 3);
|
||||
|
||||
// *********** SETTING CHANGES ***********
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive())
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive() || Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting WifiReceiver because settings now allow to.", 4);
|
||||
WifiBroadcastReceiver.startWifiReceiver(this);
|
||||
}
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive())
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive() && !Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down WifiReceiver because settings forbid to.", 4);
|
||||
WifiBroadcastReceiver.stopWifiReceiver();
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.jens.automation2.location;
|
||||
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -18,6 +17,8 @@ import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Settings;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
@ -25,11 +26,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
public static LocationProvider parentLocationProvider;
|
||||
public static Boolean wasConnected = false;
|
||||
protected static String lastWifiSsid = "";
|
||||
protected static String lastWifiSsidReal = "";
|
||||
public static boolean lastConnectedState = false;
|
||||
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
|
||||
protected static WifiBroadcastReceiver wifiBrInstance;
|
||||
protected static IntentFilter wifiListenerIntentFilter;
|
||||
protected static boolean wifiListenerActive=false;
|
||||
protected static boolean wifiListenerActive = false;
|
||||
|
||||
final static String unknownSsidName = "<unknown ssid>";
|
||||
|
||||
public static String getLastWifiSsidReal()
|
||||
{
|
||||
return lastWifiSsidReal;
|
||||
}
|
||||
|
||||
public static String getLastWifiSsid()
|
||||
{
|
||||
@ -38,12 +47,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
|
||||
public static void setLastWifiSsid(String newWifiSsid)
|
||||
{
|
||||
// Remove double quotes that sometimes come
|
||||
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
|
||||
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
|
||||
|
||||
// If it's a real name, not an empty string, it's stored as the last ssid
|
||||
if(newWifiSsid.length() > 0)
|
||||
{
|
||||
if(!newWifiSsid.equals(unknownSsidName))
|
||||
WifiBroadcastReceiver.lastWifiSsidReal = lastWifiSsid;
|
||||
|
||||
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWifiListenerActive()
|
||||
{
|
||||
@ -60,23 +76,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
// int state = -1;
|
||||
if(!StringUtils.isEmpty(intent.getAction()))
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Received signal with action \""+ intent.getAction() + "\".", 4);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Received signal with empty action.", 4);
|
||||
|
||||
NetworkInfo myWifi = null;
|
||||
|
||||
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) // fired upon disconnection
|
||||
{
|
||||
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
|
||||
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));
|
||||
myWifi = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
|
||||
}
|
||||
|
||||
WifiManager myWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
|
||||
// ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
|
||||
// myWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
// myWifi = state
|
||||
// WifiInfo wifiInfo = myWifiManager.getConnectionInfo();
|
||||
|
||||
// SupplicantState supState = wifiInfo.getSupplicantState();
|
||||
|
||||
if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) // fired upon connection
|
||||
{
|
||||
@ -93,8 +105,8 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
CellLocationChangedReceiver.stopCellLocationChangedReceiver();
|
||||
|
||||
/*
|
||||
TODO: Every time the screen is turned on, we receiver a "wifi has been connected"-event.
|
||||
This is technically wrong and not really any changed to when the screen was off. It has
|
||||
TODO: Every time the screen is turned on, we receive a "wifi has been connected"-event.
|
||||
This is technically wrong and not really any change to when the screen was off. It has
|
||||
to be filtered.
|
||||
*/
|
||||
}
|
||||
@ -120,12 +132,12 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
}
|
||||
else if(!myWifi.isConnectedOrConnecting()) // really disconnected? because sometimes also fires on connect
|
||||
{
|
||||
if(wasConnected) // wir könnten einfach noch nicht daheim sein
|
||||
if(wasConnected) // we could simply not be home yet
|
||||
{
|
||||
try
|
||||
{
|
||||
wasConnected = false;
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", String.format(context.getResources().getString(R.string.disconnectedFromWifi), getLastWifiSsid()) + " Switching to CellLocationChangedReceiver.", 3);
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Disconnected from wifi \"" + getLastWifiSsid() + "\". Switching to CellLocationChangedReceiver.", 3);
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
lastConnectedState = false;
|
||||
@ -214,17 +226,16 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
if(wifiListenerActive)
|
||||
if (wifiListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Wifi Listener", "Stopping wifiListener", 4);
|
||||
wifiListenerActive = false;
|
||||
parentLocationProvider.getParentService().unregisterReceiver(wifiBrInstance);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Wifi Listener", "Error stopping wifiListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -134,10 +134,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
case BatteryManager.BATTERY_STATUS_FULL:
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
||||
this.actionDischarging(context);
|
||||
break;
|
||||
}
|
||||
@ -225,7 +226,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
usbHostConnected = true;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
|
||||
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||
@ -247,7 +248,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
usbHostConnected = false;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
|
||||
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
||||
|
@ -94,12 +94,13 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event.", 4);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event: " + action, 5);
|
||||
|
||||
BluetoothDevice bluetoothDevice = null;
|
||||
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) | action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) || action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -107,7 +108,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
connectedDevices.add(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothConnectionTo), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) | action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) || action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -115,7 +116,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
connectedDevices.remove(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDisconnectFrom), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) | action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) || action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
|
@ -52,10 +52,14 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
|
||||
{
|
||||
broadcastsCollection.add(new EventOccurrence(Calendar.getInstance(), intent.getAction()));
|
||||
|
||||
for(String key : intent.getExtras().keySet())
|
||||
Miscellaneous.logEvent("i", "Broadcast received", "Broadcast " + intent.getAction() + " received.", 4);
|
||||
if(intent.getExtras() != null && intent.getExtras().size() > 0)
|
||||
{
|
||||
for (String key : intent.getExtras().keySet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
|
@ -0,0 +1,659 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.CalendarContract;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
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;
|
||||
|
||||
public class CalendarReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
static CalendarReceiver calendarReceiverInstance = null;
|
||||
static boolean calendarReceiverActive = false;
|
||||
static IntentFilter calendarIntentFilter = null;
|
||||
private static Intent calendarIntent = null;
|
||||
|
||||
public static final int AVAILABILITY_OUT_OF_OFFICE = 4;
|
||||
public static final int AVAILABILITY_WORKING_ELSEWHERE = 5;
|
||||
public static final String calendarAlarmAction = "ALARM_FOR_CALENDAR";
|
||||
|
||||
static List<AndroidCalendar> calendarsCache = null;
|
||||
static List<CalendarEvent> calendarEventsCache = null;
|
||||
static List<CalendarEvent> calendarEventsReoccurringCache = null;
|
||||
|
||||
// To determine for which events which rules have been executed
|
||||
static List<RuleEventPair> calendarEventsUsed = new ArrayList<>();
|
||||
|
||||
static Timer timer = null;
|
||||
static TimerTask timerTask = null;
|
||||
static Calendar nextWakeup = null;
|
||||
static AlarmManager alarmManager = null;
|
||||
static boolean wakeupNeedsToBeScheduledOrRescheduled = false;
|
||||
|
||||
public static CalendarEvent getLastTriggeringEvent()
|
||||
{
|
||||
if(calendarEventsUsed.size() > 0)
|
||||
{
|
||||
return calendarEventsUsed.get(calendarEventsUsed.size() -1).event;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class RuleEventPair
|
||||
{
|
||||
Rule rule;
|
||||
CalendarEvent event;
|
||||
|
||||
public RuleEventPair(Rule rule, CalendarEvent event)
|
||||
{
|
||||
this.rule = rule;
|
||||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
return calendarReceiverInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Received " + intent.getAction(), 4);
|
||||
|
||||
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Clearing calendar caches.", 4);
|
||||
|
||||
clearCaches();
|
||||
|
||||
routineAtAlarm();
|
||||
}
|
||||
else if(intent.getAction().equalsIgnoreCase(calendarAlarmAction))
|
||||
{
|
||||
routineAtAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
static void checkForRules(Context context)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationServiceRef)
|
||||
{
|
||||
startCalendarReceiver(automationServiceRef);
|
||||
}
|
||||
|
||||
static void clearCaches()
|
||||
{
|
||||
calendarsCache = null;
|
||||
calendarEventsCache = null;
|
||||
calendarEventsReoccurringCache = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
if(calendarReceiverActive)
|
||||
{
|
||||
if(calendarReceiverInstance != null)
|
||||
{
|
||||
AutomationService.getInstance().unregisterReceiver(calendarReceiverInstance);
|
||||
calendarReceiverInstance = null;
|
||||
}
|
||||
|
||||
clearCaches();
|
||||
calendarEventsUsed.clear();
|
||||
|
||||
calendarReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return calendarReceiverActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[]{Trigger.Trigger_Enum.calendarEvent};
|
||||
}
|
||||
|
||||
public static class AndroidCalendar
|
||||
{
|
||||
public int calendarId;
|
||||
public String displayName;
|
||||
public String accountString;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return displayName + " (" + accountString + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static class CalendarEvent
|
||||
{
|
||||
public AndroidCalendar calendar;
|
||||
public int calendarId;
|
||||
public String eventId;
|
||||
public String title;
|
||||
public String description;
|
||||
public String location;
|
||||
public String availability;
|
||||
public Calendar start, end;
|
||||
public boolean allDay, reoccurring;
|
||||
|
||||
public boolean isCurrentlyActive()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
return now.getTimeInMillis() >= start.getTimeInMillis() && now.getTimeInMillis() < end.getTimeInMillis();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Title: " + title + ", location: " + location + ", description: " + description + ", start: " + Miscellaneous.formatDate(start.getTime()) + ", end: " + Miscellaneous.formatDate(end.getTime()) + ", is currently active: " + String.valueOf(isCurrentlyActive()) + ", all day: " + String.valueOf(allDay) + ", availability: " + availability;
|
||||
}
|
||||
|
||||
@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)
|
||||
{
|
||||
if(calendarsCache == null)
|
||||
{
|
||||
calendarsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/calendars"),
|
||||
|
||||
new String[]{ CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CalendarContract.Calendars.OWNER_ACCOUNT, },
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
AndroidCalendar calendar = new AndroidCalendar();
|
||||
calendar.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
calendar.displayName = cursor.getString(1);
|
||||
calendar.accountString = cursor.getString(2);
|
||||
|
||||
calendarsCache.add(calendar);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
return calendarsCache;
|
||||
}
|
||||
|
||||
public static List<CalendarEvent> readCalendarEvents(Context context, boolean includeReoccurring, boolean includePastEvents)
|
||||
{
|
||||
if(calendarEventsCache == null)
|
||||
{
|
||||
calendarEventsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/events"),
|
||||
new String[] {
|
||||
CalendarContract.Events.CALENDAR_ID,
|
||||
CalendarContract.Events._ID,
|
||||
CalendarContract.Events.TITLE,
|
||||
CalendarContract.Events.DESCRIPTION,
|
||||
CalendarContract.Events.ALL_DAY,
|
||||
CalendarContract.Events.DTSTART,
|
||||
CalendarContract.Events.DTEND,
|
||||
CalendarContract.Events.EVENT_LOCATION,
|
||||
CalendarContract.Events.AVAILABILITY
|
||||
},
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent event = new CalendarEvent();
|
||||
event.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
|
||||
for(AndroidCalendar cal : readCalendars(context))
|
||||
{
|
||||
if(cal.calendarId == event.calendarId)
|
||||
{
|
||||
event.calendar = cal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.eventId = cursor.getString(1);
|
||||
event.title = cursor.getString(2);
|
||||
event.description = cursor.getString(3);
|
||||
event.allDay = cursor.getString(4).equals("1");
|
||||
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
|
||||
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
|
||||
event.location = cursor.getString(7);
|
||||
event.availability = cursor.getString(8);
|
||||
event.reoccurring = false;
|
||||
|
||||
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
calendarEventsCache.add(event);
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
if(includeReoccurring && calendarEventsReoccurringCache == null)
|
||||
{
|
||||
calendarEventsReoccurringCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
Calendar queryStart, queryEnd;
|
||||
if(includePastEvents)
|
||||
queryStart = Miscellaneous.calendarFromLong(0);
|
||||
else
|
||||
queryStart = Calendar.getInstance();
|
||||
|
||||
queryEnd = Calendar.getInstance();
|
||||
queryEnd.add(Calendar.YEAR, 1);
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/instances/when/" + queryStart.getTimeInMillis() + "/" + queryEnd.getTimeInMillis()),
|
||||
new String[] {
|
||||
CalendarContract.Instances.CALENDAR_ID,
|
||||
CalendarContract.Instances._ID,
|
||||
CalendarContract.Instances.TITLE,
|
||||
CalendarContract.Instances.DESCRIPTION,
|
||||
CalendarContract.Instances.ALL_DAY,
|
||||
CalendarContract.Instances.BEGIN,
|
||||
CalendarContract.Instances.END,
|
||||
CalendarContract.Instances.EVENT_LOCATION,
|
||||
CalendarContract.Instances.AVAILABILITY
|
||||
},
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent event = new CalendarEvent();
|
||||
event.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
|
||||
for(AndroidCalendar cal : readCalendars(context))
|
||||
{
|
||||
if(cal.calendarId == event.calendarId)
|
||||
{
|
||||
event.calendar = cal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.eventId = cursor.getString(1);
|
||||
event.title = cursor.getString(2);
|
||||
event.description = cursor.getString(3);
|
||||
event.allDay = cursor.getString(4).equals("1");
|
||||
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
|
||||
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
|
||||
event.location = cursor.getString(7);
|
||||
event.availability = cursor.getString(8);
|
||||
event.reoccurring = true;
|
||||
|
||||
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
{
|
||||
// For the moment keeping separate records to some extent
|
||||
calendarEventsReoccurringCache.add(event);
|
||||
calendarEventsCache.add(event);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
return calendarEventsCache;
|
||||
}
|
||||
|
||||
protected static void routineAtAlarm()
|
||||
{
|
||||
checkForRules(Miscellaneous.getAnyContext());
|
||||
|
||||
// Set next timer
|
||||
calculateNextWakeup();
|
||||
armOrRearmTimer();
|
||||
}
|
||||
|
||||
public static void armOrRearmTimer()
|
||||
{
|
||||
PendingIntent pi = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (alarmManager == null)
|
||||
{
|
||||
alarmManager = (AlarmManager) Miscellaneous.getAnyContext().getSystemService(Context.ALARM_SERVICE);
|
||||
}
|
||||
|
||||
if(pi == null)
|
||||
{
|
||||
Intent intent = new Intent(Miscellaneous.getAnyContext(), CalendarReceiver.class);
|
||||
intent.setAction(calendarAlarmAction);
|
||||
pi = PendingIntent.getBroadcast(AutomationService.getInstance(), 0, intent, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timerTask = new TimerTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
routineAtAlarm();
|
||||
}
|
||||
};
|
||||
|
||||
if(timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
timer = new Timer();
|
||||
}
|
||||
|
||||
if(nextWakeup == null)
|
||||
{
|
||||
readCalendarEvents(Miscellaneous.getAnyContext(), true,false);
|
||||
calculateNextWakeup();
|
||||
}
|
||||
|
||||
// If it's now filled, go on
|
||||
if(nextWakeup != null && wakeupNeedsToBeScheduledOrRescheduled)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && alarmManager.canScheduleExactAlarms()))
|
||||
{
|
||||
try
|
||||
{
|
||||
alarmManager.cancel(pi);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
Miscellaneous.logEvent("i", "armOrRearmTimer()", "Scheduling wakeup for calendar at " + Miscellaneous.formatDate(nextWakeup.getTime()), 4);
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
wakeupNeedsToBeScheduledOrRescheduled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
timer.schedule(timerTask, nextWakeup.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateNextWakeup()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false);
|
||||
|
||||
if (events.size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
List<Long> wakeUpCandidatesList = new ArrayList<>();
|
||||
|
||||
for (CalendarEvent event : events)
|
||||
{
|
||||
for (Rule r : ruleCandidates)
|
||||
{
|
||||
for (Trigger t : r.getTriggerSet())
|
||||
{
|
||||
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(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.", 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.", 4);
|
||||
else
|
||||
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 (!wakeupNeedsToBeScheduledOrRescheduled)
|
||||
wakeupNeedsToBeScheduledOrRescheduled = 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.", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startCalendarReceiver(final 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");
|
||||
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
|
||||
}
|
||||
|
||||
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter);
|
||||
|
||||
calendarReceiverActive = true;
|
||||
|
||||
armOrRearmTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean mayRuleStillBeActivatedForPendingCalendarEvents(Rule rule)
|
||||
{
|
||||
for(RuleEventPair pair : calendarEventsUsed)
|
||||
Miscellaneous.logEvent("i", "mayRuleStillBeActivatedForPendingCalendarEvents()", "Existing pair of " + pair.rule.getName() + " and " + pair.event, 5);
|
||||
|
||||
for(CalendarEvent event : readCalendarEvents(Miscellaneous.getAnyContext(), true,false))
|
||||
{
|
||||
for(Trigger t : rule.getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent) && t.checkCalendarEvent(event, false))
|
||||
{
|
||||
if (!hasEventBeenUsedInRule(rule, event))
|
||||
{
|
||||
/*
|
||||
If there are multiple parallel calendar events and a rule has multiple
|
||||
triggers of type calendar event, we don't want the rule to fire only once.
|
||||
*/
|
||||
if(rule.getAmountOfTriggersForType(Trigger.Trigger_Enum.calendarEvent) == 1)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "mayRuleStillBeActivatedForPendingCalendarEvents()", "Rule " + rule.getName() + " has not been used in conjunction with event " + event, 4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasEventBeenUsedInRule(Rule rule, CalendarEvent event)
|
||||
{
|
||||
for (RuleEventPair executedPair : calendarEventsUsed)
|
||||
{
|
||||
if (executedPair.rule.equals(rule) && executedPair.event.equals(event))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<CalendarReceiver.CalendarEvent> getApplyingCalendarEvents(Rule rule)
|
||||
{
|
||||
List<CalendarReceiver.CalendarEvent> returnList = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
|
||||
|
||||
for(Trigger t : rule.getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
for (CalendarReceiver.CalendarEvent event : calendarEvents)
|
||||
{
|
||||
if (t.checkCalendarEvent(event, false))
|
||||
returnList.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "getApplyingCalendarEvents()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.BuildConfig;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.TimeFrame;
|
||||
@ -28,7 +29,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
||||
{
|
||||
private static AutomationService automationServiceRef;
|
||||
private static AlarmManager centralAlarmManagerInstance;
|
||||
private static boolean alarmListenerActive=false;
|
||||
private static boolean alarmListenerActive = false;
|
||||
private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>();
|
||||
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
|
||||
static PendingIntent alarmPendingIntent = null;
|
||||
@ -243,7 +244,15 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
||||
}
|
||||
|
||||
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
|
||||
|
||||
if(Miscellaneous.getAnyContext().getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
else
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
centralAlarmManagerInstance.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
else
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");
|
||||
@ -295,7 +304,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
|
||||
clearAlarms();
|
||||
centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
alarmListenerActive = false;
|
||||
}
|
||||
else
|
||||
|
@ -20,7 +20,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
private static boolean headsetConnected = false;
|
||||
private static int headphoneType = -1;
|
||||
|
||||
protected static boolean headphoneJackListenerActive=false;
|
||||
protected static boolean headphoneJackListenerActive = false;
|
||||
protected static IntentFilter headphoneJackListenerIntentFilter = null;
|
||||
protected static HeadphoneJackListener instance;
|
||||
|
||||
@ -108,7 +108,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
Miscellaneous.logEvent("e", "HeadsetJackListener", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,13 @@ package com.jens.automation2.receivers;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
@ -19,6 +19,7 @@ import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
// See here for reference: http://gmariotti.blogspot.com/2013/11/notificationlistenerservice-and-kitkat.html
|
||||
|
||||
@ -26,8 +27,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,13 +42,42 @@ 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 void setLastNotification(SimpleNotification notification)
|
||||
{
|
||||
lastNotification = notification;
|
||||
}
|
||||
public static SimpleNotification getLastNotification()
|
||||
{
|
||||
return lastNotification;
|
||||
}
|
||||
|
||||
// To determine for which notifications which rules have been executed
|
||||
static List<RuleNotificationPair> notificationUsed = new ArrayList<>();
|
||||
|
||||
public static class RuleNotificationPair
|
||||
{
|
||||
Rule rule;
|
||||
SimpleNotification notification;
|
||||
|
||||
public RuleNotificationPair(Rule rule, SimpleNotification sn)
|
||||
{
|
||||
this.rule = rule;
|
||||
this.notification = sn;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addUsedPair(RuleNotificationPair pair)
|
||||
{
|
||||
// Add pair only if it's not in the list already.
|
||||
for(RuleNotificationPair usedPair : notificationUsed)
|
||||
{
|
||||
if(usedPair.rule.equals(pair.rule) && usedPair.notification.equals(pair.notification))
|
||||
return;
|
||||
}
|
||||
|
||||
notificationUsed.add(pair);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
@ -215,6 +243,19 @@ public class NotificationListener extends NotificationListenerService// implemen
|
||||
", text='" + text + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj)
|
||||
{
|
||||
return
|
||||
this.publishTime.getTimeInMillis() == ((SimpleNotification)obj).publishTime.getTimeInMillis()
|
||||
&&
|
||||
this.app.equals(((SimpleNotification)obj).app)
|
||||
&&
|
||||
this.title.equals(((SimpleNotification)obj).title)
|
||||
&&
|
||||
this.text.equals(((SimpleNotification)obj).text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -235,7 +276,6 @@ public class NotificationListener extends NotificationListenerService// implemen
|
||||
cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
|
||||
else
|
||||
cancelNotification(sbn.getKey());
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
|
BIN
app/src/main/res/drawable-hdpi/calendar.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable-hdpi/copier.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-hdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable-hdpi/variable.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable-ldpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-mdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-v24/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-xhdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 3.7 KiB |
BIN
app/src/main/res/drawable/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
@ -180,6 +180,7 @@
|
||||
android:id="@+id/rbNotificationDismissSimple"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/simplyDismissNotification" />
|
||||
|
||||
<RadioButton
|
||||
|
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/actionSetLocationService"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiExplanation1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/wifiExplanation1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiExplanation2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/wifiExplanation2" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:stretchColumns="1"
|
||||
android:shrinkColumns="1" >
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="@dimen/default_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:text="@string/state" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceOff"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/off" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceSensorsOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_SENSOR_ONLY" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceBatterySaving"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_BATTERY_SAVING" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceHighAccuracy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_HIGH_ACCURACY" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bActionSetLocationServiceSave"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -61,6 +61,12 @@
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:text="@string/setVariableExplanation" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLegend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/urlLegend" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveVariable"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
|
@ -113,6 +113,7 @@
|
||||
android:text="@string/startAppStartType" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/rgAppStartupType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@ -135,6 +136,12 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/startAppByStartService" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbStartAppByForegroundService"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/startAppByStartForegroundService" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</TableRow>
|
||||
@ -187,6 +194,25 @@
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/className" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etClassName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
@ -267,7 +293,6 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentNfcIdValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/parameterName" />
|
||||
@ -304,19 +329,38 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addIntentValue" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:text="@string/intentParametersHint" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvIntentPairs"
|
||||
android:visibility="gone"
|
||||
android:layout_marginVertical="@dimen/activity_horizontal_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="115dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="25dp"
|
||||
android:text="@string/variablesOnlyForTypes" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLegend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/urlLegend" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvIntentPairs"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="115dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveActionStartOtherActivity"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -90,12 +90,115 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/method"
|
||||
android:layout_marginTop="@dimen/fab_margin"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbTriggerUrlMethodGet"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/methodGet" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbTriggerUrlMethodPost"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:text="@string/methodPost" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:stretchColumns="1"
|
||||
android:shrinkColumns="1" >
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/addParameters" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/parameterName" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etParameterName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/parameterValue" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etParameterValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvHttpParams"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="115dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bAddHttpParam"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addParameters" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvTriggerUrlPostParameters"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
</ListView>
|
||||
android:layout_height="115dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
@ -109,6 +212,12 @@
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/triggerUrlVariableHint" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveSpeakText"
|
||||
android:layout_marginTop="15dp"
|
||||
|
368
app/src/main/res/layout/activity_manage_trigger_calendar.xml
Normal file
@ -0,0 +1,368 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarEventCapital"
|
||||
android:textSize="25dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarTriggerExecutionHints"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectingNoneItemForAllToMatch"/>
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/direction"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarEventActive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/eventIsCurrentlyHappening"
|
||||
android:checked="true"/>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/comparisonCaseInsensitive"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/regularExpressionsIfEquals"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<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/title" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarTitleDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</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/location" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarLocationDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarLocation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</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/calendarDescription" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarDescriptionDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarEvaluateAllDayEvent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/evaluate"
|
||||
android:checked="false"/>
|
||||
|
||||
<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:text="@string/allDayEventFalse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarEvaluateReoccurring"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/evaluate"
|
||||
android:checked="false"/>
|
||||
|
||||
<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/reoccurring" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarReoccurring"
|
||||
android:checked="false"
|
||||
android:text="@string/reoccurringFalse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/selectingNoneItemForAllToMatch" />
|
||||
|
||||
<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/availability" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityBusy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringBusy" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityFree"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringFree" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityTentative"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringTentative" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityOutOfOffice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringOutOfOffice" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityWorkingElsewhere"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringWorkingElsewhere" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/calendarAvailabilityTypesUnsupported" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/selectingNoneItemForAllToMatch" />
|
||||
|
||||
<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/calendars" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llCalendarSelection"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMissingCalendarHint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerCalendar"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -103,6 +103,14 @@
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiTriggerDisconnectionHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:textColor="@color/red"
|
||||
android:text="@string/wifiTriggerDisconnectionHint" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bTriggerWifiSave"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
|
@ -66,6 +66,12 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRestrictionPermissionsNotice"
|
||||
android:textColor="@color/red"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -65,7 +65,7 @@
|
||||
<string name="end">Ende</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="urlToTrigger">URL, die ausgelöst werden soll:</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (< Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (< Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[last_triggerurl_result] - Das Ergebnis der letzten Ausführung der triggerUrl-Aktion\n[last_run_executable_exit_code] - Der exit code der letzten starte-Programm Aktion\n[last_run_executable_output] - Die Ausgabe der letzten starte-Programm Aktion (nur für nicht-root)\n[last_calendar_title] - Titel des letzten Regel-auslösenden Kalendertermins\n[last_calendar_description] - Beschreibung des letzten Regel-auslösenden Kalendertermins\n[last_calendar_location] - Ort des letzten Regel-auslösenden Kalendertermins\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
|
||||
<string name="wifi">WLAN</string>
|
||||
<string name="activating">Aktiviere</string>
|
||||
<string name="deactivating">Deaktiviere</string>
|
||||
@ -602,7 +602,7 @@
|
||||
<string name="tabsPlacement">Position der Tableiste</string>
|
||||
<string name="top">Oben</string>
|
||||
<string name="bottom">Unten</string>
|
||||
<string name="tabsPlacementSummary">Wol soll die Taskleiste angezeigt werden?</string>
|
||||
<string name="tabsPlacementSummary">Wo soll die Taskleiste angezeigt werden?</string>
|
||||
<string name="tones">Klingeltöne</string>
|
||||
<string name="miscellaneous">Verschiedenes</string>
|
||||
<string name="dnd">Nicht stören</string>
|
||||
@ -795,5 +795,57 @@
|
||||
<string name="textToCopy">Text, der kopiert werden soll</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Über anderen Anwendungen anzeigen</string>
|
||||
<string name="overlayPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automation aus und erlauben Sie die Anzeige über anderen Apps.</string>
|
||||
<string name="overlayPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automatisierung aus und lassen Sie das Zeichnen über andere Apps zu.</string>
|
||||
<string name="variablesOnlyForTypes">Variablen sind nur für die Parametertypen String und URI verfügbar</string>
|
||||
<string name="intentParametersHint">Wenn Sie einen Parameter angeben möchten, müssen Sie auch auf \"Intent-Paar hinzufügen\" klicken. Andernfalls werden Ihre Änderungen nicht gespeichert.</string>
|
||||
<string name="languagePolish">Polnisch</string>
|
||||
<string name="languageChineseChina">Chinesisch (China)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Dieser Auslöser ist gültig, wenn Sie gerade die Verbindung zu dem oben angegebenen WLAN getrennt haben ODER während der Dienst noch gestartet wird und wenn Sie mit keinem WLAN verbunden sind. Wenn Sie möchten, dass der Auslöser nur ausgelöst wird, wenn Sie die Verbindung zu einem bestimmten WLAN explizit trennen, fügen Sie einen weiteren Auslöser hinzu: \"Der Dienst wird nicht gestartet\".</string>
|
||||
<string name="className">Klassenname</string>
|
||||
<string name="startAppByStartForegroundService">per startForegroundService()</string>
|
||||
<string name="method">Methode</string>
|
||||
<string name="takeScreenshot">Screenshot erstellen</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">An den Barrierefreiheitsdienst anbinden</string>
|
||||
<string name="bindAccessibilityService">An den Barrierefreiheitsdienst anbinden</string>
|
||||
<string name="accessibilityApiPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automatisierung aus und erlauben Sie die Barrierefreiheits-API.</string>
|
||||
<string name="accessibility_service_explanation">Erforderlich für bestimmte Aktionen.</string>
|
||||
<string name="noticeRestrictedPermissions">Wenn Sie eine der folgenden Berechtigungen nicht erteilen und eine Systemmeldung wie \"Eingeschränkte Berechtigung\" erhalten, müssen Sie zuerst zu den Android-Einstellungen und dann zu den Anwendungen gehen und Automatisierung auswählen. Nun sollten sich 3 Punkte in der oberen rechten Ecke befinden. Klicken Sie auf \"Eingeschränkte Einstellungen zulassen\". Danach sollte die erforderliche Erlaubnis erteilt werden können. Dies sollte nur für die APK-Version der App gelten, nicht für die von F-Droid oder dem Play Store.</string>
|
||||
<string name="setLocationService">Ortungsdienst festlegen</string>
|
||||
<string name="setLocationServiceCapital">Ortungsdienst einstellen</string>
|
||||
<string name="writeSecureSettingsNotice">Leider kann die Erlaubnis WRITE_SECURE_SETTINGS nicht direkt auf Ihrem Android-Gerät erteilt werden. Stattdessen müssen Sie Ihr Gerät an einen Computer anschließen und die Berechtigung über ADB erteilen. Klicken Sie hier, um zu erfahren, wie Sie es gewähren können: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Ortungsdienst</string>
|
||||
<string name="triggerUrlVariableHint">Das Ergebnis dieser Anfrage wird in der Variablen LAST_TRIGGERURL_RESULT gespeichert, wenn Sie es von einer anderen Regel aus überprüfen möchten. Im Falle von HTTP-Fehlern wie 404 ist der Wert \"HTTP_ERROR\".</string>
|
||||
<string name="calendarEvent">Kalendertermin</string>
|
||||
<string name="eventIsCurrentlyHappening">Termin ist derzeit aktiv</string>
|
||||
<string name="calendarEventCapital">Kalendertermin</string>
|
||||
<string name="location">Ort</string>
|
||||
<string name="calendarDescription">Beschreibung/Anmerkungen</string>
|
||||
<string name="availability">Verfügbarkeit</string>
|
||||
<string name="eventIsCurrentlyNotHappening">Termin findet derzeit nicht statt/ist beendet</string>
|
||||
<string name="calendarStringBusy">beschäftigt</string>
|
||||
<string name="calendarStringFree">frei</string>
|
||||
<string name="calendarStringTentative">vorbehaltlich</string>
|
||||
<string name="calendarStringOutOfOffice">nicht im Büro</string>
|
||||
<string name="calendarStringWorkingElsewhere">Anderswo arbeiten</string>
|
||||
<string name="selectingNoneItemForAllToMatch">Wenn Sie kein Element auswählen, ist jedes Element in Ordnung.</string>
|
||||
<string name="calendars">Kalender</string>
|
||||
<string name="calendarAvailabilityTypesUnsupported">Es kann sein, dass nur die ersten 3 Typen tatsächlich funktionieren, weil die anderen Typen nicht Teil der Standard-Kalenderoberfläche von Android sind.</string>
|
||||
<string name="anyCalendar">beliebiger Kalender</string>
|
||||
<string name="availabilities">Verfügbarkeiten</string>
|
||||
<string name="calendarsMissingHint">In diesem Trigger wurden zuvor Kalender mit der ID %1$s konfiguriert, aber seitdem gelöscht. Beim nächsten Speichern werden diese aus diesem Trigger entfernt. Bis dahin wird dieser Auslöser/diese Bedingung niemals erfüllt sein.</string>
|
||||
<string name="account">Konto</string>
|
||||
<string name="allDayEvent">Ganztägige Veranstaltung</string>
|
||||
<string name="allDayEventTrue">Die Veranstaltung ist eine ganztägige Veranstaltung</string>
|
||||
<string name="allDayEventFalse">Die Veranstaltung ist keine ganztägige Veranstaltung</string>
|
||||
<string name="permissionCalendarRequired">Die Berechtigung zum Lesen Ihres Kalenders ist für einen Kalenderauslöser erforderlich. Es ist bereits erforderlich, die Kalenderfelder in diesem Fenster auszufüllen.</string>
|
||||
<string name="noCalendarsOnYourDevice">Es scheint, als ob auf Ihrem Gerät keine Kalender eingerichtet wurden. Sie können diesen Trigger speichern, aber er wird nie true zurückgeben.</string>
|
||||
<string name="errorReadingCalendars">Beim Lesen der Kalender auf Ihrem Gerät ist ein Fehler aufgetreten.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Exakte Alarme setzen</string>
|
||||
<string name="alarmsPermissionHint">Nach dem Klick auf OK öffnet sich ein Fenster. Bitte wählen Sie dort Automatisierung aus und erlauben Sie der App, exakte Alarme zu planen.</string>
|
||||
<string name="evaluate">Auswerten</string>
|
||||
<string name="errorLoadingValues">Beim Laden von Werten ist ein Fehler aufgetreten.</string>
|
||||
<string name="enterValidDataIntoParametersFields">Geben Sie gültige Daten in die Parameterfelder ein.</string>
|
||||
<string name="reoccurringFalse">Ereignis ist nicht wiederkehrend</string>
|
||||
<string name="reoccurringTrue">Ereignis ist wiederkehrend</string>
|
||||
<string name="reoccurring">wiederkehrend</string>
|
||||
<string name="calendarTriggerExecutionHints">Wenn Ihr Kalender mehrere parallele, überlappende oder direkt aufeinanderfolgende Ereignisse enthält, wird eine Regel so oft ausgeführt, wie es Ereignisse gibt, die den Kriterien der Regel entsprechen. Falls eine Regel mehrere Kalenderauslöser hat und mehrere übereinstimmende Ereignisse parallel vorhanden sind, wird die Regel nur einmal ausgeführt.</string>
|
||||
</resources>
|
@ -8,9 +8,9 @@
|
||||
<string name="languageDutch">Holandés</string>
|
||||
<string name="languageRussian">Ruso</string>
|
||||
<string name="languageFrench">Francés</string>
|
||||
<string name="ruleActivate">Estoy activando regla %1$s</string>
|
||||
<string name="profileActivate">Estoy activando perfil %1$s</string>
|
||||
<string name="ruleActivateToggle">Estoy activando regla %1$s en el modo de invertir</string>
|
||||
<string name="ruleActivate">Activando regla %1$s</string>
|
||||
<string name="profileActivate">Activando perfil %1$s</string>
|
||||
<string name="ruleActivateToggle">Activando regla %1$s en el modo de invertir</string>
|
||||
<string name="addPoi">Crear sitio</string>
|
||||
<string name="addRule">Crear regla</string>
|
||||
<string name="poiList">Lista de sitios:</string>
|
||||
@ -43,7 +43,7 @@
|
||||
<string name="enterAname">Inserte un nombre.</string>
|
||||
<string name="username">Nombre de usuario</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="continueText">continuar</string>
|
||||
<string name="continueText">Continuar</string>
|
||||
<string name="rule">Regla</string>
|
||||
<string name="android.permission.SEND_SMS">Enviar mensajes SMS</string>
|
||||
<string name="android.permission.READ_CONTACTS">Leer directorio</string>
|
||||
@ -127,7 +127,7 @@
|
||||
<string name="actionTurnWifiOn">encender wifi</string>
|
||||
<string name="actionTurnWifiOff">desactivar wifi</string>
|
||||
<string name="actionTurnBluetoothOff">desactivar Bluetooth</string>
|
||||
<string name="actionTriggerUrl">Abrir URL en antecedentes</string>
|
||||
<string name="actionTriggerUrl">Abrir URL en el fondo</string>
|
||||
<string name="actionChangeSoundProfile">Cambiar perfil sonido</string>
|
||||
<string name="actionTurnUsbTetheringOn">encender enrutador USB</string>
|
||||
<string name="actionTurnUsbTetheringOff">desactivar enrutador USB</string>
|
||||
@ -197,7 +197,7 @@
|
||||
<string name="android.permission.RECORD_AUDIO">Grabar audio</string>
|
||||
<string name="android.permission.PROCESS_OUTGOING_CALLS">Detectar llamadas salientes</string>
|
||||
<string name="android.permission.READ_PHONE_STATE">Detectar el estado del dispositivo</string>
|
||||
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer la almacenamiento</string>
|
||||
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer el almacenamiento</string>
|
||||
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Escribir en el almacenamiento</string>
|
||||
<string name="android.permission.WRITE_SETTINGS">Modificar la configuración del dispositivo</string>
|
||||
<string name="android.permission.BATTERY_STATS">Determinar el estado de la bateria</string>
|
||||
@ -367,7 +367,7 @@
|
||||
<string name="networkAccuracy">Red exactitud [m]</string>
|
||||
<string name="minimumTimeForLocationUpdates">Tiempo mínimo para cambio en milisegundos para actualizar posición</string>
|
||||
<string name="timeForUpdate">Tiempo para actualizar [milisegundos]</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (< Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[variable-VARIABLENAME] - El valor de la variable definida personalizada</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (< Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[last_triggerurl_result] - El resultado de la última ejecución de la acción triggerUrl\n[last_run_executable_exit_code] - El código de salida de la última acción ejecutable ejecutada\n[last_run_executable_output] - El resultado de la última acción ejecutable ejecutada (solo para no root)Titel des letzten Regel-auslösenden Kalendertermins\n[last_calendar_title] - Título de la ultima cita en el calendar que ejecutó una regla\n[last_calendar_description] - Descriptión de la ultima cita en el calendar que ejecutó una regla\n[last_calendar_location] - Ubicación de la ultima cita en el calendar que ejecutó una regla\n[variable-VARIABLENAME] - El valor de la variable definida personalizada</string>
|
||||
<string name="screenRotationAlreadyEnabled">Rotación del monitor todavia esta activado.</string>
|
||||
<string name="screenRotationAlreadyDisabled">Rotación del monitor todavia esta desactivado.</string>
|
||||
<string name="needLocationPermForWifiList">Se puede usar la lista de wifis conocidos para determinar los sitios en los cuales estuvo. Por eso el permiso de localización es necesario para cargar la lista de wifis. Si quiere elegir uno de la lista tiene que conceder el permiso. En caso contrario todavia puede introducir un nombre wifi manualmente.</string>
|
||||
@ -765,7 +765,7 @@
|
||||
<string name="startPhoneCall">Llamar al número de teléfono</string>
|
||||
<string name="android.permission.CALL_PHONE">Llamar al número de teléfono</string>
|
||||
<string name="makePhoneCallExplanation1">Aquí puede ingresar un número de teléfono al que se llamará sin más indicaciones. Puede usar esto para realizar configuraciones como realizar ajustes en el enrutamiento de llamadas, etc. Por favor, busque los códigos necesarios para esto por su cuenta.</string>
|
||||
<string name="endPhoneCall">Terminar llamda de teléfono</string>
|
||||
<string name="endPhoneCall">Terminar llamada de teléfono</string>
|
||||
<string name="android.permission.ANSWER_PHONE_CALLS">Terminar llamda de teléfono</string>
|
||||
<string name="settingsReferringToRestrictedFeaturesInGoogle">La configuración y/o las reglas hacen referencia a funciones que no se pueden proporcionar en la versión de Google Play. Entre otras cosas que incluye todo lo relacionado con llamadas telefónicas y mensajes de texto.</string>
|
||||
<string name="variableCheckStringDeleted">Si la variable %1$s no está establecida</string>
|
||||
@ -794,4 +794,57 @@
|
||||
<string name="textToCopy">Texto para copiar</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Dibujar encima otras aplicaciones</string>
|
||||
<string name="overlayPermissionHint">Después de hacer cliquear en Aceptar, se le enviará a un cuadro de diálogo del sistema. Seleccione Automation allí y permita dibujar encima otras aplicaciones.</string>
|
||||
<string name="variablesOnlyForTypes">Las variables solo están disponibles para los tipos de parámetro String y URI</string>
|
||||
<string name="intentParametersHint">Si desea especificar un parámetro, también debe hacer clic en \"Agregar par de intención\". De lo contrario, los cambios no se guardarán.</string>
|
||||
<string name="languagePolish">Polaco</string>
|
||||
<string name="languageChineseChina">Chino (China)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Este activador será válido si acabas de desconectarte del wifi especificado anteriormente O mientras el servicio aún se está iniciando y si no estás conectado a ningún wifi. Si desea que el activador se active solo cuando se desconecte explícitamente de una determinada red WiFi, agregue otro activador \"el servicio no se está iniciando\".</string>
|
||||
<string name="className">Nombre de la clase</string>
|
||||
<string name="startAppByStartForegroundService">a través de startForegroundService((</string>
|
||||
<string name="method">Método</string>
|
||||
<string name="takeScreenshot">Tomar captura de pantalla</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Enlazar al servicio de accesibilidad</string>
|
||||
<string name="bindAccessibilityService">Enlazar al servicio de accesibilidad</string>
|
||||
<string name="accessibilityApiPermissionHint">Después de hacer clic en Aceptar, se le enviará a un cuadro de diálogo del sistema. Seleccione Automatización allí y permita Permitir API de accesibilidad.</string>
|
||||
<string name="accessibility_service_explanation">Requerido para ciertas acciones.</string>
|
||||
<string name="noticeRestrictedPermissions">Si no le otorga a uno el siguiente permiso y un mensaje del sistema como \"Ajuste restringido\", primero debe ir a la configuración de Android, luego a las aplicaciones, elija Automatización. Ahora debería haber 3 puntos en la esquina superior derecha. Haga clic en \"Permitir configuraciones restringidas\". Después de eso, el permiso necesario debería poder otorgarse. Esto solo debería aplicarse a la versión APK de la aplicación, no a las de F-Droid o Play Store.</string>
|
||||
<string name="setLocationService">Encender/desactivar el servicio de ubicación</string>
|
||||
<string name="setLocationServiceCapital">Establecer el servicio de ubicación</string>
|
||||
<string name="writeSecureSettingsNotice">Desafortunadamente, el permiso WRITE_SECURE_SETTINGS no se puede otorgar directamente en su dispositivo Android. En su lugar, debe conectar su dispositivo a una computadora y otorgar el permiso a través de ADB. Haga clic aquí para saber cómo otorgarlo: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Servicio de localización</string>
|
||||
<string name="triggerUrlVariableHint">El resultado de esta solicitud se almacenará en la variable LAST_TRIGGERURL_RESULT si desea verificarlo desde otra regla. En caso de errores HTTP como 404, el valor será \"HTTP_ERROR\".</string>
|
||||
<string name="calendarEvent">Evento de calendario</string>
|
||||
<string name="eventIsCurrentlyHappening">El evento está activo actualmente</string>
|
||||
<string name="calendarEventCapital">evento de calendario</string>
|
||||
<string name="location">Lugar</string>
|
||||
<string name="calendarDescription">Descripción/notas</string>
|
||||
<string name="availability">Disponibilidad</string>
|
||||
<string name="eventIsCurrentlyNotHappening">El evento no está ocurriendo actualmente/ha finalizado</string>
|
||||
<string name="calendarStringBusy">ocupado</string>
|
||||
<string name="calendarStringFree">libre</string>
|
||||
<string name="calendarStringTentative">intento</string>
|
||||
<string name="calendarStringOutOfOffice">fuera de la oficina</string>
|
||||
<string name="calendarStringWorkingElsewhere">Trabajar en otro lugar</string>
|
||||
<string name="selectingNoneItemForAllToMatch">Si no selecciona ningún elemento, cualquiera estará bien.</string>
|
||||
<string name="calendars">Calendarios</string>
|
||||
<string name="calendarAvailabilityTypesUnsupported">Puede ser que solo los primeros 3 tipos funcionen realmente porque los otros tipos no forman parte de la interfaz de calendario estándar de Android.</string>
|
||||
<string name="anyCalendar">cualquier calendario</string>
|
||||
<string name="availabilities">Disponibilidades</string>
|
||||
<string name="calendarsMissingHint">En este desencadenador, los calendarios con ID %1$s se han configurado previamente, pero se han eliminado desde entonces. Con el siguiente guardado, se eliminarán de este activador. Hasta entonces, este desencadenante/condición nunca se cumplirá.</string>
|
||||
<string name="account">cuenta</string>
|
||||
<string name="allDayEvent">Evento de todo el día</string>
|
||||
<string name="allDayEventTrue">El evento es un evento de todo el día</string>
|
||||
<string name="allDayEventFalse">El evento no es un evento de todo el día</string>
|
||||
<string name="permissionCalendarRequired">El permiso para leer el calendario será necesario para un activador de calendario. Ya será necesario rellenar los campos del calendario en esta ventana.</string>
|
||||
<string name="noCalendarsOnYourDevice">Parece que no se han configurado calendarios en su dispositivo. Puede guardar este desencadenador, pero nunca devolverá true.</string>
|
||||
<string name="errorReadingCalendars">Se ha producido un error al leer los calendarios de su dispositivo.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Programe alarmas exactas</string>
|
||||
<string name="alarmsPermissionHint">Después de hacer clic en Aceptar, se abrirá una ventana. Seleccione Automatización allí y permita que la aplicación programe alarmas exactas.</string>
|
||||
<string name="evaluate">Evaluar</string>
|
||||
<string name="errorLoadingValues">Se ha producido un error al cargar los valores.</string>
|
||||
<string name="enterValidDataIntoParametersFields">Introduzca datos válidos en los campos de parámetros.</string>
|
||||
<string name="reoccurringFalse">El evento no se repite</string>
|
||||
<string name="reoccurringTrue">El evento se repite</string>
|
||||
<string name="reoccurring">Recurrente</string>
|
||||
<string name="calendarTriggerExecutionHints">Si su calendario contiene varios eventos paralelos, superpuestos o directamente posteriores, una regla se ejecutará tantas veces como eventos coincidan con los criterios de la regla. En caso de que una regla tenga varios activadores de calendario y haya varios eventos coincidentes en paralelo, la regla se ejecutará solo una vez.</string>
|
||||
</resources>
|
@ -65,7 +65,7 @@
|
||||
<string name="end">Arrêt</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="urlToTrigger">URL à déclencher :</string>
|
||||
<string name="urlLegend">Variables :\nVous pouvez utiliser les variables suivantes. Lors du déclenchement, elles seront remplacées par les variables correspondantes sur votre appareil. Insérez les parenthèses dans votre texte.\n\n[uniqueid] - Identifiant unique de votre appareil\n[serialnr] - Numéro de série de votre appareil (< Android 9)\n[latitude] - Latitude de votre appraeil\n[longitude] - Longitude de votre appraeil\n[phonenr] - Numéro des derniers appels entrants ou sortants\n[d] - Jour du mois, @ chiffres commençant par 0\n[m] - Valeur numérique du mois, avec @ chiffres\n[Y] - Valeur numérique de l’année, $ chiffres\n[h] - Format horaire 12 heures, 2 chiffres\n[H] - Format horaire 24 heures, 2 chiffres\n[i] - Nombre de minutes, 2 chiffres\n[s] - Nombre de secondes, 2 chiffres\n[ms] - Nombre de millisecondes\n[notificationTitle] - titre de la dernière notification\n[notificationText] - texte de la dernière notification\n[variable-VARIABLENAME] - Valeur de votre variable définie personnalisée</string>
|
||||
<string name="urlLegend">Variables :\nVous pouvez utiliser les variables suivantes. Lors du déclenchement, elles seront remplacées par les variables correspondantes sur votre appareil. Insérez les parenthèses dans votre texte.\n\n[uniqueid] - Identifiant unique de votre appareil\n[serialnr] - Numéro de série de votre appareil (< Android 9)\n[latitude] - Latitude de votre appraeil\n[longitude] - Longitude de votre appraeil\n[phonenr] - Numéro des derniers appels entrants ou sortants\n[d] - Jour du mois, @ chiffres commençant par 0\n[m] - Valeur numérique du mois, avec @ chiffres\n[Y] - Valeur numérique de l’année, $ chiffres\n[h] - Format horaire 12 heures, 2 chiffres\n[H] - Format horaire 24 heures, 2 chiffres\n[i] - Nombre de minutes, 2 chiffres\n[s] - Nombre de secondes, 2 chiffres\n[ms] - Nombre de millisecondes\n[notificationTitle] - titre de la dernière notification\n[notificationText] - texte de la dernière notification\n[last_triggerurl_result] - Résultat de l\'exécution de la dernière action triggerUrl\n[last_run_executable_exit_code] - Le code de sortie de la dernière action exécutable exécutée\n[last_run_executable_output] - La sortie de la dernière action exécutable exécutée (uniquement pour les non-roots)\n[last_calendar_title] - Titre du dernier événement de calendrier déclenchant une règle\n[last_calendar_description] - Description du dernier événement de calendrier déclenchant une règle\n[last_calendar_location] - Emplacement du dernier événement de calendrier déclenchant la règle\n[variable-VARIABLENAME] - Valeur de votre variable définie personnalisée</string>
|
||||
<string name="wifi">wifi</string>
|
||||
<string name="activating">Allumer</string>
|
||||
<string name="deactivating">Éteindre</string>
|
||||
@ -794,4 +794,57 @@
|
||||
<string name="textToCopy">Texte à copier</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Dessiner sur d\'autres applications</string>
|
||||
<string name="overlayPermissionHint">Après avoir cliqué sur OK, vous serez redirigé vers une boîte de dialogue système. Veuillez sélectionner Automatisation et autoriser le tirage sur d\'autres applications.</string>
|
||||
<string name="variablesOnlyForTypes">Les variables ne sont disponibles que pour les types de paramètres String et URI</string>
|
||||
<string name="intentParametersHint">Si vous souhaitez spécifier un paramètre, vous devez également cliquer sur « Ajouter une paire d\'intentions ». Sinon, vos modifications ne seront pas enregistrées.</string>
|
||||
<string name="languagePolish">Polonais</string>
|
||||
<string name="languageChineseChina">Chinois (Chine)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Ce déclencheur sera valide si vous venez de vous déconnecter du wifi spécifié ci-dessus OU alors que le service est encore en cours de démarrage et si vous n\'êtes connecté à aucun wifi. Si vous souhaitez que le déclencheur ne se déclenche que lorsque vous vous déconnectez explicitement d\'un certain wifi, ajoutez un autre déclencheur « le service ne démarre pas ».</string>
|
||||
<string name="className">Nom de la classe</string>
|
||||
<string name="startAppByStartForegroundService">par startForegroundService()</string>
|
||||
<string name="method">Méthode</string>
|
||||
<string name="takeScreenshot">Prendre une capture d\'écran</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Se lier au service d\'accessibilité</string>
|
||||
<string name="bindAccessibilityService">Se lier au service d\'accessibilité</string>
|
||||
<string name="accessibilityApiPermissionHint">Après avoir cliqué sur OK, vous serez redirigé vers une boîte de dialogue système. Sélectionnez Automatisation et autorisez l\'option Autoriser l\'API d\'accessibilité.</string>
|
||||
<string name="accessibility_service_explanation">Obligatoire pour certaines actions.</string>
|
||||
<string name="noticeRestrictedPermissions">Si vous ne parvenez pas à accorder à l\'un d\'entre eux l\'autorisation suivante et un message système tel que « Autorisation restreinte », vous devez d\'abord accéder aux paramètres Android, puis aux applications, puis choisir Automatisation. Maintenant, il devrait y avoir 3 points dans le coin supérieur droit. Cliquez sur « Autoriser les paramètres restreints ». Après cela, l\'autorisation nécessaire devrait pouvoir être accordée. Cela ne devrait s\'appliquer qu\'à la version APK de l\'application, pas à celles de F-Droid ou du Play Store.</string>
|
||||
<string name="setLocationService">Définir le service de localisation</string>
|
||||
<string name="setLocationServiceCapital">Définir le service de localisation</string>
|
||||
<string name="writeSecureSettingsNotice">Malheureusement, l\'autorisation WRITE_SECURE_SETTINGS ne peut pas être donnée directement sur votre appareil Android. Au lieu de cela, vous devez connecter votre appareil à un ordinateur et accorder l\'autorisation via ADB. Cliquez ici pour savoir comment l\'accorder : https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Service de localisation</string>
|
||||
<string name="triggerUrlVariableHint">Le résultat de cette requête sera stocké dans la variable LAST_TRIGGERURL_RESULT si vous souhaitez le vérifier à partir d\'une autre règle. En cas d\'erreurs HTTP comme 404, la valeur sera « HTTP_ERROR ».</string>
|
||||
<string name="calendarEvent">Événement de calendrier</string>
|
||||
<string name="eventIsCurrentlyHappening">L\'événement est actuellement actif</string>
|
||||
<string name="calendarEventCapital">Evénement de calendrier</string>
|
||||
<string name="location">Emplacement</string>
|
||||
<string name="calendarDescription">Description/notes</string>
|
||||
<string name="availability">Beschikbaarheid</string>
|
||||
<string name="eventIsCurrentlyNotHappening">L\'événement n\'a pas lieu ou s\'est terminé</string>
|
||||
<string name="calendarStringBusy">occupé</string>
|
||||
<string name="calendarStringFree">libre</string>
|
||||
<string name="calendarStringTentative">tentative</string>
|
||||
<string name="calendarStringOutOfOffice">absent du bureau</string>
|
||||
<string name="calendarStringWorkingElsewhere">Travailler ailleurs</string>
|
||||
<string name="selectingNoneItemForAllToMatch">Si vous ne sélectionnez aucun élément, n\'importe lequel d\'entre eux sera acceptable.</string>
|
||||
<string name="calendars">Calendriers</string>
|
||||
<string name="calendarAvailabilityTypesUnsupported">Il se peut que seuls les 3 premiers types fonctionnent réellement car les autres types ne font pas partie de l\'interface de calendrier standard d\'Android.</string>
|
||||
<string name="anyCalendar">n\'importe quel calendrier</string>
|
||||
<string name="availabilities">Disponibilités</string>
|
||||
<string name="calendarsMissingHint">Dans ce déclencheur, les calendriers avec des ID %1$s ont été configurés précédemment, mais ont été supprimés depuis. Lors de la prochaine sauvegarde, ceux-ci seront supprimés de ce déclencheur. D\'ici là, ce déclencheur/condition ne sera jamais rempli.</string>
|
||||
<string name="account">compte</string>
|
||||
<string name="allDayEvent">Événement d\'une journée</string>
|
||||
<string name="allDayEventTrue">L\'événement est un événement d\'une journée</string>
|
||||
<string name="allDayEventFalse">L\'événement n\'est pas un événement d\'une journée</string>
|
||||
<string name="permissionCalendarRequired">event isL\'autorisation de lire votre calendrier sera requise pour un déclencheur de calendrier. Il sera déjà nécessaire de remplir les champs du calendrier dans cette fenêtre. Il ne s\'agit pas d\'un événement qui dure toute la journée</string>
|
||||
<string name="noCalendarsOnYourDevice">Il semble qu\'aucun calendrier n\'ait été configuré sur votre appareil. Vous pouvez enregistrer ce déclencheur, mais il ne renverra jamais true.</string>
|
||||
<string name="errorReadingCalendars">Une erreur s\'est produite lors de la lecture des calendriers sur votre appareil.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Programmer des alarmes exactes</string>
|
||||
<string name="alarmsPermissionHint">Après avoir cliqué sur OK, une fenêtre s\'ouvre. Veuillez sélectionner Automatisation et permettre à l\'application de programmer des alarmes précises.</string>
|
||||
<string name="evaluate">Évaluer</string>
|
||||
<string name="errorLoadingValues">Une erreur s\'est produite lors du chargement des valeurs.</string>
|
||||
<string name="enterValidDataIntoParametersFields">Saisissez des données valides dans les champs de paramètre.</string>
|
||||
<string name="reoccurringFalse">l\'événement ne se reproduit pas</string>
|
||||
<string name="reoccurringTrue">l\'événement se reproduit</string>
|
||||
<string name="reoccurring">Récurrents</string>
|
||||
<string name="calendarTriggerExecutionHints">Si votre calendrier contient plusieurs événements parallèles, qui se chevauchent ou qui se suivent directement, une règle sera exécutée autant de fois qu\'il y a d\'événements correspondant aux critères de la règle. Dans le cas où une règle a plusieurs déclencheurs de calendrier et qu\'il y a plusieurs événements correspondants en parallèle, la règle ne sera exécutée qu\'une seule fois.</string>
|
||||
</resources>
|
||||
|
@ -542,7 +542,7 @@
|
||||
<string name="tuesday">Martedì</string>
|
||||
<string name="unknownError">Errore indeterminato.</string>
|
||||
<string name="until">finchè</string>
|
||||
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. Quando attivate, saranno sostituite con il valore corrispondente sul tuo dispositivo. Includi le parentesi nel tuo testo.\n\n[uniqueid] - L\'ID unico del tuo dispositivo\n[serialnr] - Il numero di serie del tuo dispositivio (< Android 9)\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Numero dell\'ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre con zero iniziale \n[m] - Mese in formato numerico, sempre 2 cifre con zero iniziale \n[Y] - L\’anno, sempre con 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre\n[notificationTitle] - titolo dell\'ultima notifica\n[notificationText] - testo dell\'ultima notifica\n[variable-VARIABLENAME] - Il valore della variabile definita in modo personalizzato</string>
|
||||
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. Quando attivate, saranno sostituite con il valore corrispondente sul tuo dispositivo. Includi le parentesi nel tuo testo.\n\n[uniqueid] - L\'ID unico del tuo dispositivo\n[serialnr] - Il numero di serie del tuo dispositivio (< Android 9)\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Numero dell\'ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre con zero iniziale \n[m] - Mese in formato numerico, sempre 2 cifre con zero iniziale \n[Y] - L\’anno, sempre con 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre\n[notificationTitle] - titolo dell\'ultima notifica\n[notificationText] - testo dell\'ultima notifica\n[last_triggerurl_result] - Risultato dell\'esecuzione dell\'ultima azione triggerUrl\n[last_run_executable_exit_code] - Codice di uscita dell\'ultima azione eseguibile di esecuzione\n[last_run_executable_output] - L\'output dell\'ultima azione eseguibile eseguita (solo per i non root)\n[last_calendar_title] - Titolo dell\'ultimo evento di calendario che ha attivato la regola\n[last_calendar_description] - Descrizione dell\'ultimo evento del calendario che ha attivato la regola\n[last_calendar_location] - Posizione dell\'ultimo evento del calendario che ha attivato la regola\n[variable-VARIABLENAME] - Il valore della variabile definita in modo personalizzato</string>
|
||||
<string name="urlToTrigger">URL da caricare:</string>
|
||||
<string name="urlTooShort">L\'url deve avere almeno 10 caratteri.</string>
|
||||
<string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funzionerà dato che sei su una versione superiore ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola.</string>
|
||||
@ -795,4 +795,57 @@
|
||||
<string name="textToCopy">Testo da copiare</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Disegna su altre app</string>
|
||||
<string name="overlayPermissionHint">Dopo aver fatto clic su OK, verrai indirizzato a una finestra di dialogo di sistema. Seleziona Automazione lì e consenti il disegno su altre app.</string>
|
||||
<string name="variablesOnlyForTypes">Le variabili sono disponibili solo per i tipi di parametro String e URI</string>
|
||||
<string name="intentParametersHint">Se si desidera specificare un parametro è necessario fare clic anche su \"Aggiungi coppia intento\". In caso contrario, le modifiche non verranno salvate.</string>
|
||||
<string name="languagePolish">Polacco</string>
|
||||
<string name="languageChineseChina">Cinese (Cina)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Questo trigger sarà valido se ti sei appena disconnesso dal Wi-Fi specificato sopra OPPURE mentre il servizio è ancora in fase di avvio e se non sei connesso a nessuna rete Wi-Fi. Se vuoi che il trigger si attivi solo quando ti stai disconnettendo esplicitamente da una determinata rete Wi-Fi, aggiungi un altro trigger \"il servizio non si avvia\".</string>
|
||||
<string name="className">Nome della classe</string>
|
||||
<string name="startAppByStartForegroundService">di startForegroundService()</string>
|
||||
<string name="method">Metodo</string>
|
||||
<string name="takeScreenshot">Fai uno screenshot</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Associare al servizio di accessibilità</string>
|
||||
<string name="bindAccessibilityService">Associare al servizio di accessibilità</string>
|
||||
<string name="accessibilityApiPermissionHint">Dopo aver fatto clic su OK, verrà visualizzata una finestra di dialogo di sistema. Seleziona Automazione e consenti Consenti API di accessibilità.</string>
|
||||
<string name="accessibility_service_explanation">Obbligatorio per determinate azioni.</string>
|
||||
<string name="noticeRestrictedPermissions">Se non riesci a concedere una delle seguenti autorizzazioni e un messaggio di sistema come \"Autorizzazione limitata\", devi prima andare alle impostazioni di Android, quindi alle applicazioni, scegli Automazione. Ora dovrebbero esserci 3 punti nell\'angolo in alto a destra. Fai clic su \"Consenti impostazioni limitate\". Dopodiché dovrebbe essere concessa l\'autorizzazione necessaria. Questo dovrebbe valere solo per la versione APK dell\'app, non per quelle di F-Droid o Play Store.</string>
|
||||
<string name="setLocationService">Impostare il servizio di localizzazione</string>
|
||||
<string name="setLocationServiceCapital">Impostare il servizio di localizzazione</string>
|
||||
<string name="writeSecureSettingsNotice">Purtroppo l\'autorizzazione WRITE_SECURE_SETTINGS non può essere data direttamente sul tuo dispositivo Android. Invece, devi collegare il tuo dispositivo a un computer e concedere l\'autorizzazione tramite ADB. Clicca qui per scoprire come concederlo: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Servizio di localizzazione</string>
|
||||
<string name="triggerUrlVariableHint">Il risultato di questa richiesta verrà memorizzato nella variabile LAST_TRIGGERURL_RESULT se si desidera controllarlo da un\'altra regola. In caso di errori HTTP come 404 il valore sarà \"HTTP_ERROR\".</string>
|
||||
<string name="calendarEvent">Evento del calendario</string>
|
||||
<string name="eventIsCurrentlyHappening">L\'evento è attualmente attivo</string>
|
||||
<string name="calendarEventCapital">evento del calendario</string>
|
||||
<string name="location">Ubicazione</string>
|
||||
<string name="calendarDescription">Descrizione/note</string>
|
||||
<string name="availability">Disponibilità</string>
|
||||
<string name="eventIsCurrentlyNotHappening">L\'evento al momento non è in corso/è terminato</string>
|
||||
<string name="calendarStringBusy">occupato</string>
|
||||
<string name="calendarStringFree">gratuito</string>
|
||||
<string name="calendarStringTentative">tentativo</string>
|
||||
<string name="calendarStringOutOfOffice">Fuori sede</string>
|
||||
<string name="calendarStringWorkingElsewhere">Lavorare altrove</string>
|
||||
<string name="selectingNoneItemForAllToMatch">Se non selezioni nessun elemento, tutti saranno ok.</string>
|
||||
<string name="calendars">Calendari</string>
|
||||
<string name="calendarAvailabilityTypesUnsupported">È possibile che solo i primi 3 tipi funzionino effettivamente perché gli altri tipi non fanno parte dell\'interfaccia del calendario standard di Android.</string>
|
||||
<string name="anyCalendar">qualsiasi calendario</string>
|
||||
<string name="availabilities">Disponibilità</string>
|
||||
<string name="calendarsMissingHint">In questo trigger i calendari con ID %1$s sono stati configurati in precedenza, ma sono stati eliminati da allora. Con il prossimo salvataggio, questi verranno rimossi da questo attivatore. Fino ad allora, questa condizione non sarà mai soddisfatta.</string>
|
||||
<string name="account">conto</string>
|
||||
<string name="allDayEvent">Evento che dura tutto il giorno</string>
|
||||
<string name="allDayEventTrue">L\'evento è un evento che dura tutto il giorno</string>
|
||||
<string name="allDayEventFalse">L\'evento non è un evento che dura tutto il giorno</string>
|
||||
<string name="permissionCalendarRequired">L\'autorizzazione per leggere il calendario sarà necessaria per un trigger di calendario. Sarà già necessario compilare i campi del calendario in questa finestra.</string>
|
||||
<string name="noCalendarsOnYourDevice">Sembra che sul tuo dispositivo non sia stato impostato alcun calendario. È possibile salvare questo trigger, ma non restituirà mai true.</string>
|
||||
<string name="errorReadingCalendars">Si è verificato un errore durante la lettura dei calendari sul dispositivo.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Pianifica allarmi esatti</string>
|
||||
<string name="alarmsPermissionHint">Dopo aver fatto clic su OK, si aprirà una finestra. Seleziona Automazione lì e consenti all\'app di programmare allarmi esatti.</string>
|
||||
<string name="evaluate">Valutare</string>
|
||||
<string name="errorLoadingValues">Si è verificato un errore durante il caricamento dei valori.</string>
|
||||
<string name="enterValidDataIntoParametersFields">Immettere dati validi nei campi dei parametri.</string>
|
||||
<string name="reoccurringFalse">l\'evento non si ripete</string>
|
||||
<string name="reoccurringTrue">l\'evento si ripete</string>
|
||||
<string name="reoccurring">Reoccurring</string>
|
||||
<string name="calendarTriggerExecutionHints">Se il calendario contiene più eventi paralleli, sovrapposti o direttamente successivi, una regola verrà eseguita tante volte quanti sono gli eventi che corrispondono ai criteri della regola. Nel caso in cui una regola disponga di più trigger di calendario e siano presenti più eventi corrispondenti in parallelo, la regola verrà eseguita una sola volta.</string>
|
||||
</resources>
|
||||
|
@ -64,7 +64,7 @@
|
||||
<string name="end">Einde</string>
|
||||
<string name="save">Opslaan</string>
|
||||
<string name="urlToTrigger">URL om te activeren:</string>
|
||||
<string name="urlLegend">Variabelen:U kunt de volgende variabelen gebruiken. Bij het triggeren zullen ze worden vervangen door de corresponderende waarde op je apparaat. Zet de haakjes in uw tekst. \n[uniqueid] - Het unieke id van uw apparaat[serialnr] - Het serienummer van uw apparaat (< Android 9)[latitude] - De breedtegraad van uw apparaat[longitude] - De lengtegraad van uw apparaat[phonenr] - Nummer van het laatste inkomende of uitgaande gesprek[d] - Dag van de maand, 2 cijfers met voorloopnullen[m] - Numerieke weergave van een maand, met voorloopnullen[Y] - een volledige numerieke weergave van een jaar, 4 cijfers[h] - 12-uurs indeling van een uur, met voorloopnullen[H] - 24-uurs indeling van een uur, met voorloopnullen[i] - minuten, met voorloopnullen[s] - seconden, met voorloopnullen[ms] - milliseconden[notificationTitle] - titel van de laatste melding[notificationText] - tekst van de laatste melding\n[variable-VARIABLENAME] - De waarde van uw aangepaste gedefinieerde variabele</string>
|
||||
<string name="urlLegend">Variabelen:U kunt de volgende variabelen gebruiken. Bij het triggeren zullen ze worden vervangen door de corresponderende waarde op je apparaat. Zet de haakjes in uw tekst. \n[uniqueid] - Het unieke id van uw apparaat[serialnr] - Het serienummer van uw apparaat (< Android 9)[latitude] - De breedtegraad van uw apparaat[longitude] - De lengtegraad van uw apparaat[phonenr] - Nummer van het laatste inkomende of uitgaande gesprek[d] - Dag van de maand, 2 cijfers met voorloopnullen[m] - Numerieke weergave van een maand, met voorloopnullen[Y] - een volledige numerieke weergave van een jaar, 4 cijfers[h] - 12-uurs indeling van een uur, met voorloopnullen[H] - 24-uurs indeling van een uur, met voorloopnullen[i] - minuten, met voorloopnullen[s] - seconden, met voorloopnullen[ms] - milliseconden[notificationTitle] - titel van de laatste melding[notificationText] - tekst van de laatste melding\n[last_triggerurl_result] - Het resultaat van de laatste uitvoering van de triggerUrl-actie\n[last_run_executable_exit_code] - De afsluitcode van de uitvoerbare actie van de laatste uitvoering\n[last_run_executable_output] - De uitvoer van de uitvoerbare actie van de laatste uitvoering (alleen voor niet-root)\n[last_calendar_title] - Titel van de laatste agenda-afspraak die regels activeert\n[last_calendar_description] - Beschrijving van de laatste agenda-gebeurtenis die regels activeert\n[last_calendar_location] - Locatie van de laatste agenda-gebeurtenis die de regel activeert\n[variable-VARIABLENAME] - De waarde van uw aangepaste gedefinieerde variabele</string>
|
||||
<string name="wifi">wifi</string>
|
||||
<string name="activating">Activeren</string>
|
||||
<string name="deactivating">Deactiveren</string>
|
||||
@ -793,5 +793,58 @@
|
||||
<string name="textToCopy">Tekst om te kopiëren</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Tekenen over andere apps</string>
|
||||
<string name="overlayPermissionHint">Nadat u op OK hebt geklikt, wordt u naar een systeemdialoogvenster gestuurd. Selecteer daar Automatisering en sta tekenen toe over andere apps.</string>
|
||||
<string name="variablesOnlyForTypes">Variabelen zijn alleen beschikbaar voor parametertypen Tekenreeks en URI</string>
|
||||
<string name="intentParametersHint">Als u een parameter wilt opgeven, moet u ook op \"Intentiepaar toevoegen\" klikken. Anders worden uw wijzigingen niet opgeslagen.</string>
|
||||
<string name="languagePolish">Pools</string>
|
||||
<string name="languageChineseChina">Chinees (China)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Deze trigger is geldig als je net de verbinding met de hierboven gespecificeerde wifi hebt verbroken OF terwijl de service nog aan het starten is en als je niet verbonden bent met wifi. Als je wilt dat de trigger alleen wordt geactiveerd wanneer je expliciet de verbinding met een bepaalde wifi verbreekt, voeg dan nog een trigger toe \"service start niet\".</string>
|
||||
<string name="className">Naam van de klasse</string>
|
||||
<string name="startAppByStartForegroundService">door startForegroundService()</string>
|
||||
<string name="method">Methode</string>
|
||||
<string name="takeScreenshot">Screenshot maken</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Binden aan toegankelijkheidsservice</string>
|
||||
<string name="bindAccessibilityService">Binden aan toegankelijkheidsservice</string>
|
||||
<string name="accessibilityApiPermissionHint">Nadat u op OK hebt geklikt, wordt u naar een systeemdialoogvenster gestuurd. Selecteer daar Automatisering en sta Toegankelijkheids-API toestaan toe.</string>
|
||||
<string name="accessibility_service_explanation">Vereist voor bepaalde acties.</string>
|
||||
<string name="noticeRestrictedPermissions">Als u er niet in slaagt om een van de volgende machtigingen en een systeembericht zoals \"Beperkte toestemming\" te verlenen, moet u eerst naar Android-instellingen gaan en vervolgens naar toepassingen en Automatisering kiezen. Nu zouden er 3 stippen in de rechterbovenhoek moeten zijn. Klik op \"Beperkte instellingen toestaan\". Daarna moet de benodigde toestemming aanvaardbaar zijn. Dit zou alleen van toepassing moeten zijn op de APK-versie van de app, niet die van F-Droid of Play Store.</string>
|
||||
<string name="setLocationService">Locatieservice instellen</string>
|
||||
<string name="setLocationServiceCapital">Locatieservice instellen</string>
|
||||
<string name="writeSecureSettingsNotice">Helaas kan de toestemming WRITE_SECURE_SETTINGS niet rechtstreeks op uw Android-apparaat worden gegeven. In plaats daarvan moet u uw apparaat op een computer aansluiten en de toestemming verlenen via ADB. Klik hier om te weten te komen hoe u het kunt toekennen: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Locatie service</string>
|
||||
<string name="triggerUrlVariableHint">Het resultaat van dit verzoek wordt opgeslagen in de variabele LAST_TRIGGERURL_RESULT als u het vanuit een andere regel wilt controleren. In het geval van HTTP-fouten zoals 404 is de waarde \"HTTP_ERROR\".</string>
|
||||
<string name="calendarEvent">Agenda-afspraak</string>
|
||||
<string name="eventIsCurrentlyHappening">Begivenheden er aktiv i øjeblikket</string>
|
||||
<string name="calendarEventCapital">agenda-afspraak</string>
|
||||
<string name="location">Plaats</string>
|
||||
<string name="calendarDescription">Beschrijving/opmerkingen</string>
|
||||
<string name="availability">Beschikbaarheid</string>
|
||||
<string name="eventIsCurrentlyNotHappening">Evenement vindt momenteel niet plaats/is afgelopen</string>
|
||||
<string name="calendarStringBusy">druk</string>
|
||||
<string name="calendarStringFree">vrij</string>
|
||||
<string name="calendarStringTentative">proberen</string>
|
||||
<string name="calendarStringOutOfOffice">Niet op kantoor</string>
|
||||
<string name="calendarStringWorkingElsewhere">elders werken</string>
|
||||
<string name="selectingNoneItemForAllToMatch">Als u geen item selecteert, is elk item in orde.</string>
|
||||
<string name="calendars">Kalenders</string>
|
||||
<string name="calendarAvailabilityTypesUnsupported">Het kan zijn dat alleen de eerste 3 typen daadwerkelijk werken omdat de andere typen geen deel uitmaken van de standaard agenda-interface van Android.</string>
|
||||
<string name="anyCalendar">elke kalender</string>
|
||||
<string name="availabilities">Beschikbaarheid</string>
|
||||
<string name="calendarsMissingHint">In deze trigger zijn kalenders met ID\'s %1$s eerder geconfigureerd, maar sindsdien verwijderd. Bij de volgende save worden die uit deze trigger verwijderd. Tot die tijd zal nooit aan deze trigger/voorwaarde worden voldaan.</string>
|
||||
<string name="account">rekening</string>
|
||||
<string name="allDayEvent">Evenement dat de hele dag duurt</string>
|
||||
<string name="allDayEventTrue">evenement is een evenement dat de hele dag duurt</string>
|
||||
<string name="allDayEventFalse">evenement is niet een evenement dat de hele dag duurt</string>
|
||||
<string name="permissionCalendarRequired">De toestemming om uw agenda te lezen is vereist voor een agendatrigger. Het is al nodig om de kalendervelden in dit venster in te vullen.</string>
|
||||
<string name="noCalendarsOnYourDevice">Het lijkt erop dat er geen agenda\'s zijn ingesteld op uw apparaat. U kunt deze trigger opslaan, maar deze wordt nooit waar geretourneerd.</string>
|
||||
<string name="errorReadingCalendars">Er is een fout opgetreden bij het lezen van de agenda\'s op uw apparaat.</string>
|
||||
<string name="android.permission.SCHEDULE_EXACT_ALARM">Plan exacte alarmen</string>
|
||||
<string name="alarmsPermissionHint">Nadat u op OK hebt geklikt, wordt een venster geopend. Selecteer daar Automatisering en laat de app exacte alarmen plannen.</string>
|
||||
<string name="evaluate">Evalueren</string>
|
||||
<string name="errorLoadingValues">Er is een fout opgetreden tijdens het laden van waarden.</string>
|
||||
<string name="enterValidDataIntoParametersFields">Voer geldige gegevens in de parametervelden in.</string>
|
||||
<string name="reoccurringFalse">gebeurtenis zich niet opnieuw voordoet</string>
|
||||
<string name="reoccurringTrue">gebeurtenis zich opnieuw voordoet</string>
|
||||
<string name="reoccurring">Terugkerende</string>
|
||||
<string name="calendarTriggerExecutionHints">Als uw agenda meerdere parallelle, overlappende of direct volgende gebeurtenissen bevat, wordt een regel net zo vaak uitgevoerd als er afspraken zijn die voldoen aan de criteria van de regel. Als een regel meerdere agendatriggers heeft en er meerdere overeenkomende gebeurtenissen parallel zijn, wordt de regel slechts één keer uitgevoerd.</string>
|
||||
|
||||
</resources>
|
||||
|