Compare commits

..

80 Commits

Author SHA1 Message Date
jens 7e72dfd19a Version 1.8.7 2026-03-06 22:22:34 +01:00
jens 23223480e5 Version 1.8.6 2026-03-06 22:05:01 +01:00
jens e3e2a87b5e Http request action streamlined to also cover the insecure setting in the same function. 2026-03-01 00:20:53 +01:00
jens 4cea4391eb Libraries updated 2026-02-28 22:52:42 +01:00
jens 63150ed8f6 Libraries updated 2026-02-27 23:56:04 +01:00
jens d986fcdf4d Upgraded to Gradle 8.13.2 2026-02-27 23:09:30 +01:00
jens ea57dd01e5 Upgraded to Gradle 8.4.2 2026-02-27 23:07:22 +01:00
jens 6f1f112d98 Further actions for trigger url action 2026-02-27 22:46:31 +01:00
jens 549c4f109e Merge remote-tracking branch 'origin/development' into development 2026-02-25 23:02:02 +01:00
jens d63841dd27 Further actions for trigger url action 2026-02-25 23:01:45 +01:00
jens 4913f9236b Version 1.8.5 2026-02-01 18:28:20 +01:00
jens 8f6e376231 Version 1.8.5 2026-02-01 18:12:37 +01:00
jens 9ff121e82a URL in variable bug fixed 2026-01-25 18:55:44 +01:00
jens ccf87dbef0 Action to change system settings 2026-01-06 16:51:13 +01:00
jens b510811b18 Action to change system settings 2026-01-05 18:00:46 +01:00
jens c1619e67ec Action to change system settings 2026-01-02 17:15:25 +01:00
jens 1c22a3386b Action to change system settings 2026-01-01 17:17:58 +01:00
jens b83b6568ca Minor changes 2025-12-31 15:54:25 +01:00
jens 4a90b36f6a Many small fixes 2025-12-28 15:27:50 +01:00
jens fd90b14bdc Release candidate 2025-12-26 16:06:09 +01:00
jens 91fdef99c3 startActivity package name fix 2025-12-17 23:22:14 +01:00
jens 63264fcf9b Profile activation logs 2025-12-14 12:49:58 +01:00
jens 2758ef180d NFC tag fix 2025-12-07 23:13:15 +01:00
jens 3d2b48706d Vibrations fix 2025-12-07 14:00:17 +01:00
jens e52ce4cd30 Crash in Google Play version fixed 2025-12-07 12:53:48 +01:00
jens bbb477fc77 Merge branch 'development' of https://git.server47.de/jens/Automation into development
# Conflicts:
#	fastlane/metadata/android/en-US/changelogs/145.txt
2025-12-06 18:00:53 +01:00
jens 4478006109 Permission check for ability to schedule exact timers 2025-12-06 17:59:22 +01:00
jens d117484143 Variable comparison check fixed 2025-12-06 11:30:58 +01:00
jens f7d8389668 Trigger URL fixes 2025-11-29 23:41:32 +01:00
jens 4282c53372 Vibration fix 2025-11-23 18:47:38 +01:00
jens 35e2a1158d Fixed airplane mode trigger not working 2025-11-16 20:30:38 +01:00
jens 66e86e66b3 Minor corrections 2025-11-13 23:12:17 +01:00
jens 4c4a355ff5 BLUETOOTH_CONNECT permission requested for Bluetooth trigger editor in Google Play version 2025-11-10 23:51:13 +01:00
jens 07011b2053 proximity trigger 2025-11-09 23:11:28 +01:00
jens fdcdaf53c9 proximity trigger 2025-11-06 23:27:32 +01:00
jens 55a1c24753 proximity trigger 2025-11-06 22:35:49 +01:00
jens ca88fbfb07 proximity trigger 2025-11-02 23:56:58 +01:00
jens 3497d7b8ea Proximity sensor trigger 2025-11-02 19:10:05 +01:00
jens e8e763210b trigger_url variable name fixed 2025-11-02 01:02:41 +01:00
jens b6ea652e46 UI theme can be changed 2025-10-29 23:24:13 +01:00
jens a30a47f67a UI theme can be changed 2025-10-27 00:13:08 +01:00
jens 914f5c033b UI theme 2025-10-26 19:35:14 +01:00
jens f64b8ea860 Missing translation added 2025-10-26 18:38:18 +01:00
jens 2445431393 Missing translation added 2025-10-25 00:34:47 +02:00
jens a6e10d09c3 Forum added to contact options 2025-10-19 23:32:34 +02:00
jens 7972a335c3 Foreground service type 2025-10-18 18:03:53 +02:00
jens e99203c7e4 Multiple bug fixes 2025-07-19 23:21:44 +02:00
jens ee311b0ba5 New version 1.8.3 RC 2025-07-19 18:03:37 +02:00
jens fb64c46c95 Many fixes 2025-07-18 19:05:42 +02:00
jens c7557519e8 Many fixes 2025-07-16 18:08:58 +02:00
jens 01c1ac3f5e Many fixes 2025-07-15 16:46:03 +02:00
jens b473034703 Many fixes 2025-07-12 18:51:37 +02:00
jens bf78ecc794 Many fixes 2025-07-10 18:39:07 +02:00
jens 6d9a77a990 Screen brightness 2025-07-09 21:20:21 +02:00
jens ec68d375c7 Many fixes 2025-07-08 18:11:56 +02:00
jens e8524f719f Fixed warnings in logs for formatted notifications 2025-05-01 16:07:22 +02:00
jens f04c517c80 Toggle logcat on/off 2025-04-27 13:32:30 +02:00
jens b6d7958389 Invert variable check 2025-03-30 17:50:39 +02:00
jens 04d2e4b432 Bugfix when checking for any battery charging type 2025-03-23 18:33:13 +01:00
jens abd346946a Bugfix when triggering URL 2025-03-22 20:27:59 +01:00
jens 17edf90086 v1.8.2 2025-01-19 16:03:10 +01:00
jens 879e1c6ef3 Additional variables 2024-12-27 15:10:29 +01:00
jens d7d806fb5c Added permission for Termux remote commands 2024-08-25 17:11:24 +02:00
jens 910af92989 Multiple bug fixes 2024-08-11 14:58:13 +02:00
jens 9f36411511 New version 2024-05-23 23:03:43 +02:00
jens eb893a7f21 Fixed crash when exiting settings while service is running 2024-05-23 16:02:58 +02:00
jens 8788a89e48 Removed calendar trigger from Google version and fixed bug in startOtherActivity 2024-05-23 15:02:12 +02:00
jens bb10620883 Removed calendar trigger from Google version 2024-05-07 09:49:32 +02:00
jens 3e29054f82 New version 2024-05-05 23:39:46 +02:00
jens 9d5f0a3cef Merge remote-tracking branch 'origin/development-stable' into development-stable 2024-04-17 23:48:58 +02:00
jens 695b1f2481 New version prepared 2024-04-17 23:48:43 +02:00
jens d7357b0b0f date time repetition 2024-03-29 15:31:32 +01:00
jens e272338cc6 Date time repetition 2024-02-12 23:15:05 +01:00
jens 3dd84220a3 date time repetition 2024-02-11 17:25:42 +01:00
jens 4bc2781ee7 Date time repetition 2024-02-08 23:53:15 +01:00
jens 62bfbbb064 date time repetition 2024-02-08 20:25:54 +01:00
jens 31d167a93f New version prep, fix attempt in notification listener 2024-02-07 23:24:03 +01:00
jens 500610fb98 Merge branch 'development' into development-stable 2024-02-02 23:09:23 +01:00
jens 5ca7295c30 date time repetition 2024-01-27 17:03:27 +01:00
jens 6e73c74b60 Added changelog for v137 2023-12-03 23:27:23 +01:00
195 changed files with 5728 additions and 3159 deletions
+15 -14
View File
@@ -3,16 +3,16 @@ plugins {
}
android {
compileSdkVersion 29
compileSdkVersion 36
defaultConfig {
applicationId "com.jens.automation2"
minSdkVersion 16
compileSdkVersion 33
buildToolsVersion '29.0.2'
minSdkVersion 19
compileSdkVersion 36
buildToolsVersion '36.0.0'
useLibrary 'org.apache.http.legacy'
versionCode 138
versionName "1.8"
versionCode 148
versionName "1.8.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -36,7 +36,7 @@ android {
{
dimension "version"
versionNameSuffix "-googlePlay"
targetSdkVersion 33
targetSdkVersion 36
}
/*
@@ -63,24 +63,25 @@ android {
checkReleaseBuilds false
}
namespace 'com.jens.automation2'
buildToolsVersion '36.0.0'
}
dependencies {
implementation 'org.jetbrains:annotations:15.0'
implementation 'org.jetbrains:annotations:26.1.0'
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0'
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
implementation 'org.apache.commons:commons-lang3:3.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.28.6'
implementation 'org.apache.commons:commons-lang3:3.20.0'
//implementation "androidx.security:security-crypto:1.0.0"
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
testImplementation 'junit:junit:4'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
+13 -19
View File
@@ -70,15 +70,16 @@
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.hardware.sensor.proximity"/>
<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.BLUETOOTH_CONNECT" />
<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-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-feature
android:name="android.hardware.telephony"
@@ -111,20 +112,11 @@
android:name="google_analytics_ssaid_collection_enabled"
android:value="false" />
<activity
android:name=".ActivityMainScreen"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivityManagePoi"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivitySettings"
android:label="@string/app_name"></activity>
<service
android:name=".AutomationService"
android:exported="false"
android:label="@string/app_name" />
android:label="@string/app_name"
android:foregroundServiceType="specialUse" />
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
<intent-filter>
@@ -164,6 +156,9 @@
</intent-filter>
</receiver>
<activity android:name=".ActivityMainScreen" android:label="@string/app_name" />
<activity android:name=".ActivityManagePoi" android:label="@string/app_name" />
<activity android:name=".ActivitySettings" android:label="@string/app_name" />
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
@@ -221,7 +216,6 @@
</intent-filter>
-->
<!--
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
@@ -234,15 +228,16 @@
<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" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service
android:name=".receivers.NotificationListener"
@@ -255,7 +250,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"/>
@@ -514,8 +514,6 @@ public class Rule implements Comparable<Rule>
protected boolean activateInternally(AutomationService automationService)
{
boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable;
String message;
@@ -556,7 +554,8 @@ public class Rule implements Comparable<Rule>
{
try
{
Rule.this.getActionSet().get(i).run(automationService, doToggle);
Miscellaneous.logEvent("i", "RuleExecution", "Running action " + Rule.this.getActionSet().get(i).toStringShort() + " of rule " + Rule.this.getName(), 5);
Rule.this.getActionSet().get(i).run(automationService, doToggle);
}
catch(Exception e)
{
@@ -593,10 +592,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force)
{
ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
}
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
+13 -18
View File
@@ -68,14 +68,16 @@
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.hardware.sensor.proximity"/>
<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.BLUETOOTH_CONNECT" />
<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-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-feature
android:name="android.hardware.telephony"
@@ -108,20 +110,11 @@
android:name="google_analytics_ssaid_collection_enabled"
android:value="false" />
<activity
android:name=".ActivityMainScreen"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivityManagePoi"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivitySettings"
android:label="@string/app_name"></activity>
<service
android:name=".AutomationService"
android:exported="false"
android:label="@string/app_name" />
android:label="@string/app_name"
android:foregroundServiceType="specialUse" />
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
<intent-filter>
@@ -161,6 +154,9 @@
</intent-filter>
</receiver>
<activity android:name=".ActivityMainScreen" android:label="@string/app_name" />
<activity android:name=".ActivityManagePoi" android:label="@string/app_name" />
<activity android:name=".ActivitySettings" android:label="@string/app_name" />
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
@@ -218,7 +214,6 @@
</intent-filter>
-->
<!--
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
@@ -231,15 +226,16 @@
<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" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service
android:name=".receivers.NotificationListener"
@@ -252,7 +248,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"/>
@@ -487,8 +487,6 @@ public class Rule implements Comparable<Rule>
protected boolean activateInternally(AutomationService automationService)
{
boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable;
String message;
@@ -529,6 +527,7 @@ public class Rule implements Comparable<Rule>
{
try
{
Miscellaneous.logEvent("i", "RuleExecution", "Running action " + Rule.this.getActionSet().get(i).toStringShort() + " of rule " + Rule.this.getName(), 5);
Rule.this.getActionSet().get(i).run(automationService, doToggle);
}
catch(Exception e)
@@ -566,10 +565,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force)
{
ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
}
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
+18 -30
View File
@@ -66,14 +66,15 @@
<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_CALENDAR" />
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.hardware.sensor.proximity"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<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" />-->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<application
android:allowBackup="true"
@@ -93,20 +94,15 @@
android:name="google_analytics_ssaid_collection_enabled"
android:value="false" />
<activity
android:name=".ActivityMainScreen"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivityManagePoi"
android:label="@string/app_name"></activity>
<activity
android:name=".ActivitySettings"
android:label="@string/app_name"></activity>
<service
android:name=".AutomationService"
android:exported="false"
android:label="@string/app_name" />
android:label="@string/app_name"
android:foregroundServiceType="specialUse" >
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Automating things on the device" />
</service>
<receiver android:name=".receivers.StartupIntentReceiver"
android:enabled="true"
@@ -148,6 +144,9 @@
</intent-filter>
</receiver>
<activity android:name=".ActivityMainScreen" android:label="@string/app_name" />
<activity android:name=".ActivityManagePoi" android:label="@string/app_name" />
<activity android:name=".ActivitySettings" android:label="@string/app_name" />
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
@@ -204,7 +203,6 @@
</intent-filter>
-->
<!--
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
@@ -222,9 +220,11 @@
<activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service
android:name=".receivers.NotificationListener"
@@ -258,18 +258,6 @@
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>
@@ -514,8 +514,6 @@ public class Rule implements Comparable<Rule>
protected boolean activateInternally(AutomationService automationService)
{
boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable;
String message;
@@ -556,6 +554,7 @@ public class Rule implements Comparable<Rule>
{
try
{
Miscellaneous.logEvent("i", "RuleExecution", "Running action " + Rule.this.getActionSet().get(i).toStringShort() + " of rule " + Rule.this.getName(), 5);
Rule.this.getActionSet().get(i).run(automationService, doToggle);
}
catch(Exception e)
@@ -593,10 +592,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force)
{
ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
}
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
@@ -8,6 +8,7 @@ import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
@@ -33,13 +34,9 @@ public class Action
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl,
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
turnScreenOnOrOff,
@@ -60,9 +57,10 @@ public class Action
startPhoneCall,
stopPhoneCall,
copyToClipboard,
takeScreenshot,
setLocationService,
sendTextMessage;
sendTextMessage,
takeScreenshot,
setSystemSetting;
public String getFullName(Context context)
{
@@ -80,14 +78,6 @@ public class Action
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation);
case turnWifiOn:
return context.getResources().getString(R.string.actionTurnWifiOn);
case turnWifiOff:
return context.getResources().getString(R.string.actionTurnWifiOff);
case turnBluetoothOn:
return context.getResources().getString(R.string.actionTurnBluetoothOn);
case turnBluetoothOff:
return context.getResources().getString(R.string.actionTurnBluetoothOff);
case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile:
@@ -96,14 +86,6 @@ public class Action
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
case turnWifiTetheringOn:
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
case turnWifiTetheringOff:
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
case enableScreenRotation:
return context.getResources().getString(R.string.actionEnableScreenRotation);
case disableScreenRotation:
return context.getResources().getString(R.string.actionDisableScreenRotation);
case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
@@ -150,6 +132,8 @@ public class Action
return context.getResources().getString(R.string.takeScreenshot);
case setLocationService:
return context.getResources().getString(R.string.setLocationServiceCapital);
case setSystemSetting:
return context.getResources().getString(R.string.setSystemSettingCapital);
default:
return "Unknown";
}
@@ -493,25 +477,9 @@ public class Action
for(Action_Enum action : Action_Enum.values())
{
if( // exclusion for deprecated types
!action.toString().equals("turnWifiOn")
&&
!action.toString().equals("turnWifiOff")
&&
!action.toString().equals("turnBluetoothOn")
&&
!action.toString().equals("turnBluetoothOff")
&&
!action.toString().equals("turnUsbTetheringOn")
&&
!action.toString().equals("turnUsbTetheringOff")
&&
!action.toString().equals("turnWifiTetheringOn")
&&
!action.toString().equals("turnWifiTetheringOff")
&&
!action.toString().equals("enableScreenRotation")
&&
!action.toString().equals("disableScreenRotation")
) // exclusion for deprecated types
actionTypesList.add(action.toString());
}
@@ -525,27 +493,11 @@ public class Action
for(Action_Enum action : Action_Enum.values())
{
if( // exclusion for deprecated types
!action.toString().equals("turnWifiOn")
&&
!action.toString().equals("turnWifiOff")
&&
!action.toString().equals("turnBluetoothOn")
&&
!action.toString().equals("turnBluetoothOff")
&&
!action.toString().equals("turnUsbTetheringOn")
&&
!action.toString().equals("turnUsbTetheringOff")
&&
!action.toString().equals("turnWifiTetheringOn")
&&
!action.toString().equals("turnWifiTetheringOff")
&&
!action.toString().equals("enableScreenRotation")
&&
!action.toString().equals("disableScreenRotation")
) // exclusion for deprecated types
actionTypesList.add(action.getFullName(context));
actionTypesList.add(action.getFullName(context));
}
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
@@ -687,6 +639,10 @@ public class Action
case setLocationService:
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
break;
case setSystemSetting:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
Actions.setSystemSetting(this.getParameter2(), AutomationService.getInstance());
break;
default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break;
@@ -734,8 +690,8 @@ public class Action
try
{
url = Miscellaneous.replaceVariablesInText(url, context);
if(!StringUtils.isEmpty(params))
params = Miscellaneous.replaceVariablesInText(params, context);
// if(!StringUtils.isEmpty(params))
// params = URLEncoder.encode(Miscellaneous.replaceVariablesInText(params, context), "UTF-8");
Actions myAction = new Actions();
@@ -774,7 +730,7 @@ public class Action
if(parameters.length >= 3)
{
urlUsername = parameters[1];
urlPassword = parameters[2];
urlPassword = parameters[2];
if(parameters.length >= 4)
method = parameters[3];
@@ -783,13 +739,24 @@ public class Action
{
// has params
String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter);
String value = "";
for(String pair : paramPairs)
{
String[] pieces = pair.split(Action.actionParameters2SeparatorInner);
httpParams.put(pieces[0], pieces[1]);
try
{
value = Miscellaneous.replaceVariablesInText(pieces[1], Miscellaneous.getAnyContext());
}
catch (Exception e)
{
value = "error";
}
if(pieces.length == 2)
httpParams.put(pieces[0], value);
}
}
}
String response = httpErrorDefaultText;
@@ -802,10 +769,10 @@ public class Action
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"))
// if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
else
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
// else
// response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
try
{
File diff suppressed because it is too large Load Diff
@@ -8,6 +8,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
@@ -40,6 +41,7 @@ public class ActivityControlCenter extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_control_center);
@@ -98,8 +100,17 @@ public class ActivityControlCenter extends Activity
@Override
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, requestCodeImport);
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.importChooseFolderNotice), ActivityControlCenter.this);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialogInterface)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, requestCodeImport);
}
});
dialog.show();
}
});
@@ -22,6 +22,7 @@ public class ActivityDisplayLongMessage extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_display_long_message);
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
@@ -14,6 +14,7 @@ public class ActivityHelp extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(layout.activity_help_text);
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
@@ -45,6 +45,7 @@ public class ActivityMainPoi extends ActivityGeneric
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_poi_layout);
instance = this;
@@ -41,6 +41,7 @@ public class ActivityMainProfiles extends ActivityGeneric
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_profile_layout);
instance = this;
@@ -49,6 +49,7 @@ public class ActivityMainRules extends ActivityGeneric
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_rule_layout);
instance = this;
@@ -196,7 +197,14 @@ public class ActivityMainRules extends ActivityGeneric
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithRule));
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital), getResources().getString(R.string.clone) }, new DialogInterface.OnClickListener()
String toggleEnabled;
if(ruleThisIsAbout.isRuleActive())
toggleEnabled = getResources().getString(R.string.disable);
else
toggleEnabled = getResources().getString(R.string.enable);
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital), toggleEnabled, getResources().getString(R.string.clone) }, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
@@ -248,6 +256,19 @@ public class ActivityMainRules extends ActivityGeneric
deleteDialog.show();
break;
case 3:
ruleToEdit = ruleThisIsAbout;
if(ruleToEdit.isRuleActive())
ruleToEdit.setRuleActive(false);
else
ruleToEdit.setRuleActive(true);
if(ruleToEdit.change(ActivityMainRules.this))
{
ruleToEdit = null; //clear cache
updateListView();
}
break;
case 4:
ruleToEdit = ruleThisIsAbout;
if(ruleToEdit.cloneRule(ActivityMainRules.this))
{
@@ -11,6 +11,7 @@ import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
@@ -46,7 +47,7 @@ public class ActivityMainScreen extends ActivityGeneric
ToggleButton toggleService, tbLockSound;
Button bShowHelp, bPrivacy, bAddSoundLockTIme, bDonate, bControlCenter;
TextView tvActivePoi, tvClosestPoi, tvLastRule, tvLastProfile, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvLockSoundDuration;
TextView tvActivePoi, tvClosestPoi, tvLastRule, tvLastProfile, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvLockSoundDuration, tvContactNotice;
ListView lvRuleHistory;
ArrayAdapter<Rule> ruleHistoryListViewAdapter;
@@ -56,6 +57,7 @@ public class ActivityMainScreen extends ActivityGeneric
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_overview_layout);
activityMainScreenInstance = this;
@@ -83,10 +85,14 @@ public class ActivityMainScreen extends ActivityGeneric
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
tvContactNotice = (TextView) findViewById(R.id.tvContactNotice);
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
bDonate.setVisibility(View.VISIBLE);
// Make links clickable
tvContactNotice.setMovementMethod(LinkMovementMethod.getInstance());
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@@ -122,9 +128,9 @@ public class ActivityMainScreen extends ActivityGeneric
@Override
public void onClick(View v)
{
String privacyPolicyUrl = "https://server47.de/donate";
String donationUrl = "https://server47.de/donate";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(donationUrl));
startActivity(browserIntent);
}
});
@@ -533,6 +539,13 @@ public class ActivityMainScreen extends ActivityGeneric
return;
}
if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34 && !ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, context))
{
Toast.makeText(context, context.getResources().getString(R.string.permissionForegroundServiceTypeSpecialUseRequired), Toast.LENGTH_LONG).show();
activityMainScreenInstance.toggleService.setChecked(false);
return;
}
if (!AutomationService.isMyServiceRunning(context))
{
myServiceIntent = new Intent(context, AutomationService.class);
@@ -590,7 +603,7 @@ public class ActivityMainScreen extends ActivityGeneric
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android9RecordAudioNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
}
if(Build.VERSION.SDK_INT >= 29 && !Settings.noticeAndroid10WifiShown && Rule.isAnyRuleUsing(Action.Action_Enum.setWifi))
if(Miscellaneous.getTargetSDK(ActivityMainScreen.this) >= 29 && !Settings.noticeAndroid10WifiShown && Rule.isAnyRuleUsing(Action.Action_Enum.setWifi))
{
Settings.noticeAndroid10WifiShown = true;
Settings.writeSettings(ActivityMainScreen.this);
@@ -5,6 +5,7 @@ import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.TabHost;
@@ -24,6 +25,7 @@ public class ActivityMainTabLayout extends TabActivity
super.onCreate(savedInstanceState);
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
if(Settings.tabsPlacement == 1)
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
@@ -60,22 +62,24 @@ public class ActivityMainTabLayout extends TabActivity
tabHost.setCurrentTab(Settings.startScreen);
}
@Override
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()));
if(!(getIntent().getAction().isEmpty()) && getIntent().getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
{
NfcReceiver.checkIntentForNFC(this, getIntent());
moveTaskToBack(true);
}
}
@Override
protected void onNewIntent(Intent intent)
{
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5);
// setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent);
}
}
@@ -27,6 +27,7 @@ public class ActivityManageActionBrightnessSetting extends Activity
{
setContentView(R.layout.activity_manage_action_brightness_settings);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
super.onCreate(savedInstanceState);
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
@@ -260,6 +260,7 @@ public class ActivityManageActionCloseNotification extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_close_notification);
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
@@ -20,6 +20,7 @@ public class ActivityManageActionControlMedia extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_control_media);
rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause);
@@ -20,6 +20,7 @@ public class ActivityManageActionCopyToClipboard extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_copy_to_clipboard);
bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard);
@@ -25,6 +25,7 @@ public class ActivityManageActionCreateNotification extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_create_notification);
etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle);
@@ -20,6 +20,7 @@ public class ActivityManageActionLocationService extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_location_service);
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
@@ -22,6 +22,7 @@ public class ActivityManageActionMakePhoneCall extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_make_phone_call);
etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber);
@@ -27,6 +27,7 @@ public class ActivityManageActionPlaySound extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_play_sound);
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
@@ -29,6 +29,7 @@ public class ActivityManageActionRunExecutable extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_run_executable);
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
@@ -38,6 +38,7 @@ public class ActivityManageActionSendBroadcast extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_send_broadcast);
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
@@ -49,6 +49,7 @@ public class ActivityManageActionSendTextMessage extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_send_textmessage);
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
@@ -0,0 +1,157 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class ActivityManageActionSetSystemSetting extends Activity
{
Spinner spinnerSettingDataType;
EditText etSettingName, etSettingValue;
Button bSaveSetSystemSetting;
TextView tvSetSystemSettingExamples, tvSetSystemSettingNoticeWriteSecureSettings;
ArrayAdapter<String> settingDataTypeSpinnerAdapter;
protected final static String[] dataTypes = { "String", "Long", "Int", "Float" };
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_set_system_setting);
spinnerSettingDataType = (Spinner) findViewById(R.id.spinnerSettingDataType);
etSettingName = (EditText)findViewById(R.id.etSettingName);
etSettingValue = (EditText)findViewById(R.id.etSettingValue);
bSaveSetSystemSetting = (Button)findViewById(R.id.bSaveSetSystemSetting);
tvSetSystemSettingExamples = (TextView)findViewById(R.id.tvSetSystemSettingExamples);
tvSetSystemSettingNoticeWriteSecureSettings = (TextView)findViewById(R.id.tvSetSystemSettingNoticeWriteSecureSettings);
settingDataTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, dataTypes);
spinnerSettingDataType.setAdapter(settingDataTypeSpinnerAdapter);
settingDataTypeSpinnerAdapter.notifyDataSetChanged();
tvSetSystemSettingExamples.setMovementMethod(LinkMovementMethod.getInstance());
if(ActivityPermissions.havePermission(Manifest.permission.WRITE_SECURE_SETTINGS, ActivityManageActionSetSystemSetting.this))
tvSetSystemSettingNoticeWriteSecureSettings.setVisibility(View.GONE);
else
tvSetSystemSettingNoticeWriteSecureSettings.setVisibility(View.VISIBLE);
spinnerSettingDataType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
{
if(dataTypes[i].equalsIgnoreCase("String"))
etSettingValue.setInputType(InputType.TYPE_CLASS_TEXT);
else if(dataTypes[i].equalsIgnoreCase("Float"))
etSettingValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
else
etSettingValue.setInputType(InputType.TYPE_CLASS_NUMBER);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView)
{
}
});
bSaveSetSystemSetting.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if(etSettingName.getText().toString().isEmpty())
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterAname), Toast.LENGTH_LONG).show();
return;
}
if(etSettingValue.getText().toString().isEmpty())
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterAvalue), Toast.LENGTH_LONG).show();
return;
}
else
{
String selectedDataType = dataTypes[spinnerSettingDataType.getSelectedItemPosition()];
if(
selectedDataType.equalsIgnoreCase("Int")
||
selectedDataType.equalsIgnoreCase("Long")
)
{
if(Miscellaneous.isNumericDecimal(etSettingValue.getText().toString()) || !Miscellaneous.isNumeric(etSettingValue.getText().toString()))
{
Toast.makeText(ActivityManageActionSetSystemSetting.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
}
else if(selectedDataType.equalsIgnoreCase("Float"))
{
if(!Miscellaneous.isNumeric(etSettingValue.getText().toString()))
{
Toast.makeText(ActivityManageActionSetSystemSetting.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
}
}
Intent returnIntent = new Intent();
String param2Data = dataTypes[spinnerSettingDataType.getSelectedItemPosition()] + Action.actionParameter2Split + etSettingName.getText().toString() + Action.actionParameter2Split + etSettingValue.getText().toString();
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter1, false);
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter2, param2Data);
setResult(RESULT_OK, returnIntent);
finish();
}
});
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
{
// dataType, setting name, setting value
String[] components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
int position = Miscellaneous.arraySearchIndexOf(dataTypes, components[0], false, true);
if(position >= 0)
{
spinnerSettingDataType.setSelection(position);
etSettingName.setText(components[1]);
etSettingValue.setText(components[2]);
}
}
}
private void updateListView()
{
Miscellaneous.logEvent("i", "ListView", "Attempting to update spinnerSettingDataType", 4);
try
{
if(spinnerSettingDataType.getAdapter() == null)
spinnerSettingDataType.setAdapter(settingDataTypeSpinnerAdapter);
settingDataTypeSpinnerAdapter.notifyDataSetChanged();
}
catch(NullPointerException e)
{}
}
}
@@ -25,6 +25,7 @@ public class ActivityManageActionSetVariable extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_set_variable);
etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey);
@@ -23,6 +23,7 @@ public class ActivityManageActionSpeakText extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_speak_text);
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
@@ -32,7 +33,7 @@ public class ActivityManageActionSpeakText extends Activity
@Override
public void onClick(View v)
{
if(etSpeakText.getText().toString().length()>0)
if(!etSpeakText.getText().toString().isEmpty())
{
if(resultingAction == null)
{
@@ -53,11 +53,11 @@ public class ActivityManageActionStartActivity extends Activity
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
Spinner spinnerParameterType;
RadioGroup rgAppStartupType;
boolean edit = false;
// boolean edit = false;
ProgressDialog progressDialog = null;
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService;
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
final String urlShowExamples = "https://server47.de/automation/examples.html";
public final static String startByActivityString = "0";
public final static String startByBroadcastString = "1";
public final static String startByServiceString = "2";
@@ -70,6 +70,7 @@ public class ActivityManageActionStartActivity extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_start_activity);
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
@@ -95,8 +96,6 @@ public class ActivityManageActionStartActivity extends Activity
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
intentTypeSpinnerAdapter.notifyDataSetChanged();
etClassName.setEnabled(false);
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
bSelectApp.setOnClickListener(new OnClickListener()
{
@@ -233,26 +232,29 @@ public class ActivityManageActionStartActivity extends Activity
String parameter2 = "";
if (rbStartAppSelectByActivity.isChecked())
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
else
{
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();
/*
0 = packageName
1 = className
2 = activityName/actionName
3 = startType
4 = parameters
*/
parameter2 += Action.actionParameter2Split + etClassName.getText().toString();
}
parameter2 += etPackageName.getText().toString()
+ Action.actionParameter2Split
+ etClassName.getText().toString()
+ Action.actionParameter2Split
+ etActivityOrActionPath.getText().toString()
+ Action.actionParameter2Split;
if (rbStartAppByActivity.isChecked())
parameter2 += Action.actionParameter2Split + startByActivityString;
parameter2 += startByActivityString;
else if(rbStartAppByService.isChecked())
parameter2 += Action.actionParameter2Split + startByServiceString;
parameter2 += startByServiceString;
else if(rbStartAppByForegroundService.isChecked())
parameter2 += Action.actionParameter2Split + startByForegroundServiceString;
parameter2 += startByForegroundServiceString;
else
parameter2 += Action.actionParameter2Split + startByBroadcastString;
parameter2 += startByBroadcastString;
for (String s : intentPairList)
parameter2 += Action.actionParameter2Split + s;
@@ -316,23 +318,6 @@ 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);
@@ -625,52 +610,36 @@ public class ActivityManageActionStartActivity extends Activity
rbStartAppSelectByActivity.setChecked(!selectionByAction);
rbStartAppSelectByAction.setChecked(selectionByAction);
String[] params;
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
/*
0 = packageName
1 = className
2 = activityName/actionName
3 = startType
4 = parameters
*/
if(partsString.contains(Action.actionParameter2Split))
params = partsString.split(Action.actionParameter2Split);
else
params = partsString.split(";");
try
{
String[] params;
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
if(partsString.contains(Action.actionParameter2Split))
params = partsString.split(Action.actionParameter2Split, -1);
else
params = partsString.split(";", -1);
etPackageName.setText(params[0]);
etClassName.setText(params[1]);
etActivityOrActionPath.setText(params[2]);
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;
if(!selectionByAction)
{
etPackageName.setText(params[0]);
etActivityOrActionPath.setText(params[1]);
}
else
{
if(!params[0].contains(Actions.dummyPackageString))
etPackageName.setText(params[0]);
etActivityOrActionPath.setText(params[1]);
etClassName.setText(params[2]);
}
if (params.length >= 4)
startIndex = 4;
if(startIndex > -1 && params.length > startIndex)
{
intentPairList.clear();
for(int i=startIndex; i<params.length; i++)
for(int i=4; i<params.length; i++)
{
if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE);
@@ -680,6 +649,10 @@ public class ActivityManageActionStartActivity extends Activity
updateIntentPairList();
}
catch(Exception e)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.errorLoadingValues), Toast.LENGTH_LONG).show();
}
}
private void updateIntentPairList()
@@ -19,6 +19,7 @@ import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -38,6 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
CheckBox chkTriggerUrlUseAuthentication;
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
TableLayout tlTriggerUrlAuthentication;
TextView tvHttpParameterExplanation;
ArrayAdapter<String> httpParametersAdapter;
private ArrayList<String> httpParamsList = new ArrayList<>();
@@ -46,14 +48,12 @@ public class ActivityManageActionTriggerUrl extends Activity
public static final String methodGet = "GET";
public static final String methodPost = "POST";
// public static boolean edit = false;
// public static Action resultingAction = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_trigger_url);
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
@@ -69,6 +69,7 @@ public class ActivityManageActionTriggerUrl extends Activity
etParameterName = (EditText) findViewById(R.id.etParameterName);
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam);
tvHttpParameterExplanation = (TextView)findViewById(R.id.tvHttpParameterExplanation);
etParameterName.setEnabled(false);
etParameterValue.setEnabled(false);
@@ -87,6 +88,8 @@ public class ActivityManageActionTriggerUrl extends Activity
}
});
tvHttpParameterExplanation.setText(String.format(getResources().getString(R.string.httpParametersExplanation), Miscellaneous.httpMainData, Miscellaneous.doNoEncodingString));
httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList);
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
@@ -2,10 +2,13 @@ package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.view.View;
@@ -22,12 +25,14 @@ public class ActivityManageActionVibrate extends Activity
{
TextView etVibratePattern;
Button bTestVibratePattern, bSaveVibratePattern;
ProgressDialog pdPleaseWait = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_vibrate);
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
@@ -59,7 +64,20 @@ public class ActivityManageActionVibrate extends Activity
if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this))
{
String pattern = etVibratePattern.getText().toString();
Actions.vibrate(false, pattern);
String[] patternArray = pattern.split(",");
long sum = 0;
for(String element : patternArray)
sum += Long.parseLong(element);
if(sum <= 2000)
Actions.vibrate(false, pattern);
else
{
pdPleaseWait = ProgressDialog.show(ActivityManageActionVibrate.this, null, getResources().getString(R.string.pleaseWait));
VibrateTask vt = new VibrateTask();
vt.execute(pattern);
}
}
}
}
@@ -83,4 +101,22 @@ public class ActivityManageActionVibrate extends Activity
return true;
}
class VibrateTask extends AsyncTask<String, Void, Void>
{
@Override
protected Void doInBackground(String... strings)
{
String pattern = (String)strings[0];
Actions.vibrate(false, pattern);
return null;
}
@Override
protected void onPostExecute(Void unused)
{
pdPleaseWait.dismiss();
super.onPostExecute(unused);
}
}
}
@@ -28,6 +28,7 @@ public class ActivityManageActionWakeLock extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_wakelock);
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
@@ -24,6 +24,7 @@ public class ActivityManageActionWifi extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_wifi);
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
@@ -35,14 +36,14 @@ public class ActivityManageActionWifi extends Activity
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameActionParameter1))
{
rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
rbActionWifiOff.setChecked(!input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
}
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
chkWifiRunAsRoot.setChecked(Boolean.parseBoolean(input.getStringExtra(ActivityManageRule.intentNameActionParameter2)));
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
// Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice), ActivityManageActionWifi.this).show();
if(getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
tvWifiExplanation1.setVisibility(View.VISIBLE);
else
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@@ -7,6 +8,7 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
@@ -23,6 +25,9 @@ import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.PermissionChecker;
import com.jens.automation2.receivers.ConnectivityReceiver;
import java.util.Calendar;
@@ -40,6 +45,7 @@ public class ActivityManagePoi extends Activity
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
Calendar locationSearchStart = null;
Timer timer = null;
int requestCodeGetLocationPermission = 1293;
final static int defaultRadius = 250;
final static int searchTimeout = 120;
@@ -60,6 +66,7 @@ public class ActivityManagePoi extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_specific_poi);
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
@@ -77,7 +84,15 @@ public class ActivityManagePoi extends Activity
public void onClick(View v)
{
hideKeyboard();
getNotificationDialog(getResources().getString(R.string.positioningWindowNotice)).show();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if (ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityManagePoi.this))
getNotificationDialog(getResources().getString(R.string.positioningWindowNotice)).show();
else
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, requestCodeGetLocationPermission);
}
else
getNotificationDialog(getResources().getString(R.string.positioningWindowNotice)).show();
}
});
@@ -111,7 +126,20 @@ public class ActivityManagePoi extends Activity
//else
// new Poi to be created
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if(requestCode == requestCodeGetLocationPermission)
{
if(permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults[0] == PackageManager.PERMISSION_GRANTED)
getNotificationDialog(getResources().getString(R.string.positioningWindowNotice)).show();
else
Toast.makeText(ActivityManagePoi.this, getResources().getString(R.string.locationPermissionRequired), Toast.LENGTH_LONG).show();
}
// super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void createPoi()
{
myLocationManager.removeUpdates(myLocationListenerGps);
@@ -314,20 +342,20 @@ public class ActivityManagePoi extends Activity
public void onClick(DialogInterface dialog, int which)
{
progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
if(Build.VERSION.SDK_INT >= 31)
{
AlertDialog dia = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.locationNotWorkingOn12), ActivityManagePoi.this);
dia.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialogInterface)
{
getLocation();
}
});
dia.show();
}
else
// if(Build.VERSION.SDK_INT >= 31)
// {
// AlertDialog dia = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.locationNotWorkingOn12), ActivityManagePoi.this);
// dia.setOnDismissListener(new DialogInterface.OnDismissListener()
// {
// @Override
// public void onDismiss(DialogInterface dialogInterface)
// {
// getLocation();
// }
// });
// dia.show();
// }
// else
getLocation();
}
};
@@ -1,7 +1,6 @@
package com.jens.automation2;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -28,8 +27,6 @@ import android.widget.Toast;
import androidx.annotation.RequiresApi;
import java.io.File;
public class ActivityManageProfile extends Activity
{
private static ProgressDialog progressDialog;
@@ -37,12 +34,13 @@ public class ActivityManageProfile extends Activity
final static int intentCodeRingtonePickerCallsRingtone = 9011;
final static int intentCodeRingtonePickerNotificationsFile = 9020;
final static int intentCodeRingtonePickerNotificationsRingtone = 9021;
final static String android14Hint = " (>= Android 14)";
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback, checkBoxChangeDnd;
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeRingtone, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback, checkBoxChangeDnd;
Spinner spinnerSoundMode, spinnerDndMode;
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms;
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms, seekBarVolumeRingtones;
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
TextView tvIncomingCallsRingtone, tvNotificationsRingtone;
TextView tvIncomingCallsRingtone, tvNotificationsRingtone, tvRingtoneVolume, tvNotificationsVolume;
EditText etName;
boolean guiUpdate = false;
@@ -87,12 +85,14 @@ public class ActivityManageProfile extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_specific_profile);
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
checkBoxChangeDnd = (CheckBox)findViewById(R.id.checkBoxChangeDnd);
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications);
checkBoxChangeVolumeRingtone = (CheckBox)findViewById(R.id.checkBoxChangeVolumeRingtones);
checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms);
checkBoxChangeIncomingCallsRingtone = (CheckBox)findViewById(R.id.checkBoxChangeIncomingCallsRingtone);
checkBoxChangeNotificationRingtone = (CheckBox)findViewById(R.id.checkBoxChangeNotificationRingtone);
@@ -108,11 +108,14 @@ public class ActivityManageProfile extends Activity
spinnerDndMode = (Spinner)findViewById(R.id.spinnerDndMode);
seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic);
seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications);
seekBarVolumeRingtones = (SeekBar)findViewById(R.id.seekBarVolumeRingtones);
seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms);
bChangeSoundIncomingCalls = (Button)findViewById(R.id.bChangeSoundIncomingCalls);
bChangeSoundNotifications = (Button)findViewById(R.id.bChangeSoundNotifications);
tvIncomingCallsRingtone = (TextView)findViewById(R.id.tvIncomingCallsRingtone);
tvNotificationsRingtone = (TextView)findViewById(R.id.tvNotificationsRingtone);
tvRingtoneVolume = (TextView)findViewById(R.id.tvRingtoneVolume);
tvNotificationsVolume = (TextView)findViewById(R.id.tvNotificationsVolume);
bSaveProfile = (Button)findViewById(R.id.bSaveProfile);
etName = (EditText)findViewById(R.id.etName);
@@ -124,6 +127,7 @@ public class ActivityManageProfile extends Activity
spinnerDndMode.setEnabled(false);
seekBarVolumeMusic.setEnabled(false);
seekBarVolumeNotifications.setEnabled(false);
seekBarVolumeRingtones.setEnabled(false);
seekBarVolumeAlarms.setEnabled(false);
bChangeSoundIncomingCalls.setEnabled(false);
bChangeSoundNotifications.setEnabled(false);
@@ -137,11 +141,36 @@ public class ActivityManageProfile extends Activity
checkBoxChangeDnd.setEnabled(false);
spinnerDndMode.setEnabled(false);
}
if(Build.VERSION.SDK_INT >= 34)
{
checkBoxChangeVolumeRingtone.setEnabled(true);
checkBoxChangeVolumeRingtone.setVisibility(View.VISIBLE);
tvRingtoneVolume.setVisibility(View.VISIBLE);
seekBarVolumeRingtones.setVisibility(View.VISIBLE);
tvNotificationsVolume.setText(getResources().getString(R.string.volumeNotifications));
tvRingtoneVolume.setText(getResources().getString(R.string.volumeRingtone));
}
else
{
checkBoxChangeVolumeRingtone.setEnabled(false);
tvRingtoneVolume.setEnabled(false);
seekBarVolumeRingtones.setEnabled(false);
checkBoxChangeVolumeRingtone.setVisibility(View.GONE);
tvRingtoneVolume.setVisibility(View.GONE);
seekBarVolumeRingtones.setVisibility(View.GONE);
tvNotificationsVolume.setText(getResources().getString(R.string.volumeRingtone) + " + " + getResources().getString(R.string.volumeNotifications));
}
// Scale SeekBars to the system's maximum volume values
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
seekBarVolumeMusic.setMax(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
seekBarVolumeRingtones.setMax(am.getStreamMaxVolume(AudioManager.STREAM_RING));
seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM));
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[]
@@ -201,6 +230,14 @@ public class ActivityManageProfile extends Activity
seekBarVolumeNotifications.setEnabled(isChecked);
}
});
checkBoxChangeVolumeRingtone.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
seekBarVolumeRingtones.setEnabled(isChecked);
}
});
checkBoxChangeVolumeAlarms.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
@@ -336,7 +373,7 @@ public class ActivityManageProfile extends Activity
});
if(ActivityMainProfiles.profileToEdit != null)
editProfile(ActivityMainProfiles.profileToEdit);
loadValuesIntoGui(ActivityMainProfiles.profileToEdit);
//else
// new Profile to be created
@@ -369,7 +406,7 @@ public class ActivityManageProfile extends Activity
}
}
public void editProfile(Profile profileToEdit)
public void loadValuesIntoGui(Profile profileToEdit)
{
guiUpdate = true;
@@ -378,6 +415,7 @@ public class ActivityManageProfile extends Activity
checkBoxChangeDnd.setChecked(ActivityMainProfiles.profileToEdit.getChangeDndMode());
checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia());
checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications());
checkBoxChangeVolumeRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeRingtones());
checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms());
checkBoxChangeIncomingCallsRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeIncomingCallsRingtone());
checkBoxChangeNotificationRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeNotificationRingtone());
@@ -390,6 +428,7 @@ public class ActivityManageProfile extends Activity
spinnerDndMode.setSelection(ActivityMainProfiles.profileToEdit.getDndMode()-1);
seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic());
seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications());
seekBarVolumeRingtones.setProgress(ActivityMainProfiles.profileToEdit.getVolumeRingtones());
seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms());
checkBoxAudibleSelection.setChecked(ActivityMainProfiles.profileToEdit.audibleSelection);
checkBoxScreenLockUnlockSound.setChecked(ActivityMainProfiles.profileToEdit.screenLockUnlockSound);
@@ -414,6 +453,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setChangeDndMode(checkBoxChangeDnd.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeRingtones(checkBoxChangeVolumeRingtone.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked());
ActivityMainProfiles.profileToEdit.setChangeIncomingCallsRingtone(checkBoxChangeIncomingCallsRingtone.isChecked());
ActivityMainProfiles.profileToEdit.setChangeNotificationRingtone(checkBoxChangeNotificationRingtone.isChecked());
@@ -430,6 +470,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setDndMode(spinnerDndMode.getSelectedItemPosition()+1);
ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeRingtones(seekBarVolumeRingtones.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress());
ActivityMainProfiles.profileToEdit.setIncomingCallsRingtone(incomingCallsRingtone);
ActivityMainProfiles.profileToEdit.setNotificationRingtone(notificationsRingtone);
@@ -147,6 +147,10 @@ public class ActivityManageRule extends Activity
final static int requestCodeTriggerCalendarEventEdit = 834;
final static int requestCodeTriggerChargingAdd = 835;
final static int requestCodeTriggerChargingEdit = 836;
final static int requestCodeTriggerProximityAdd = 837;
final static int requestCodeTriggerProximityEdit = 838;
final static int requestCodeActionSetSystemSettingAdd = 839;
final static int requestCodeActionSetSystemSettingEdit = 840;
public static ActivityManageRule getInstance()
{
@@ -161,6 +165,7 @@ public class ActivityManageRule extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_specific_rule);
context = this;
@@ -363,6 +368,12 @@ public class ActivityManageRule extends Activity
chargingStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(chargingStateEditor, requestCodeTriggerChargingEdit);
break;
case proximity:
Intent proximityEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerProximity.class);
proximityEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
proximityEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(proximityEditor, requestCodeTriggerProximityEdit);
break;
default:
break;
}
@@ -501,6 +512,12 @@ public class ActivityManageRule extends Activity
actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit);
break;
case setSystemSetting:
Intent actionSetSystemSettingIntent = new Intent(context, ActivityManageActionSetSystemSetting.class);
// actionSetSystemSettingIntent.putExtra(intentNameActionParameter1, a.getParameter1());
actionSetSystemSettingIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionSetSystemSettingIntent, requestCodeActionSetSystemSettingEdit);
break;
default:
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
break;
@@ -541,7 +558,7 @@ public class ActivityManageRule extends Activity
public void onClick(View v)
{
// Open help popup
Miscellaneous.messageBox(getResources().getString(R.string.whatsThis), getResources().getString(R.string.helpTextToggable), ActivityManageRule.this).show();
Miscellaneous.messageBox(getResources().getString(R.string.whatsThis), getResources().getString(R.string.helpTextToggleable), ActivityManageRule.this).show();
}
});
}
@@ -622,7 +639,7 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Trigger_Enum.phoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS"))
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
items.add(new Item(typesLong[i].toString(), R.drawable.phone));
}
else if(types[i].toString().equals(Trigger_Enum.nfcTag.toString()))
@@ -654,7 +671,10 @@ public class ActivityManageRule extends Activity
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));
{
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.READ_CALENDAR))
items.add(new Item(typesLong[i].toString(), R.drawable.calendar));
}
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@@ -722,6 +742,13 @@ public class ActivityManageRule extends Activity
startActivityForResult(triggerChargingIntent, requestCodeTriggerChargingAdd);
return;
}
else if(triggerType == Trigger_Enum.proximity)
{
newTrigger.setTriggerType(Trigger_Enum.proximity);
Intent triggerProximityIntent = new Intent(myContext, ActivityManageTriggerProximity.class);
startActivityForResult(triggerProximityIntent, requestCodeTriggerProximityAdd);
return;
}
else if(triggerType == Trigger_Enum.musicPlaying)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection)
@@ -1483,19 +1510,43 @@ public class ActivityManageRule extends Activity
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerProximityAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, false));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerChargingEdit)
{
if(resultCode == RESULT_OK)
{
Trigger responseTimeFrame = new Trigger();
responseTimeFrame.setTriggerType(Trigger_Enum.charging);
responseTimeFrame.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
responseTimeFrame.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
responseTimeFrame.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, responseTimeFrame);
Trigger chargingStateTrigger = new Trigger();
chargingStateTrigger.setTriggerType(Trigger_Enum.charging);
chargingStateTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
chargingStateTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
chargingStateTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, chargingStateTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerProximityEdit)
{
if(resultCode == RESULT_OK)
{
Trigger proximityTrigger = new Trigger();
proximityTrigger.setTriggerType(Trigger_Enum.proximity);
proximityTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
proximityTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
proximityTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, proximityTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeActionStartActivityAdd)
{
// manage start of other activity
@@ -2174,6 +2225,32 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetSystemSettingAdd)
{
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 == requestCodeActionSetSystemSettingEdit)
{
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();
}
}
}
protected AlertDialog getActionTypeDialog()
@@ -2235,27 +2312,33 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.script));
else if(types[i].toString().equals(Action_Enum.startPhoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.CALL_PHONE))
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.CALL_PHONE))
items.add(new Item(typesLong[i].toString(), R.drawable.phone));
}
else if(types[i].toString().equals(Action_Enum.stopPhoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.ANSWER_PHONE_CALLS))
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.ANSWER_PHONE_CALLS))
items.add(new Item(typesLong[i].toString(), R.drawable.phone));
}
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
items.add(new Item(typesLong[i].toString(), R.drawable.message));
}
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 if(types[i].toString().equals(Action_Enum.takeScreenshot.toString()))
{
if(ActivityPermissions.isServiceAvailable(Miscellaneous.getAnyContext(), "MyAccessibilityService"))
items.add(new Item(typesLong[i].toString(), R.drawable.copier));
}
else if(types[i].toString().equals(Action_Enum.setSystemSetting.toString()))
{ items.add(new Item(typesLong[i].toString(), R.drawable.gears_small));
}
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@@ -2288,28 +2371,28 @@ public class ActivityManageRule extends Activity
{
newAction = new Action();
if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.triggerUrl.toString()))
CharSequence[] actionTypes = Action.getActionTypesAsArray();
if(actionTypes[which].toString().equals(Action_Enum.triggerUrl.toString()))
{
//launch other activity to enter a url and parameters;
newAction.setAction(Action_Enum.triggerUrl);
// ActivityManageActionTriggerUrl.resultingAction = null;
Intent editTriggerIntent = new Intent(context, ActivityManageActionTriggerUrl.class);
startActivityForResult(editTriggerIntent, requestCodeActionTriggerUrlAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifi.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setWifi.toString()))
{
newAction.setAction(Action_Enum.setWifi);
Intent editSetWifiIntent = new Intent(context, ActivityManageActionWifi.class);
startActivityForResult(editSetWifiIntent, requestCodeActionSetWifiAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetooth.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setBluetooth.toString()))
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
newAction.setAction(Action_Enum.setBluetooth);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setUsbTethering.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setUsbTethering.toString()))
{
newAction.setAction(Action_Enum.setUsbTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
@@ -2317,12 +2400,12 @@ public class ActivityManageRule extends Activity
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1)
Miscellaneous.messageBox(context.getResources().getString(R.string.warning), context.getResources().getString(R.string.usbTetheringFailForAboveGingerbread), context).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifiTethering.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setWifiTethering.toString()))
{
newAction.setAction(Action_Enum.setWifiTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetoothTethering.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setBluetoothTethering.toString()))
{
newAction.setAction(Action_Enum.setBluetoothTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
@@ -2333,12 +2416,12 @@ public class ActivityManageRule extends Activity
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
Miscellaneous.messageBox(context.getResources().getString(R.string.notice), context.getResources().getString(R.string.btTetheringNotice), context).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDisplayRotation.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setDisplayRotation.toString()))
{
newAction.setAction(Action_Enum.setDisplayRotation);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.changeSoundProfile.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.changeSoundProfile.toString()))
{
if(Profile.getProfileCollection().size() > 0)
{
@@ -2348,23 +2431,23 @@ public class ActivityManageRule extends Activity
else
Toast.makeText(context, getResources().getString(R.string.noProfilesCreateOneFirst), Toast.LENGTH_LONG).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.startOtherActivity.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.startOtherActivity.toString()))
{
newAction.setAction(Action_Enum.startOtherActivity);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
startActivityForResult(intent, requestCodeActionStartActivityAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.waitBeforeNextAction.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.waitBeforeNextAction.toString()))
{
newAction.setAction(Action_Enum.waitBeforeNextAction);
getActionWaitBeforeNextActionDialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
{
newAction.setAction(Action_Enum.turnScreenOnOrOff);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setAirplaneMode.toString()))
{
newAction.setAction(Action_Enum.setAirplaneMode);
getActionParameter1Dialog(ActivityManageRule.this).show();
@@ -2373,13 +2456,13 @@ public class ActivityManageRule extends Activity
Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
}
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDataConnection.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setDataConnection.toString()))
{
newAction.setAction(Action_Enum.setDataConnection);
getActionParameter1Dialog(ActivityManageRule.this).show();
Miscellaneous.messageBox(getResources().getString(R.string.actionDataConnection), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.speakText.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.speakText.toString()))
{
//launch other activity to enter a url and parameters;
newAction.setAction(Action_Enum.speakText);
@@ -2387,9 +2470,9 @@ public class ActivityManageRule extends Activity
Intent editTriggerIntent = new Intent(context, ActivityManageActionSpeakText.class);
startActivityForResult(editTriggerIntent, requestCodeActionSpeakTextAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.sendTextMessage.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
{
//launch other activity to enter parameters;
newAction.setAction(Action_Enum.sendTextMessage);
@@ -2398,102 +2481,108 @@ public class ActivityManageRule extends Activity
startActivityForResult(editTriggerIntent, requestCodeActionSendTextMessageAdd);
}
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.playMusic.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.playMusic.toString()))
{
newAction.setAction(Action_Enum.playMusic);
ruleToEdit.getActionSet().add(newAction);
refreshActionList();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.vibrate.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.vibrate.toString()))
{
newAction.setAction(Action_Enum.vibrate);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
startActivityForResult(intent, requestCodeActionVibrateAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendBroadcast.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.sendBroadcast.toString()))
{
newAction.setAction(Action_Enum.sendBroadcast);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
startActivityForResult(intent, requestCodeActionSendBroadcastAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.runExecutable.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.runExecutable.toString()))
{
newAction.setAction(Action_Enum.runExecutable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
startActivityForResult(intent, requestCodeActionRunExecutableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.startPhoneCall.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.startPhoneCall.toString()))
{
newAction.setAction(Action_Enum.startPhoneCall);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionMakePhoneCall.class);
startActivityForResult(intent, requestCodeActionMakePhoneCallAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setVariable.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setVariable.toString()))
{
newAction.setAction(Action_Enum.setVariable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSetVariable.class);
startActivityForResult(intent, requestCodeActionSetVariableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.stopPhoneCall.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.stopPhoneCall.toString()))
{
newAction.setAction(Action_Enum.stopPhoneCall);
ruleToEdit.getActionSet().add(newAction);
refreshActionList();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.wakelock.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.wakelock.toString()))
{
newAction.setAction(Action_Enum.wakelock);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
startActivityForResult(intent, requestCodeActionWakeLockAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.controlMediaPlayback.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.controlMediaPlayback.toString()))
{
newAction.setAction(Action_Enum.controlMediaPlayback);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionControlMedia.class);
startActivityForResult(intent, requestCodeActionControlMediaAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.createNotification.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.createNotification.toString()))
{
newAction.setAction(Action_Enum.createNotification);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCreateNotification.class);
startActivityForResult(intent, requestCodeActionCreateNotificationAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.closeNotification.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.closeNotification.toString()))
{
newAction.setAction(Action_Enum.closeNotification);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCloseNotification.class);
startActivityForResult(intent, requestCodeActionCloseNotificationAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setScreenBrightness.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.setScreenBrightness.toString()))
{
newAction.setAction(Action_Enum.setScreenBrightness);
Intent actionScreenBrightnessIntent = new Intent(context, ActivityManageActionBrightnessSetting.class);
startActivityForResult(actionScreenBrightnessIntent, requestCodeActionScreenBrightnessAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.playSound.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.playSound.toString()))
{
newAction.setAction(Action_Enum.playSound);
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.copyToClipboard.toString()))
else if(actionTypes[which].toString().equals(Action_Enum.copyToClipboard.toString()))
{
newAction.setAction(Action_Enum.copyToClipboard);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.takeScreenshot.toString()))
else if(actionTypes[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()))
else if(actionTypes[which].toString().equals(Action_Enum.setLocationService.toString()))
{
newAction.setAction(Action_Enum.setLocationService);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class);
startActivityForResult(intent, requestCodeActionSetLocationServiceAdd);
}
else if(actionTypes[which].toString().equals(Action_Enum.setSystemSetting.toString()))
{
newAction.setAction(Action_Enum.setSystemSetting);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSetSystemSetting.class);
startActivityForResult(intent, requestCodeActionSetSystemSettingAdd);
}
}
});
@@ -1,8 +1,10 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
@@ -16,23 +18,27 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.jens.automation2.receivers.BluetoothReceiver;
public class ActivityManageTriggerBluetooth extends Activity
{
final static int requestPermissionCodeBluetoothConnect = 4711;
protected static Trigger editedBluetoothTrigger;
RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange;
Button bSaveBluetoothTrigger;
Spinner spinnerBluetoothDevices;
TextView tvBluetoothNotPresentNotice;
ArrayAdapter<String> bluetoothDevicesSpinnerAdapter;
ArrayAdapter<String> bluetoothDevicesSpinnerAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_bluetooth);
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
@@ -45,8 +51,6 @@ public class ActivityManageTriggerBluetooth extends Activity
bSaveBluetoothTrigger = (Button)findViewById(R.id.bSaveBluetoothTrigger);
spinnerBluetoothDevices = (Spinner)findViewById(R.id.spinnerBluetoothDevices);
tvBluetoothNotPresentNotice = (TextView)findViewById(R.id.tvBluetoothNotPresentNotice);
bluetoothDevicesSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, BluetoothReceiver.getAllPairedBluetoothDevicesStrings());
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
tvBluetoothNotPresentNotice.setVisibility(View.VISIBLE);
@@ -74,17 +78,37 @@ public class ActivityManageTriggerBluetooth extends Activity
}
}
});
refreshBluetoothDeviceSpinner();
spinnerBluetoothDevices.setEnabled(false);
if(Miscellaneous.getTargetSDK(ActivityManageTriggerBluetooth.this) >= 31 && !ActivityPermissions.havePermission(Manifest.permission.BLUETOOTH_CONNECT, ActivityManageTriggerBluetooth.this))
requestPermissions(new String[] {Manifest.permission.BLUETOOTH_CONNECT }, requestPermissionCodeBluetoothConnect);
else
refreshBluetoothDeviceSpinner();
spinnerBluetoothDevices.setEnabled(false);
if(editedBluetoothTrigger.getBluetoothDeviceAddress() != null && editedBluetoothTrigger.getBluetoothDeviceAddress().length() > 0)
loadVariableIntoGui();
}
protected void refreshBluetoothDeviceSpinner()
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == requestPermissionCodeBluetoothConnect)
{
if(permissions[0].equals(Manifest.permission.BLUETOOTH_CONNECT) && grantResults[0] == PackageManager.PERMISSION_GRANTED)
refreshBluetoothDeviceSpinner();
}
}
protected void refreshBluetoothDeviceSpinner()
{
Miscellaneous.logEvent("i", "Spinner", "Attempting to update spinnerBluetoothDevices", 4);
if(bluetoothDevicesSpinnerAdapter == null)
bluetoothDevicesSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, BluetoothReceiver.getAllPairedBluetoothDevicesStrings());
if(spinnerBluetoothDevices.getAdapter() == null)
{
spinnerBluetoothDevices.setAdapter(bluetoothDevicesSpinnerAdapter);
@@ -29,6 +29,7 @@ public class ActivityManageTriggerBroadcast extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_broadcasts);
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
@@ -51,6 +51,7 @@ public class ActivityManageTriggerCalendar extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_calendar);
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
@@ -10,12 +10,7 @@ import android.widget.RadioButton;
import androidx.annotation.Nullable;
import com.jens.automation2.ActivityManageRule;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.R;
import com.jens.automation2.Trigger;
import org.apache.commons.lang3.StringUtils;
import com.jens.automation2.receivers.BatteryReceiver;
public class ActivityManageTriggerCharging extends Activity
{
@@ -27,6 +22,7 @@ public class ActivityManageTriggerCharging extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_charging);
rbChargingOn = (RadioButton) findViewById(R.id.rbChargingOn);
@@ -69,13 +65,13 @@ public class ActivityManageTriggerCharging extends Activity
String param2 = "";
if(rbChargingTypeAny.isChecked())
param2 = "0";
param2 = String.valueOf(BatteryReceiver.batteryChargingTypeAny);
else if(rbChargingTypeAc.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_AC);
param2 = String.valueOf(BatteryReceiver.batteryChargingTypeAc);
else if(rbChargingTypeUsb.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_USB);
param2 = String.valueOf(BatteryReceiver.batteryChargingTypeUsb);
else if(rbChargingTypeWireless.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_WIRELESS);
param2 = String.valueOf(BatteryReceiver.batteryChargingTypeWireless);
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, param2);
@@ -5,6 +5,8 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import androidx.annotation.Nullable;
@@ -14,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerCheckVariable extends Activity
{
EditText etVariableKeyTrigger, etVariableValueTrigger;
CheckBox chkTriggerVariableDirection;
Button bTriggerVariableSave;
@Override
@@ -21,13 +24,19 @@ public class ActivityManageTriggerCheckVariable extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_check_variable);
etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger);
etVariableValueTrigger = (EditText) findViewById(R.id.etVariableValueTrigger);
chkTriggerVariableDirection = (CheckBox)findViewById(R.id.chkTriggerVariableDirection);
bTriggerVariableSave = (Button) findViewById(R.id.bTriggerVariableSave);
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
chkTriggerVariableDirection.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{
String[] conditions = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
@@ -36,13 +45,26 @@ public class ActivityManageTriggerCheckVariable extends Activity
etVariableValueTrigger.setText(conditions[1]);
}
chkTriggerVariableDirection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
{
if(checked)
chkTriggerVariableDirection.setText(getResources().getString(R.string.matches));
else
chkTriggerVariableDirection.setText(getResources().getString(R.string.doesNotMatch));
}
});
bTriggerVariableSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent response = new Intent();
// response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbTetheringOn.isChecked());
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkTriggerVariableDirection.isChecked());
if(StringUtils.isEmpty(etVariableValueTrigger.getText().toString()))
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, etVariableKeyTrigger.getText().toString());
@@ -105,6 +105,7 @@ public class ActivityManageTriggerDeviceOrientation extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_device_orientation);
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
@@ -40,6 +40,7 @@ public class ActivityManageTriggerNfc extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_nfc);
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
@@ -150,7 +151,12 @@ public class ActivityManageTriggerNfc extends Activity
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
final PendingIntent pendingIntent;
if(Miscellaneous.getTargetSDK(activity) >= 31)
pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE);
else
pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
@@ -185,7 +191,7 @@ public class ActivityManageTriggerNfc extends Activity
@Override
protected void onPause()
{
/**
/*
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/
disableForegroundDispatch(this);
@@ -197,7 +203,7 @@ public class ActivityManageTriggerNfc extends Activity
protected void onResume()
{
super.onResume();
/**
/*
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
@@ -231,10 +237,18 @@ public class ActivityManageTriggerNfc extends Activity
if(currentStatus == 0)
{
generatedId = NfcReceiver.readTag(discoveredTag);
if(generatedId != null && generatedId.length() > 0)
tvCurrentNfcId.setText(generatedId);
if(generatedId != null && generatedId.length() > 0)
{
tvCurrentNfcId.setText(generatedId);
bReadNfcTag.setEnabled(true);
bUseValueCurrentlyStored.setEnabled(true);
}
else
tvCurrentNfcId.setText(getResources().getString(R.string.nfcTagDataNotUsable));
{
tvCurrentNfcId.setText(getResources().getString(R.string.nfcTagDataNotUsable));
bReadNfcTag.setEnabled(false);
bUseValueCurrentlyStored.setEnabled(false);
}
}
else if(currentStatus == 1)
{
@@ -259,6 +259,7 @@ public class ActivityManageTriggerNotification extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_notification);
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
@@ -36,6 +36,7 @@ public class ActivityManageTriggerPhoneCall extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_phone_call);
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
@@ -32,6 +32,7 @@ public class ActivityManageTriggerProfile extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_profile);
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile);
@@ -0,0 +1,172 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.wifi.ScanResult;
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.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.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import com.google.android.material.slider.RangeSlider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ActivityManageTriggerProximity extends Activity
{
TextView tvTriggerProximityHint, tvProximityCurrentValue;
Button bTriggerProximitySave;
RangeSlider rsProximity;
SeekBar sbProximityTest;
SensorManager sensorManager;
Sensor proximitySensor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
/*
A modern theme is required for this activity because of the RangeSlider.
The value configured in settings is ignored.
*/
this.setTheme(R.style.AppThemeMaterial);
setContentView(R.layout.activity_manage_trigger_proximity);
rsProximity = (RangeSlider) findViewById(R.id.rsProximity);
sbProximityTest = (SeekBar) findViewById(R.id.sbProximityTest);
tvTriggerProximityHint = (TextView) findViewById(R.id.tvTriggerProximityHint);
tvProximityCurrentValue = (TextView) findViewById(R.id.tvProximityCurrentValue);
bTriggerProximitySave = (Button) findViewById(R.id.bTriggerProximitySave);
sbProximityTest.setEnabled(false);
tvTriggerProximityHint.setVisibility(View.GONE);
bTriggerProximitySave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Intent response = new Intent();
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, String.valueOf(rsProximity.getValues().get(0)) + Trigger.triggerParameter2Split + String.valueOf(rsProximity.getValues().get(1)));
setResult(RESULT_OK, response);
finish();
}
});
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{
String[] values = getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
rsProximity.setValues(Float.parseFloat(values[0]), Float.parseFloat(values[1]));
}
else
rsProximity.setValues(0f, 10f);
}
@Override
protected void onResume()
{
super.onResume();
startPreview();
}
@Override
protected void onPause()
{
super.onPause();
stopPreview();
}
void startPreview()
{
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// from sensor service we are
// calling proximity sensor
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// handling the case if the proximity
// sensor is not present in users device.
if (proximitySensor == null)
{
tvTriggerProximityHint.setVisibility(View.VISIBLE);
finish();
}
else
{
// registering our sensor with sensor manager.
sensorManager.registerListener(proximitySensorEventListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
void stopPreview()
{
if(proximitySensor != null)
sensorManager.unregisterListener(proximitySensorEventListener);
}
SensorEventListener proximitySensorEventListener = new SensorEventListener()
{
@Override
public void onSensorChanged(SensorEvent sensorEvent)
{
// check if the sensor type is proximity sensor.
if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY)
{
sbProximityTest.setProgress((int)sensorEvent.values[0]);
tvProximityCurrentValue.setText((String.valueOf(sensorEvent.values[0])));
// if (sensorEvent.values[0] == 0)
// {
// here we are setting our status to our textview..
// if sensor event return 0 then object is closed
// to sensor else object is away from sensor.
// sensorStatusTV.setText("Near");
// }
// else
// {
// sensorStatusTV.setText("Away");
// }
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i)
{
}
};
}
@@ -22,6 +22,7 @@ public class ActivityManageTriggerSubSystemState extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_subsystemstate);
rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi);
@@ -27,6 +27,7 @@ public class ActivityManageTriggerTethering extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_tethering);
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -36,12 +37,22 @@ public class ActivityManageTriggerTimeFrame extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
/*
A modern theme is required for this activity. Classic theme can cause crashes with the TimePicker.
The value configured in settings is ignored.
*/
this.setTheme(R.style.AppThemeCompat);
setContentView(R.layout.activity_manage_trigger_timeframe);
// if(Build.VERSION.SDK_INT == 34)
// Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.Android14TimePickerHint), ActivityManageTriggerTimeFrame.this).show();
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
startPicker.setIs24HourView(true);
stopPicker.setIs24HourView(true);
stopPicker.setIs24HourView(true);
bSaveTimeFrame = (Button)findViewById(R.id.bSaveTimeFrame);
checkMonday = (CheckBox)findViewById(R.id.checkMonday);
@@ -15,7 +15,6 @@ 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;
@@ -54,6 +53,7 @@ public class ActivityManageTriggerWifi extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_wifi);
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
@@ -74,7 +74,7 @@ public class ActivityManageTriggerWifi extends Activity
if(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
&&
!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
tvWifiTriggerNameLocationNotice.setVisibility(View.VISIBLE);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
@@ -11,6 +12,8 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
@@ -25,9 +28,9 @@ import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.jens.automation2.receivers.NotificationListener;
import androidx.core.content.ContextCompat;
import org.w3c.dom.DOMImplementationSource;
import com.jens.automation2.receivers.NotificationListener;
import java.util.ArrayList;
import java.util.Arrays;
@@ -66,6 +69,7 @@ public class ActivityPermissions extends Activity
public final static String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
public final static String permissionNameGoogleActivityDetection = "com.google.android.gms.permission.ACTIVITY_RECOGNITION";
public final static String permissionNameSuperuser = "android.permission.ACCESS_SUPERUSER";
public final static String permissionNameProximity = "android.hardware.sensor.proximity";
public static ActivityPermissions getInstance()
{
@@ -84,6 +88,7 @@ public class ActivityPermissions extends Activity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.permissions_activity);
bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions);
@@ -276,6 +281,19 @@ public class ActivityPermissions extends Activity
return false;
}
public static int getAmountOfRulesWhichLackPermissions(Context context)
{
int rulesWhichLackPermissions = 0;
for(Rule r : Rule.getRuleCollection())
{
if(!ActivityPermissions.havePermissionsForRule(r, context))
rulesWhichLackPermissions++;
}
return rulesWhichLackPermissions;
}
public static boolean havePermission(String s, Context context)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
@@ -314,9 +332,20 @@ public class ActivityPermissions extends Activity
{
return haveAccessibilityAccess(Miscellaneous.getAnyContext());
}
else if(s.equals(Manifest.permission.SCHEDULE_EXACT_ALARM) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
/*
It appears like as long as targetSdk has not been raised, this check
will return true even if the slider in the settings for that
permission is not enabled.
*/
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
return alarmManager.canScheduleExactAlarms();
}
else
{
int res = context.checkCallingOrSelfPermission(s);
// int res = context.checkCallingOrSelfPermission(s);
int res = ContextCompat.checkSelfPermission(context, s);
return (res == PackageManager.PERMISSION_GRANTED);
}
}
@@ -424,6 +453,11 @@ public class ActivityPermissions extends Activity
}
}
if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34 && !havePermission(Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, workingContext))
{
addToArrayListUnique(Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, requiredPermissions);
}
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
@@ -515,6 +549,8 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
if(Build.VERSION.SDK_INT >= 31)
addToArrayListUnique(Manifest.permission.BLUETOOTH_CONNECT, requiredPermissions);
break;
case charging:
// addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
@@ -565,7 +601,10 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
break;
case timeFrame:
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31
||
Build.VERSION.SDK_INT >= 34 //https://developer.android.com/about/versions/14/changes/schedule-exact-alarms
)
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
break;
case usb_host_connection:
@@ -579,7 +618,7 @@ public class ActivityPermissions extends Activity
(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
&&
isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
||
Build.VERSION.SDK_INT >= 33
@@ -594,6 +633,10 @@ public class ActivityPermissions extends Activity
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
break;
// Proximity permission cannot be requested, but is always granted.
case proximity:
// addToArrayListUnique(ActivityPermissions.permissionNameProximity, requiredPermissions);
break;
default:
break;
}
@@ -611,12 +654,6 @@ public class ActivityPermissions extends Activity
if(targetProfile.changeIncomingCallsRingtone || targetProfile.changeNotificationRingtone)
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
break;
case disableScreenRotation:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case enableScreenRotation:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case playMusic:
break;
case controlMediaPlayback:
@@ -703,7 +740,7 @@ public class ActivityPermissions extends Activity
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
if(Build.VERSION.SDK_INT >= 29)
{
String parts[];
String[] parts;
if(action.getParameter2().contains(Action.actionParameter2Split))
parts = action.getParameter2().split(Action.actionParameter2Split);
else
@@ -711,7 +748,15 @@ public class ActivityPermissions extends Activity
// Permission only required for starts of activity, not broadcasts or services
if(parts[2].equals(ActivityManageActionStartActivity.startByActivityString))
if(
(
parts.length >= 4
&&
parts[3].equals(ActivityManageActionStartActivity.startByActivityString)
)
||
parts[2].equals(ActivityManageActionStartActivity.startByActivityString)
)
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
}
break;
@@ -719,40 +764,12 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions);
break;
case turnBluetoothOff:
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnBluetoothOn:
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnUsbTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case turnUsbTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case turnWifiOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case waitBeforeNextAction:
break;
case playSound:
@@ -778,8 +795,12 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions);
break;
case setLocationService:
case setSystemSetting:
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
break;
case setScreenBrightness:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
default:
break;
}
@@ -898,18 +919,6 @@ public class ActivityPermissions extends Activity
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setWifiTethering))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnWifiOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnWifiOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnWifiTetheringOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnWifiTetheringOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.ACCESS_WIFI_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
@@ -918,24 +927,12 @@ public class ActivityPermissions extends Activity
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.BLUETOOTH_ADMIN:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.BLUETOOTH:
case Manifest.permission.BLUETOOTH_CONNECT:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.GET_TASKS:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.process_started_stopped))
@@ -1042,11 +1039,18 @@ public class ActivityPermissions extends Activity
case Manifest.permission.WRITE_SECURE_SETTINGS:
for(String ruleName : getRulesUsing(Action.Action_Enum.setLocationService))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setSystemSetting))
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;
// Proximity permission cannot be requested, but is always granted.
// case ActivityPermissions.permissionNameProximity:
// for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.proximity))
// usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
// break;
}
return usingElements;
@@ -1064,7 +1068,7 @@ public class ActivityPermissions extends Activity
required permissions have been granted.
*/
super.onActivityResult(requestCode, resultCode, data);
// super.onActivityResult(requestCode, resultCode, data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
@@ -1127,16 +1131,16 @@ public class ActivityPermissions extends Activity
ArrayList<String> permissionList = new ArrayList<String>();
for(String permission : permissionNames)
{
if(permissionNames.equals(Manifest.permission.PROCESS_OUTGOING_CALLS))
if(permission.equals(Manifest.permission.PROCESS_OUTGOING_CALLS))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.PROCESS_OUTGOING_CALLS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
if(ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.PROCESS_OUTGOING_CALLS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
{
permissionList.add(permission);
}
}
else if(permissionNames.equals(Manifest.permission.SEND_SMS))
else if(permission.equals(Manifest.permission.SEND_SMS))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
if(ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
{
permissionList.add(permission);
}
@@ -1305,7 +1309,7 @@ public class ActivityPermissions extends Activity
{
if(requiredPermissions.contains(Manifest.permission.PROCESS_OUTGOING_CALLS))
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
if(!ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
&&
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
)
@@ -1316,7 +1320,7 @@ public class ActivityPermissions extends Activity
}
if(requiredPermissions.contains(Manifest.permission.SEND_SMS))
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
if(!ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
)
{
requiredPermissions.remove(Manifest.permission.SEND_SMS);
@@ -1686,12 +1690,53 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK);
}
public static boolean isPermissionDeclaratedInManifest(Context context, String permission)
public static boolean isServiceAvailable(Context context, String serviceName)
{
/*int flags = PackageManager.GET_ACTIVITIES
| PackageManager.GET_CONFIGURATIONS
| PackageManager.GET_DISABLED_COMPONENTS
| PackageManager.GET_GIDS | PackageManager.GET_INSTRUMENTATION
| PackageManager.GET_INTENT_FILTERS
| PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
| PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
| PackageManager.GET_SIGNATURES;
PackageManager packageManager = getPackageManager();
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(flags);
for (PackageInfo packageInfo : installedPackages)
{
ServiceInfo[] services = packageInfo.services;
PermissionInfo[] permissions = packageInfo.permissions;
}*/
StringBuffer buffer = new StringBuffer();
try
{
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo("com.jens.automation2", PackageManager.GET_SERVICES);
ServiceInfo[] services = packageInfo.services;
for (ServiceInfo serviceInfo : services)
{
if(serviceInfo.name.endsWith(serviceName))
return true;
}
PermissionInfo[] permissions = packageInfo.permissions;
}
catch (PackageManager.NameNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public static boolean isPermissionDeclaredInManifest(Context context, String permission)
{
PackageManager pm = context.getPackageManager();
try
{
PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] requestedPermissions = null;
if (packageInfo != null)
{
@@ -17,6 +17,13 @@ public class ActivitySettings extends PreferenceActivity
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
// Dark Theme doesn't work in PreferenceActivity, so only a bright theme is readable
if(Settings.uiTheme != 0)
this.setTheme(R.style.AppThemeCompatLight);
// Miscellaneous.setUiTheme(this);
addPreferencesFromResource(layout.activity_settings);
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
@@ -31,6 +31,7 @@ public class ActivityVolumeTest extends Activity
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_volume_calibration);
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
@@ -1,5 +1,7 @@
package com.jens.automation2;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -12,6 +14,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Build;
@@ -156,6 +159,15 @@ public class AutomationService extends Service implements OnInitListener
ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE);
return false;
}
else
{
if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34 && !ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE_SPECIAL_USE, context))
{
Toast.makeText(context, context.getResources().getString(R.string.permissionForegroundServiceTypeSpecialUseRequired), Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("e", "Permission", "Don't have permission FOREGROUND_SERVICE_SPECIAL_USE. Will request it now.", 4);
return false;
}
}
}
if (
@@ -168,6 +180,17 @@ public class AutomationService extends Service implements OnInitListener
Rule.getRuleCollection().size() == 0
)
{
if(
Rule.getRuleCollection().size() > 0
&&
Rule.getRuleCollection().size() == ActivityPermissions.getAmountOfRulesWhichLackPermissions(Miscellaneous.getAnyContext())
)
{
Miscellaneous.logEvent("w", "AutomationService", "Don't have complete permissions for any defined rule. Not starting service.", 1);
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStartPermissions), Toast.LENGTH_LONG).show();
return false;
}
if (startAtBoot)
{
/*
@@ -243,7 +266,7 @@ public class AutomationService extends Service implements OnInitListener
updateNotification();
if (isMainActivityRunning(this))
if(isMainActivityRunning(this))
ActivityMainScreen.updateMainScreen();
this.isRunning = true;
@@ -320,8 +343,10 @@ public class AutomationService extends Service implements OnInitListener
ReceiverCoordinator.applySettingsAndRules();
DateTimeListener.reloadAlarms();
CalendarReceiver.armOrRearmTimer();
DateTimeListener.setOrResetAlarms();
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent) && ActivityPermissions.isPermissionDeclaredInManifest(AutomationService.getInstance(), Manifest.permission.READ_CALENDAR) && ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, AutomationService.getInstance()))
CalendarReceiver.armOrRearmTimer();
}
@Override
@@ -390,6 +415,20 @@ public class AutomationService extends Service implements OnInitListener
r.activate(AutomationService.this, false);
}
if(!Settings.hasBeenDone(Settings.constVersion143StartOtherProgramConfigEditHint))
{
if(Rule.isAnyRuleUsing(Action.Action_Enum.startOtherActivity))
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
Miscellaneous.createDismissibleNotificationWithDelay(1010, null, getResources().getString(R.string.version143StartOtherActivityHint), 9123, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, null);
else
Miscellaneous.createDismissibleNotification(null, getResources().getString(R.string.version143StartOtherActivityHint), 9123, false, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, null);
}
Settings.considerDone(Settings.constVersion143StartOtherProgramConfigEditHint);
Settings.writeSettings(Miscellaneous.getAnyContext());
}
Settings.serviceStartDone = true;
Settings.deviceStartDone = true;
}
@@ -476,7 +515,12 @@ public class AutomationService extends Service implements OnInitListener
if(Miscellaneous.googleToBlameForLocation(true))
{
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
PendingIntent pi;
// if(Miscellaneous.getTargetSDK(AutomationService.this) >= Build.VERSION_CODES.S)
pi = PendingIntent.getActivity(AutomationService.this, 0, intent, FLAG_IMMUTABLE);
// else
// pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
@@ -493,6 +537,7 @@ public class AutomationService extends Service implements OnInitListener
{
Intent myServiceIntent = new Intent(context, AutomationService.class);
myServiceIntent.putExtra("startAtBoot", startAtBoot);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(myServiceIntent);
else
@@ -527,42 +572,6 @@ public class AutomationService extends Service implements OnInitListener
centralInstance = null;
Settings.serviceStartDone = false;
}
protected static Builder createDefaultNotificationBuilderOld()
{
Builder builder = new Builder(AutomationService.getInstance());
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());
builder.setContentIntent(myPendingIntent);
Notification defaultNotification = builder.build();
defaultNotification.icon = R.drawable.crane;
defaultNotification.when = System.currentTimeMillis();
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
// defaultNotification.defaults |= Notification.DEFAULT_LIGHTS;
defaultNotification.flags |= Notification.FLAG_AUTO_CANCEL;
// defaultNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
defaultNotification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
// defaultNotification.ledARGB = Color.YELLOW;
// defaultNotification.ledOnMS = 1500;
// defaultNotification.ledOffMS = 1500;
return builder;
}
protected static NotificationCompat.Builder createServiceNotificationBuilder()
{
@@ -612,6 +621,9 @@ public class AutomationService extends Service implements OnInitListener
@SuppressWarnings("deprecation")
public static void updateNotification()
{
if(!Settings.showIconWhenServiceIsRunning && Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return;
AutomationService instance = getInstance();
if(instance != null)
@@ -677,7 +689,10 @@ public class AutomationService extends Service implements OnInitListener
myNotification.flags |= Notification.FLAG_NO_CLEAR;
// notificationManager.notify(notificationId, myNotification);
instance.startForeground(notificationId, myNotification);
// if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34)
// instance.startForeground(notificationId, myNotification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
// else
instance.startForeground(notificationId, myNotification);
}
}
@@ -92,6 +92,7 @@ import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
@@ -126,10 +127,36 @@ import eu.chainfire.libsuperuser.Shell;
public class Miscellaneous extends Service
{
protected static String writeableFolderStringCache = null;
protected final static String http_error_string = "HTTP_ERROR";
protected final static String last_trigger_url_result_string = "last_trigger_url_result";
protected final static String httpMainData = "httpMainData";
protected final static String doNoEncodingString = "NoEncoding";
protected final static String httpEncoding = "UTF-8";
public static Context startupContext;
public static final String lineSeparator = System.getProperty("line.separator");
public static class TrustAllCertificates implements X509TrustManager
{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
{
// Do nothing (trust all clients)
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
{
// Do nothing (trust all servers)
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0]; // No accepted issuers
}
}
public static String downloadURL(String url, String username, String password, String method, Map<String, String> httpParams)
{
HttpClient httpclient = new DefaultHttpClient();
@@ -144,12 +171,24 @@ public class Miscellaneous extends Service
HttpURLConnection connection;
if(url.toLowerCase().contains("https"))
{
connection = (HttpsURLConnection) urlObject.openConnection();
}
{
connection = (HttpsURLConnection) urlObject.openConnection();
if(Settings.httpAcceptAllCertificates)
{
SSLContext sslContext = SSLContext.getInstance("TLS"); // Use "TLS" (not "SSL" which is outdated)
sslContext.init(
null, // No KeyManager (client authentication not needed)
new TrustManager[]{new TrustAllCertificates()}, // Use our trust manager
new SecureRandom() // Secure random number generator
);
((HttpsURLConnection)connection).setSSLSocketFactory(sslContext.getSocketFactory());
((HttpsURLConnection)connection).setHostnameVerifier((hostname, session) -> true); // Trust all hostnames
}
}
else
connection = (HttpURLConnection) urlObject.openConnection();
// Add http simple authentication if specified
if(username != null && password != null)
{
@@ -161,9 +200,10 @@ public class Miscellaneous extends Service
else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
connection.setRequestMethod("POST");
if(httpParams.size() > 0)
if(httpParams.size() > 0)
{
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoInput(true);
connection.setDoOutput(true);
@@ -173,8 +213,8 @@ public class Miscellaneous extends Service
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));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, httpEncoding));
writer.write(getQuery(paramPairs, method));
writer.flush();
writer.close();
}
@@ -198,27 +238,58 @@ public class Miscellaneous extends Service
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
if(errorFound)
return "httpError";
return http_error_string;
else
return responseBody.toString();
}
}
private static String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException
private static String getQuery(List<NameValuePair> params, String method) throws UnsupportedEncodingException
{
StringBuilder result = new StringBuilder();
boolean first = true;
for (NameValuePair pair : params)
{
if (first)
first = false;
else
result.append("&");
if (method.equals(ActivityManageActionTriggerUrl.methodGet))
{
if (first)
first = false;
else
result.append("&");
}
else if (pair.getName().startsWith(httpMainData))
continue; // if post and main data skip lookup run
result.append(pair.getName());
result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
if (pair.getName().endsWith(doNoEncodingString))
result.append(URLEncoder.encode(pair.getValue(), httpEncoding));
else
result.append(pair.getValue());
}
/*
If method is POST and there's a httpMainData field, we transfer
this one at the end without parameter name and equals sign.
*/
if (method.equals(ActivityManageActionTriggerUrl.methodPost))
{
for (NameValuePair pair : params)
{
if (pair.getName().startsWith(httpMainData))
{
if (pair.getName().endsWith(doNoEncodingString))
result.append(pair.getValue());
else
result.append(URLEncoder.encode(pair.getValue(), httpEncoding));
return result.toString();
}
}
}
return result.toString();
@@ -273,8 +344,8 @@ public class Miscellaneous extends Service
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
return "httpError";
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
return http_error_string;
}
// finally
// {
@@ -313,15 +384,18 @@ public class Miscellaneous extends Service
header = "Automation";
}
if(type.equals("e"))
Log.e(header, description);
if(Settings.logToConsole)
{
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(type.equals("w"))
Log.w(header, description);
if(type.equals("i"))
Log.i(header, description);
if(Settings.writeLogFile && Settings.logLevel >= logLevel)
{
writeToLogFile(type, header, description);
@@ -585,7 +659,45 @@ public class Miscellaneous extends Service
Miscellaneous.logEvent("i", "TimeCompare", "Default return code. Shouldn't be here.", 5);
return 0;
}
public static int compareTimes(Calendar calOne, Calendar calTwo)
{
if(calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY) && calOne.get(Calendar.MINUTE) == calTwo.get((Calendar.MINUTE)))
{
// Miscellaneous.logEvent("i", "TimeCompare", "Times are equal.");
return 0;
}
if(calOne.get(Calendar.HOUR_OF_DAY) > calTwo.get(Calendar.HOUR_OF_DAY))
{
// Miscellaneous.logEvent("i", "TimeCompare", "Time1 is bigger/later by hours.");
return -1;
}
if(calOne.get(Calendar.HOUR_OF_DAY) < calTwo.get(Calendar.HOUR_OF_DAY))
{
// Miscellaneous.logEvent("i", "TimeCompare", "Time2 is bigger/later by hours.");
return 1;
}
if(calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY))
{
if(calOne.get(Calendar.MINUTE) < calTwo.get(Calendar.MINUTE))
{
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time2 is bigger/later by minutes.");
return 1;
}
if(calOne.get(Calendar.MINUTE) > calTwo.get(Calendar.MINUTE))
{
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time1 is bigger/later by minutes.");
return -1;
}
}
Miscellaneous.logEvent("i", "TimeCompare", "Default return code. Shouldn't be here.", 5);
return 0;
}
public static String convertStreamToString(InputStream is)
@@ -679,7 +791,9 @@ public class Miscellaneous extends Service
source.contains("[H]") ||
source.contains("[i]") ||
source.contains("[s]") ||
source.contains("[ms]")
source.contains("[ms]") ||
source.contains("[w]") ||
source.contains("[F]")
)
{
Calendar cal = Calendar.getInstance();
@@ -747,6 +861,24 @@ public class Miscellaneous extends Service
{
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
}
if(source.contains("[w]"))
{
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date d = new Date();
String dayOfTheWeek = sdf.format(d);
// source = source.replace("[w]", LocalDate.now().getDayOfWeek().name());
source = source.replace("[w]", dayOfTheWeek);
}
if(source.contains("[F]"))
{
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
Date d = new Date();
String month = sdf.format(d);
// source = source.replace("[F]", LocalDate.now().getMonth().name());
source = source.replace("[F]", month);
}
}
if(source.contains("[notificationTitle]"))
@@ -756,7 +888,7 @@ public class Miscellaneous extends Service
String notificationTitle = NotificationListener.getLastNotification().getTitle();
if (notificationTitle != null && notificationTitle.length() > 0)
source = source.replace("[notificationTitle]", escapeStringForUrl(notificationTitle));
source = source.replace("[notificationTitle]", notificationTitle);
else
{
source = source.replace("[notificationTitle]", "notificationTitle unknown");
@@ -777,7 +909,8 @@ public class Miscellaneous extends Service
String notificationText = NotificationListener.getLastNotification().getText();
if (notificationText != null && notificationText.length() > 0)
source = source.replace("[notificationText]", escapeStringForUrl(notificationText));
//source = source.replace("[notificationText]", escapeStringForUrl(notificationText));
source = source.replace("[notificationText]", notificationText);
else
{
source = source.replace("[notificationText]", "notificationText unknown");
@@ -791,15 +924,15 @@ public class Miscellaneous extends Service
}
}
if(source.contains("[last_trigger_url_result]"))
if(source.contains("[" + last_trigger_url_result_string + "]"))
{
try
{
source = source.replace("[last_trigger_url_result]", AutomationService.getInstance().getVariableMap().get("last_trigger_url_result"));
source = source.replace("[" + last_trigger_url_result_string + "]", AutomationService.getInstance().getVariableMap().get(last_trigger_url_result_string));
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable last_trigger_url_result.", 3);
Miscellaneous.logEvent("w", "Variable replacement", "Error replacing variable " + last_trigger_url_result_string + ".", 3);
}
}
@@ -2014,6 +2147,50 @@ public class Miscellaneous extends Service
return formattedDate;
}
public static int arraySearchIndexOf(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
{
if(matchFullLine)
{
if(caseSensitive)
{
for (int i = 0; i < haystack.length; i++)
{
if (haystack[i].equals(needle))
return i;
}
}
else
{
for (int i = 0; i < haystack.length; i++)
{
if (haystack[i].toLowerCase().equals(needle.toLowerCase()))
return i;
}
}
}
else
{
if(caseSensitive)
{
for (int i = 0; i < haystack.length; i++)
{
if (haystack[i].contains(needle))
return i;
}
}
else
{
for (int i = 0; i < haystack.length; i++)
{
if (haystack[i].toLowerCase().contains(needle.toLowerCase()))
return i;
}
}
}
return -1;
}
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
{
if(matchFullLine)
@@ -2133,6 +2310,22 @@ public class Miscellaneous extends Service
return context.getApplicationContext().getApplicationInfo().targetSdkVersion;
}
public static void setUiTheme(Context context)
{
switch(Settings.uiTheme)
{
case 0:
context.setTheme(R.style.AppTheme);
break;
case 1:
context.setTheme(R.style.AppThemeCompat);
break;
default:
context.setTheme(R.style.AppTheme);
break;
}
}
public static void setDisplayLanguage(Context context)
{
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
@@ -38,6 +38,9 @@ public class Profile implements Comparable<Profile>
protected boolean changeVolumeNotifications;
protected int volumeNotifications;
protected boolean changeVolumeRingtones;
protected int volumeRingtones;
protected boolean changeVolumeAlarms;
protected int volumeAlarms;
@@ -145,6 +148,26 @@ public class Profile implements Comparable<Profile>
return volumeNotifications;
}
public boolean getChangeVolumeRingtones()
{
return changeVolumeRingtones;
}
public void setChangeVolumeRingtones(boolean changeVolumeRingtones)
{
this.changeVolumeRingtones = changeVolumeRingtones;
}
public int getVolumeRingtones()
{
return volumeRingtones;
}
public void setVolumeRingtones(int volumeRingtones)
{
this.volumeRingtones = volumeRingtones;
}
public void setChangeVolumeAlarms(boolean changeVolumeAlarms)
{
this.changeVolumeAlarms = changeVolumeAlarms;
@@ -520,52 +543,92 @@ public class Profile implements Comparable<Profile>
{
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
if(changeSoundMode)
Actions.setSound(context, soundMode);
if(changeSoundMode)
{
Miscellaneous.logEvent("i", "Profile", "Setting sound mode to " + String.valueOf(soundMode), 4);
Actions.setSound(context, soundMode);
}
if(changeDndMode)
Actions.setDoNotDisturb(context, dndMode);
{
Miscellaneous.logEvent("i", "Profile", "Setting DND mode to " + String.valueOf(dndMode), 4);
Actions.setDoNotDisturb(context, dndMode);
}
if(changeVolumeMusicVideoGameMedia)
am.setStreamVolume(AudioManager.STREAM_MUSIC, volumeMusic, AudioManager.FLAG_PLAY_SOUND);
{
Miscellaneous.logEvent("i", "Profile", "Setting media volume to " + String.valueOf(volumeMusic), 4);
am.setStreamVolume(AudioManager.STREAM_MUSIC, volumeMusic, AudioManager.FLAG_PLAY_SOUND);
}
if(changeVolumeNotifications)
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, volumeNotifications, AudioManager.FLAG_PLAY_SOUND);
{
Miscellaneous.logEvent("i", "Profile", "Setting notification volume to " + String.valueOf(volumeNotifications), 4);
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, volumeNotifications, AudioManager.FLAG_PLAY_SOUND);
}
if(Build.VERSION.SDK_INT >= 34)
{
if (changeVolumeRingtones)
{
Miscellaneous.logEvent("i", "Profile", "Setting ring volume to " + String.valueOf(volumeRingtones), 4);
am.setStreamVolume(AudioManager.STREAM_RING, volumeRingtones, AudioManager.FLAG_PLAY_SOUND);
}
}
if(changeVolumeAlarms)
am.setStreamVolume(AudioManager.STREAM_ALARM, volumeAlarms, AudioManager.FLAG_PLAY_SOUND);
{
Miscellaneous.logEvent("i", "Profile", "Setting alarm volume to " + String.valueOf(volumeAlarms), 4);
am.setStreamVolume(AudioManager.STREAM_ALARM, volumeAlarms, AudioManager.FLAG_PLAY_SOUND);
}
if(changeIncomingCallsRingtone)
if(incomingCallsRingtone != null)
applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
{
if (incomingCallsRingtone != null)
{
Miscellaneous.logEvent("i", "Profile", "Setting ringtone " + incomingCallsRingtone, 4);
applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
}
}
if(changeVibrateWhenRinging)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
Miscellaneous.logEvent("i", "Profile", "Setting vibrate when ringing to " + String.valueOf(vibrateWhenRinging?1:0), 4);
android.provider.Settings.System.putInt(context.getContentResolver(), "vibrate_when_ringing", vibrateWhenRinging?1:0);
}
else
{
Miscellaneous.logEvent("i", "Profile", "Setting vibrate when ringing to " + String.valueOf(vibrateWhenRinging), 4);
if (vibrateWhenRinging)
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
else
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
}
}
if(changeNotificationRingtone)
if(notificationRingtone != null)
applyRingTone(notificationRingtone, RingtoneManager.TYPE_NOTIFICATION, context);
{
if (notificationRingtone != null)
{
Miscellaneous.logEvent("i", "Profile", "Setting notification ringtone to " + String.valueOf(notificationRingtone), 4);
applyRingTone(notificationRingtone, RingtoneManager.TYPE_NOTIFICATION, context);
}
}
if(changeScreenLockUnlockSound)
{
Miscellaneous.logEvent("i", "Profile", "Setting lockscreen sounds enabled to " + String.valueOf(screenLockUnlockSound ? 1 : 0), 4);
android.provider.Settings.System.putInt(context.getContentResolver(), "lockscreen_sounds_enabled" , screenLockUnlockSound ? 1 : 0);
}
if(changeAudibleSelection)
{
if(audibleSelection)
Miscellaneous.logEvent("i", "Profile", "Setting audible selection to " + String.valueOf(audibleSelection ? 1 : 0), 4);
if(audibleSelection)
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED, 1); // enable
else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED, 0); // dissable
@@ -573,7 +636,9 @@ public class Profile implements Comparable<Profile>
if(changeHapticFeedback)
{
if(hapticFeedback)
Miscellaneous.logEvent("i", "Profile", "Setting haptic feedback to " + String.valueOf(hapticFeedback ? 1 : 0), 4);
if(hapticFeedback)
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED, 1); // enable
else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED, 0); // disable
@@ -585,7 +650,8 @@ public class Profile implements Comparable<Profile>
}
finally
{
Miscellaneous.logEvent("i", "Profile", "Checking for applicable rules after profile " + this.getName() + " has been activated.", 2);
Miscellaneous.logEvent("i", "Profile", "Profile activation complete: " + this.getName(), 3);
Miscellaneous.logEvent("i", "Profile", "Checking for applicable rules after profile " + this.getName() + " has been activated.", 3);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.profileActive);
for(int i=0; i<ruleCandidates.size(); i++)
{
@@ -637,6 +703,15 @@ public class Profile implements Comparable<Profile>
return false;
}
if(Build.VERSION.SDK_INT >= 34)
{
if (changeVolumeRingtones)
{
if (am.getStreamVolume(AudioManager.STREAM_RING) != volumeRingtones)
return false;
}
}
if (changeVolumeAlarms)
{
if (am.getStreamVolume(AudioManager.STREAM_ALARM) != volumeAlarms)
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.os.Build;
import android.util.Log;
@@ -18,6 +19,7 @@ import com.jens.automation2.receivers.MediaPlayerListener;
import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ProximityReceiver;
import com.jens.automation2.receivers.ScreenStateReceiver;
import com.jens.automation2.receivers.SubSystemStateReceiver;
import com.jens.automation2.receivers.TetheringReceiver;
@@ -212,8 +214,11 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent) && ActivityPermissions.isPermissionDeclaredInManifest(AutomationService.getInstance(), Manifest.permission.READ_CALENDAR) && ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, AutomationService.getInstance()))
CalendarReceiver.startCalendarReceiver(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.proximity))
ProximityReceiver.startProximityReceiver(AutomationService.getInstance());
}
public static void stopAllReceivers()
@@ -233,6 +238,7 @@ public class ReceiverCoordinator
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
SubSystemStateReceiver.getInstance().stopListener(AutomationService.getInstance());
ProximityReceiver.stopProximityReceiver();
try
{
@@ -469,7 +475,7 @@ public class ReceiverCoordinator
}
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent) && ActivityPermissions.isPermissionDeclaredInManifest(AutomationService.getInstance(), Manifest.permission.READ_CALENDAR) && ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, AutomationService.getInstance()))
{
if(!CalendarReceiver.getInstance().isListenerRunning())
CalendarReceiver.getInstance().startListener(AutomationService.getInstance());
@@ -19,8 +19,9 @@ public class Settings implements SharedPreferences
public static final String folderName = "Automation";
public static final String zipFileName = "automation.zip";
public static final String constNewsOptInDone ="newsOptInDone";
public static final String constNotificationChannelCleanupApk118 ="notificationChannelCleanupApk118";
public static final String constNewsOptInDone = "newsOptInDone";
public static final String constNotificationChannelCleanupApk118 = "notificationChannelCleanupApk118";
public static final String constVersion143StartOtherProgramConfigEditHint = "constVersion143StartOtherProgramConfigEditHint";
public static long minimumDistanceChangeForGpsUpdate;
public static long minimumDistanceChangeForNetworkUpdate;
@@ -29,6 +30,7 @@ public class Settings implements SharedPreferences
public static int gpsTimeout;
public static long minimumTimeBetweenUpdate;
public static boolean startServiceAtSystemBoot;
public static boolean logToConsole;
public static boolean writeLogFile;
public static long logLevel;
public static int logFileMaxSize;
@@ -61,6 +63,7 @@ public class Settings implements SharedPreferences
public static int activityDetectionFrequency;
public static int activityDetectionRequiredProbability;
public static boolean privacyLocationing;
public static int uiTheme;
public static int startScreen;
public static int tabsPlacement;
public static boolean executeRulesAndProfilesWithSingleClick;
@@ -97,6 +100,7 @@ public class Settings implements SharedPreferences
public static final int default_gpsTimeout = 300; // seconds
public static final long default_minimumTimeBetweenUpdate = 30000; // in Milliseconds
public static final boolean default_startServiceAtSystemBoot = false;
public static final boolean default_logToConsole = false;
public static final boolean default_writeLogFile = false;
public static final long default_logLevel = 2;
public static final int default_logFileMaxSize = 10;
@@ -128,6 +132,7 @@ public class Settings implements SharedPreferences
public static final int default_activityDetectionFrequency = 60;
public static final int default_activityDetectionRequiredProbability = 75;
public static final boolean default_privacyLocationing = false;
public static final int default_uiTheme = 0;
public static final int default_startScreen = 0;
public static final int default_tabsPlacement = 0;
public static final boolean default_executeRulesAndProfilesWithSingleClick = false;
@@ -198,6 +203,7 @@ public class Settings implements SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
startServiceAtSystemBoot = prefs.getBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot);
logToConsole = prefs.getBoolean("logToConsole", default_logToConsole);
writeLogFile = prefs.getBoolean("writeLogFile", default_writeLogFile);
boolean useTextToSpeech = false;
@@ -260,6 +266,7 @@ public class Settings implements SharedPreferences
activityDetectionRequiredProbability = Integer.parseInt(prefs.getString("activityDetectionRequiredProbability", String.valueOf(default_activityDetectionRequiredProbability)));
privacyLocationing = prefs.getBoolean("privacyLocationing", default_privacyLocationing);
uiTheme = Integer.parseInt(prefs.getString("uiTheme", String.valueOf(default_uiTheme)));
startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
@@ -338,6 +345,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("startServiceAtSystemBoot") || force)
editor.putBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot);
if(!prefs.contains("logToConsole") || force)
editor.putBoolean("logToConsole", default_logToConsole);
if(!prefs.contains("writeLogFile") || force)
editor.putBoolean("writeLogFile", default_writeLogFile);
@@ -453,6 +463,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("privacyLocationing") || force)
editor.putBoolean("privacyLocationing", default_privacyLocationing);
if(!prefs.contains("uiTheme") || force)
editor.putString("uiTheme", String.valueOf(default_uiTheme));
if(!prefs.contains("startScreen") || force)
editor.putString("startScreen", String.valueOf(default_startScreen));
@@ -514,6 +527,7 @@ public class Settings implements SharedPreferences
Editor editor = prefs.edit();
editor.putBoolean("startServiceAtSystemBoot", startServiceAtSystemBoot);
editor.putBoolean("logToConsole", logToConsole);
editor.putBoolean("writeLogFile", writeLogFile);
// editor.putBoolean("useTextToSpeech", useTextToSpeech);
editor.putBoolean("useTextToSpeechOnNormal", useTextToSpeechOnNormal);
@@ -552,6 +566,7 @@ public class Settings implements SharedPreferences
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
editor.putBoolean("privacyLocationing", privacyLocationing);
editor.putString("uiTheme", String.valueOf(uiTheme));
editor.putString("startScreen", String.valueOf(startScreen));
editor.putString("tabsPlacement", String.valueOf(tabsPlacement));
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Collections;
public class TimeFrame
{
@@ -20,18 +21,19 @@ public class TimeFrame
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
Collections.sort(dayList);
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
// Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item)));
}
Collections.sort(dayList);
}
public TimeObject getTriggerTimeStart()
@@ -17,6 +17,7 @@ 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.DateTimeListener;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener;
import com.jens.automation2.receivers.MediaPlayerListener;
@@ -25,6 +26,7 @@ import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.NotificationListener;
import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ProximityReceiver;
import com.jens.automation2.receivers.ScreenStateReceiver;
import com.jens.automation2.receivers.TetheringReceiver;
@@ -66,6 +68,7 @@ public class Trigger
tethering,
subSystemState,
checkVariable,
proximity,
calendarEvent,
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
@@ -127,6 +130,8 @@ public class Trigger
return context.getResources().getString(R.string.subSystemState);
case checkVariable:
return context.getResources().getString(R.string.checkVariable);
case proximity:
return context.getResources().getString(R.string.proximity);
case calendarEvent:
return context.getResources().getString(R.string.calendarEventCapital);
default:
@@ -135,6 +140,35 @@ public class Trigger
}
};
boolean triggerParameter; //if true->started event, if false->stopped
String triggerParameter2;
public static final String triggerParameter2Split = "tp2split";
Trigger_Enum triggerType = null;
PointOfInterest pointOfInterest = null;
TimeFrame timeFrame;
public static String triggerPhoneCallStateRinging = "ringing";
public static String triggerPhoneCallStateStarted = "started";
public static String triggerPhoneCallStateStopped = "stopped";
public static String triggerPhoneCallDirectionIncoming = "incoming";
public static String triggerPhoneCallDirectionOutgoing = "outgoing";
public static String triggerPhoneCallDirectionAny = "any";
public static String triggerPhoneCallNumberAny = "any";
double speed; //km/h
long noiseLevelDb;
String processName = null;
int batteryLevel;
int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing
String phoneNumber = null;
String nfcTagId = null;
String bluetoothEvent = null;
String bluetoothDeviceAddress = null;
int activityDetectionType = -1;
int headphoneType = -1;
public static enum subSystemStates { wifi, bluetooth };
Rule parentRule = null;
@@ -261,6 +295,10 @@ public class Trigger
if(!checkCalendarEvent(false))
result = false;
break;
case proximity:
if(!checkProximity())
result = false;
break;
default:
break;
}
@@ -293,17 +331,17 @@ public class Trigger
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
String[] params = this.getTriggerParameter2().split(triggerParameter2Split);
String[] params = this.getTriggerParameter2().split(triggerParameter2Split, -1);
String myApp = params[0];
String myTitleDir = params[1];
String requiredTitle = params[2];
String myTextDir = params[3];
String requiredText;
if (params.length >= 5)
requiredText = params[4];
else
requiredText = "";
// String requiredText;
// if (params.length >= 5)
String requiredText = params[4];
// else
// requiredText = "";
if(this.getTriggerParameter())
{
@@ -562,16 +600,42 @@ public class Trigger
boolean checkHeadsetPlugged()
{
if(HeadphoneJackListener.isHeadsetConnected() != this.getTriggerParameter())
return false;
else
if(this.getHeadphoneType() != 2 && this.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType())
/*
Wenn verbunden:
- either -> true
- headphone -> true
- mikro -> wenn tatsächlich mikro
Wenn nicht verbunden:
- either -> true
- headphone -> true
- mikro -> true
*/
if(HeadphoneJackListener.isHeadsetConnected()) // connection detected
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), this.getParentRule().getName()), 3);
return false;
if(this.getTriggerParameter()) // connection demanded
{
if (this.getHeadphoneType() == 1)
{
if (this.getHeadphoneType() == HeadphoneJackListener.getHeadphoneType()) // Microphone demanded
return true;
else
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), this.getParentRule().getName()), 3);
}
else
return true;
}
}
else // disconnection detected
{
// Type doesn't matter here
if(!this.getTriggerParameter()) // disconnection demanded
return true;
}
return true;
return false;
}
boolean checkSubSystemState()
@@ -613,8 +677,14 @@ public class Trigger
{
if (map.containsKey(conditions[0]))
{
if (map.get(conditions[0]).equals(conditions[1]))
return true;
if(Miscellaneous.isRegularExpression(conditions[1]))
{
return (map.get(conditions[0]).matches(conditions[1]) == this.getTriggerParameter());
}
else
{
return (map.get(conditions[0]).equals(conditions[1]) == this.getTriggerParameter());
}
}
}
}
@@ -761,6 +831,27 @@ public class Trigger
return true;
}
public boolean checkProximity()
{
try
{
float currentLevel = ProximityReceiver.getProximityLevel();
String[] values = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
float part1 = Float.parseFloat(values[0]);
float part2 = Float.parseFloat(values[1]);
// Are we within the defined scope?
if(part1 <= currentLevel && currentLevel <= part2)
return true;
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "checkProximity()", Log.getStackTraceString(e), 1);
}
return false;
}
boolean checkBluetooth()
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Checking for bluetooth...", this.getParentRule().getName()), 4);
@@ -1124,8 +1215,6 @@ public class Trigger
// We are not at any POI. But if this trigger requires us NOT to be there, that may be fine.
if(this.getPointOfInterest() != null)
{
// if(activePoi.equals(oneTrigger.getPointOfInterest()))
// {
if(!this.getTriggerParameter())
{
Miscellaneous.logEvent("i", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), this.getParentRule().getName()), "We are not at POI \"" + this.getPointOfInterest().getName() + "\". But since that's required by this rule that's fine.", 4);
@@ -1135,7 +1224,6 @@ public class Trigger
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;
}
// }
}
else if(this.getPointOfInterest() == null)
{
@@ -1152,6 +1240,12 @@ public class Trigger
public boolean hasStateNotAppliedSinceLastRuleExecution()
{
/*
There is no easy event to tell when a tag has been disconnected again.
*/
if(getTriggerType().equals(Trigger_Enum.nfcTag))
return true;
if(getParentRule().getLastExecution() == null)
{
Miscellaneous.logEvent("i", "Trigger", "Trigger " + this.toString() + " of rule " + getParentRule().getName() + " has NOT applied since the parent rule\'s last activation.", 4);
@@ -1193,7 +1287,9 @@ public class Trigger
int desiredType;
String[] typeParams = getTriggerParameter2().split(triggerParameter2Split, -1);
desiredType = Integer.parseInt(typeParams[0]);
if(desiredType == BatteryReceiver.getCurrentChargingType())
if(desiredType == BatteryReceiver.batteryChargingTypeAny)
return true;
else if(desiredType == BatteryReceiver.getCurrentChargingType())
return true;
}
}
@@ -1224,7 +1320,7 @@ public class Trigger
return false;
}
public boolean checkDateTime(Object triggeringObject, boolean checkifStateChangedSinceLastRuleExecution)
public boolean checkDateTime(Object triggeringObject, boolean checkIfStateChangedSinceLastRuleExecution)
{
/*
* Use format known from Automation
@@ -1246,142 +1342,52 @@ public class Trigger
{
TimeFrame tf = new TimeFrame(getTriggerParameter2());
if(tf.getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK)))
if (DateTimeListener.areWeInTimeFrame(this, triggeringObject) != this.getTriggerParameter())
{
if(
// Regular case, start time is lower than end time
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
)
||
// Other case, start time higher than end time, timeframe goes over midnight
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0
&&
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0)
)
||
// further case: start and end times are identical, meaning a 24h window
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) == 0
)
)
if (triggerParameter)
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") outside of the specified TimeFrame (" + tf.toString() + "), but demanded is inside.", 5);
else
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + tf.toString() + "), but demanded is outside.", 4);
return false;
}
// We are inside or outside of the timeframe as demanded by the trigger
if (tf.getRepetition() > 0)
{
if (!isSupposedToRepeatSinceLastExecution(Calendar.getInstance()))
{
// We are in the timeframe
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + tf.toString() + ").", 4);
if(getTriggerParameter())
{
if(checkifStateChangedSinceLastRuleExecution)
{
/*
* Was there a target repetition time between last execution and now?
* If not -> return false.
*/
Calendar compareCal = Calendar.getInstance();
compareCal.setTimeInMillis(triggeringTime.getTime());
if(tf.getRepetition() > 0)
{
if(!isSupposedToRepeatSinceLastExecution(compareCal))
{
Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but repeated execution is not due, yet.", 4);
return false;
}
}
else
{
/*
* This is not a repeating rule. Have we left
* the relevant timeframe since the last run?
* Determine if it has ran today already. If yes
* return false because every rule that is not
* repeating can only be executed once per day.
*/
if(
getParentRule().getLastExecution().get(Calendar.YEAR) == calNow.get(Calendar.YEAR)
&&
getParentRule().getLastExecution().get(Calendar.MONTH) == calNow.get(Calendar.MONTH)
&&
getParentRule().getLastExecution().get(Calendar.DAY_OF_MONTH) == calNow.get(Calendar.DAY_OF_MONTH)
)
{
Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but it was already executed today.", 4);
return false;
}
}
}
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: That's what's specified. Trigger of rule " + this.getParentRule().getName() + " applies.", 4);
return true;
}
else
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: That's not what's specified. Trigger of rule " + this.getParentRule().getName() + " doesn't apply.", 4);
return false;
}
Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but repetition is not due, yet.", 4);
return false;
}
else
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + tf.toString() + ") because of the time.", 5);
if(!getTriggerParameter())
{
if(checkifStateChangedSinceLastRuleExecution)
{
/*
* Was there a target repetition time between last execution and now?
* If not -> return false.
*/
Calendar compareCal = Calendar.getInstance();
compareCal.setTimeInMillis(triggeringTime.getTime());
if(tf.getRepetition() > 0)
{
if(!isSupposedToRepeatSinceLastExecution(compareCal))
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but repeated execution is not due, yet.", 4);
return false;
}
}
else
{
/*
* This is not a repeating rule. Have we left
* the relevant timeframe since the last run?
* Determine if it has ran today already. If yes
* return false because every rule that is not
* repeating can only be executed once per day.
*/
if(
getParentRule().getLastExecution().get(Calendar.YEAR) == calNow.get(Calendar.YEAR)
&&
getParentRule().getLastExecution().get(Calendar.MONTH) == calNow.get(Calendar.MONTH)
&&
getParentRule().getLastExecution().get(Calendar.DAY_OF_MONTH) == calNow.get(Calendar.DAY_OF_MONTH)
)
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but it was already executed today.", 4);
return false;
}
}
}
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: That's what's specified. Trigger of rule " + this.getParentRule().getName() + " applies.", 5);
return true;
}
else
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: That's not what's specified. Trigger of rule " + this.getParentRule().getName() + " doesn't apply.", 5);
return false;
}
}
Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " would apply because repetition is due.", 4);
}
else
{
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + tf.toString() + ") because of the day.", 5);
return false;
if (checkIfStateChangedSinceLastRuleExecution)
{
/*
* This is not a repeating rule. Have we left
* the relevant timeframe since the last run?
* Determine if it has ran today already. If yes
* return false because every rule that is not
* repeating can only be executed once per day.
*/
if (
getParentRule().getLastExecution().get(Calendar.YEAR) == calNow.get(Calendar.YEAR)
&&
getParentRule().getLastExecution().get(Calendar.MONTH) == calNow.get(Calendar.MONTH)
&&
getParentRule().getLastExecution().get(Calendar.DAY_OF_MONTH) == calNow.get(Calendar.DAY_OF_MONTH)
)
{
Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but it was already executed today.", 4);
return false;
}
}
}
}
catch(Exception e)
@@ -1389,43 +1395,8 @@ public class Trigger
Miscellaneous.logEvent("e", "Trigger", "There was an error while checking if the time based trigger applies: " + Log.getStackTraceString(e), 1);
return false;
}
}
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(trigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
else
setTime = tf.getTriggerTimeStop();
calSet = (Calendar) now.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// If the starting time is a day ahead remove 1 day.
if(calSet.getTimeInMillis() > now.getTimeInMillis())
calSet.add(Calendar.DAY_OF_MONTH, -1);
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calSet.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
long nextScheduleTimestamp = (calSet.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition());
Calendar calSchedule = Calendar.getInstance();
calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000);
return calSchedule;
}
else
Miscellaneous.logEvent("i", "Trigger", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5);
return null;
return true;
}
boolean isSupposedToRepeatSinceLastExecution(Calendar now)
@@ -1435,7 +1406,7 @@ public class Trigger
// the simple stuff:
if(lastExec == null) // rule never run, go any way
if(lastExec == null) // rule never ran, go in any case
return true;
else if(tf.getRepetition() <= 0) // is not set to repeat at all
return false;
@@ -1446,41 +1417,17 @@ public class Trigger
* we're inside the specified timeframe.
*/
Calendar timeSupposedToRunNext = getNextRepeatedExecutionAfter(this, lastExec);
if(now.getTimeInMillis() > timeSupposedToRunNext.getTimeInMillis())
Calendar lastRepetitionNotExecutedYet = DateTimeListener.getNextRepeatedExecution(this);
lastRepetitionNotExecutedYet.add(Calendar.SECOND, (int) -(tf.getRepetition()));
Miscellaneous.logEvent("i", "isSupposedToRepeatSinceLastExecution()", "Last execution: " + Miscellaneous.formatDate(lastExec.getTime()), 5);
Miscellaneous.logEvent("i", "isSupposedToRepeatSinceLastExecution()", "lastRepetitionNotExecutedYet: " + Miscellaneous.formatDate(lastRepetitionNotExecutedYet.getTime()), 5);
if(now.getTimeInMillis() > lastRepetitionNotExecutedYet.getTimeInMillis())
return true;
return false;
}
boolean triggerParameter; //if true->started event, if false->stopped
String triggerParameter2;
public static final String triggerParameter2Split = "tp2split";
Trigger_Enum triggerType = null;
PointOfInterest pointOfInterest = null;
TimeFrame timeFrame;
public static String triggerPhoneCallStateRinging = "ringing";
public static String triggerPhoneCallStateStarted = "started";
public static String triggerPhoneCallStateStopped = "stopped";
public static String triggerPhoneCallDirectionIncoming = "incoming";
public static String triggerPhoneCallDirectionOutgoing = "outgoing";
public static String triggerPhoneCallDirectionAny = "any";
public static String triggerPhoneCallNumberAny = "any";
double speed; //km/h
long noiseLevelDb;
String processName = null;
int batteryLevel;
int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing
String phoneNumber = null;
String nfcTagId = null;
String bluetoothEvent = null;
String bluetoothDeviceAddress = null;
int activityDetectionType = -1;
int headphoneType = -1;
public int getHeadphoneType()
{
@@ -1787,7 +1734,7 @@ public class Trigger
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
if (ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
if (ActivityPermissions.isPermissionDeclaredInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
{
// This type doesn't have an activate/deactivate equivalent, at least not yet.
returnString.append(Miscellaneous.runMethodReflective(ActivityManageRule.activityDetectionClassPath, "getDescription", new Object[]{getActivityDetectionType()}));
@@ -1983,13 +1930,21 @@ public class Trigger
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deactivated));
break;
case checkVariable:
if (triggerParameter2.contains(triggerParameter2Split))
if(triggerParameter)
{
String[] parts = triggerParameter2.split(triggerParameter2Split);
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckString), parts[0], parts[1]));
if (triggerParameter2.contains(triggerParameter2Split))
{
String[] parts = triggerParameter2.split(triggerParameter2Split);
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckString), parts[0], parts[1]));
}
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2));
}
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2));
{
String[] parts = triggerParameter2.split(triggerParameter2Split);
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringNot), parts[0], parts[1]));
}
break;
case calendarEvent:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent));
@@ -2040,6 +1995,10 @@ public class Trigger
returnString.append(")");
break;
case proximity:
String[] parts = triggerParameter2.split(triggerParameter2Split);
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.proximityText), parts[0], parts[1]));
break;
default:
returnString.append("error");
break;
@@ -148,6 +148,13 @@ public class XmlFileInterface
serializer.startTag(null, "volumeNotifications");
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getVolumeNotifications()));
serializer.endTag(null, "volumeNotifications");
serializer.startTag(null, "changeVolumeRingtones");
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeVolumeRingtones()));
serializer.endTag(null, "changeVolumeRingtones");//
serializer.startTag(null, "volumeRingtones");
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getVolumeRingtones()));
serializer.endTag(null, "volumeRingtones");
serializer.startTag(null, "changeVolumeAlarms");
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeVolumeAlarms()));
@@ -619,8 +626,12 @@ public class XmlFileInterface
newProfile.setVolumeMusic(Integer.parseInt(readTag(parser, "volumeMusic")));
else if (name.equals("changeVolumeNotifications"))
newProfile.setChangeVolumeNotifications(Boolean.parseBoolean(readTag(parser, "changeVolumeNotifications")));
else if (name.equals("changeVolumeRingtones"))
newProfile.setChangeVolumeRingtones(Boolean.parseBoolean(readTag(parser, "changeVolumeRingtones")));
else if (name.equals("volumeNotifications"))
newProfile.setVolumeNotifications(Integer.parseInt(readTag(parser, "volumeNotifications")));
else if (name.equals("volumeRingtones"))
newProfile.setVolumeRingtones(Integer.parseInt(readTag(parser, "volumeRingtones")));
else if (name.equals("changeVolumeAlarms"))
newProfile.setChangeVolumeAlarms(Boolean.parseBoolean(readTag(parser, "changeVolumeAlarms")));
else if (name.equals("volumeAlarms"))
@@ -700,7 +711,7 @@ public class XmlFileInterface
private static Rule readRule(XmlPullParser parser) throws XmlPullParserException, IOException
{
/* FILE EXAMPE:
/* FILE EXAMPLE:
* *****************
* <Automation>
* <PointOfInterestCollection>
@@ -1084,7 +1095,7 @@ public class XmlFileInterface
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
{
/* FILE EXAMPE:
/* FILE EXAMPLE:
* *****************
* <Automation>
* <PointOfInterestCollection>
@@ -1135,28 +1146,10 @@ public class XmlFileInterface
// *** deprecated
//else
if(actionNameString.equals("turnWifiOn"))
newAction.setAction(Action_Enum.turnWifiOn);
else if(actionNameString.equals("turnWifiOff"))
newAction.setAction(Action_Enum.turnWifiOff);
else if(actionNameString.equals("turnBluetoothOn"))
newAction.setAction(Action_Enum.turnBluetoothOn);
else if(actionNameString.equals("turnBluetoothOff"))
newAction.setAction(Action_Enum.turnBluetoothOff);
else if(actionNameString.equals("turnUsbTetheringOn"))
if(actionNameString.equals("turnUsbTetheringOn"))
newAction.setAction(Action_Enum.turnUsbTetheringOn);
else if(actionNameString.equals("turnUsbTetheringOff"))
newAction.setAction(Action_Enum.turnUsbTetheringOff);
else if(actionNameString.equals("turnWifiTetheringOn"))
newAction.setAction(Action_Enum.turnWifiTetheringOn);
else if(actionNameString.equals("turnWifiTetheringOff"))
newAction.setAction(Action_Enum.turnWifiTetheringOff);
else if(actionNameString.equals("enableScreenRotation"))
newAction.setAction(Action_Enum.enableScreenRotation);
else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation);
else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation);
else if(actionNameString.equals("playMusic"))
{
newAction.setAction(Action_Enum.controlMediaPlayback);
@@ -1175,31 +1168,7 @@ public class XmlFileInterface
else if (name.equals("ActionParameter1"))
{
// exclusion for deprecated types
if(newAction.getAction().equals(Action_Enum.turnWifiOn))
{
newAction.setAction(Action_Enum.setWifi);
newAction.setParameter1(true);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnWifiOff))
{
newAction.setAction(Action_Enum.setWifi);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnBluetoothOn))
{
newAction.setAction(Action_Enum.setBluetooth);
newAction.setParameter1(true);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnBluetoothOff))
{
newAction.setAction(Action_Enum.setBluetooth);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnUsbTetheringOn))
if(newAction.getAction().equals(Action_Enum.turnUsbTetheringOn))
{
newAction.setAction(Action_Enum.setUsbTethering);
newAction.setParameter1(true);
@@ -1211,36 +1180,6 @@ public class XmlFileInterface
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnWifiTetheringOn))
{
newAction.setAction(Action_Enum.setWifiTethering);
newAction.setParameter1(true);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnWifiTetheringOff))
{
newAction.setAction(Action_Enum.setWifiTethering);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.enableScreenRotation))
{
newAction.setAction(Action_Enum.setDisplayRotation);
newAction.setParameter1(true);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
{
newAction.setAction(Action_Enum.setDisplayRotation);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
{
newAction.setAction(Action_Enum.setDisplayRotation);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnScreenOnOrOff) && newAction.getParameter1())
{
/*
@@ -78,7 +78,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
{
for(Action action : Rule.getLastActivatedRule().getActionSet())
{
if(action.getAction() == Action.Action_Enum.turnWifiOn)
if(action.getAction() == Action.Action_Enum.setWifi && action.getParameter1())
{
// we will be using wifiReceiver, deactivate AccelerometerTimer if applicable
SensorActivity.stopAccelerometerTimer();
@@ -88,7 +88,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
catch(NullPointerException ne)
{
// Nothing to do, there is no last activated rule. Wifi hasn't been activated so we don't
// deactive accelerometer receiver.
// deactivate accelerometer receiver.
}
}
else
@@ -363,10 +363,10 @@ public class CellLocationChangedReceiver extends PhoneStateListener
// Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4);
}
else
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 5);
}
else
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4);
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 5);
}
}
catch(Exception ex)
@@ -64,36 +64,36 @@ public class SensorActivity implements SensorEventListener
{
}
public void onSensorChanged(SensorEvent event)
{
// Device has been moved
public void onSensorChanged(SensorEvent event)
{
// Device has been moved
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
if(mInitialized)
{
deltaX = Math.abs(lastX-x);
deltaY = Math.abs(lastY-y);
deltaZ = Math.abs(lastZ-z);
//Wenn das jetzt einen gewissen Grenzwert übersteigt, müßten wir den CellListener wieder aktivieren
if(deltaX > Settings.accelerometerMovementThreshold | deltaY > Settings.accelerometerMovementThreshold | deltaZ > Settings.accelerometerMovementThreshold)
{
String text = "Device has been moved. " + String.valueOf(deltaX)+" / "+String.valueOf(deltaY)+" / "+String.valueOf(deltaZ);
Miscellaneous.logEvent("i", "Accelerometer", text, 5);
CellLocationChangedReceiver.resetFollowUpdate();
CellLocationChangedReceiver.startCellLocationChangedReceiver();
if(mInitialized)
{
deltaX = Math.abs(lastX-x);
deltaY = Math.abs(lastY-y);
deltaZ = Math.abs(lastZ-z);
// If that exceeds a certain delta we need to start CellLocationListener again
if(deltaX > Settings.accelerometerMovementThreshold | deltaY > Settings.accelerometerMovementThreshold | deltaZ > Settings.accelerometerMovementThreshold)
{
String text = "Device has been moved. " + String.valueOf(deltaX)+" / "+String.valueOf(deltaY)+" / "+String.valueOf(deltaZ);
Miscellaneous.logEvent("i", "Accelerometer", text, 5);
CellLocationChangedReceiver.resetFollowUpdate();
CellLocationChangedReceiver.startCellLocationChangedReceiver();
}
}
else
{
lastX = x;
lastY = y;
lastZ = z;
mInitialized = true;
}
}
}
else
{
lastX = x;
lastY = y;
lastZ = z;
mInitialized = true;
}
}
protected static void startAccelerometerReceiver()
{
@@ -1,11 +1,13 @@
package com.jens.automation2.receivers;
import static android.os.BatteryManager.*;
import android.os.BatteryManager;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.util.Log;
import com.jens.automation2.ActivityPermissions;
@@ -18,6 +20,11 @@ import java.util.ArrayList;
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface
{
public static final int batteryChargingTypeAny = 0;
public static final int batteryChargingTypeAc = BatteryManager.BATTERY_PLUGGED_AC;
public static final int batteryChargingTypeUsb = BatteryManager.BATTERY_PLUGGED_USB;
public static final int batteryChargingTypeWireless = BatteryManager.BATTERY_PLUGGED_WIRELESS;
public static AutomationService automationServiceRef = null;
static int batteryLevel = -1; // initialize with a better value than this
static boolean usbHostConnected = false;
@@ -102,7 +109,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
{
try
{
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
batteryLevel = intent.getIntExtra(EXTRA_LEVEL, -1);
// int scale = -1;
// int voltage = -1;
// int temp = -1;
@@ -112,36 +119,36 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
this.actionBatteryLevel(context);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
int status = intent.getIntExtra(EXTRA_STATUS, -1);
int statusPlugged = intent.getIntExtra(EXTRA_PLUGGED, -1);
Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged), 5);
switch(statusPlugged)
{
case BatteryManager.BATTERY_PLUGGED_AC:
case BATTERY_PLUGGED_AC:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
this.actionCharging(context, statusPlugged);
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
case BATTERY_PLUGGED_WIRELESS:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "BatteryReceiver", "Wireless charging.", 5);
this.actionCharging(context, statusPlugged);
break;
case BatteryManager.BATTERY_PLUGGED_USB:
case BATTERY_PLUGGED_USB:
this.actionUsbConnected(context);
break;
}
switch(status)
{
case BatteryManager.BATTERY_STATUS_CHARGING:
case BatteryManager.BATTERY_STATUS_FULL:
case BATTERY_STATUS_CHARGING:
case BATTERY_STATUS_FULL:
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
this.actionCharging(context, statusPlugged);
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
case BATTERY_STATUS_DISCHARGING:
case BATTERY_STATUS_NOT_CHARGING:
this.actionDischarging(context);
break;
}
@@ -163,7 +170,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
case 1:
Miscellaneous.logEvent("i", "ChargingInfo", "Device is discharging.", 3);
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
case BATTERY_STATUS_CHARGING:
Miscellaneous.logEvent("i", "ChargingInfo", "Device is charging.", 3);
break;
}
@@ -178,10 +185,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private void actionCharging(Context context, int statusPlugged)
{
if(currentChargingState != BatteryManager.BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
if(currentChargingState != BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING;
currentChargingState = BATTERY_STATUS_CHARGING;
currentChargingType = statusPlugged;
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
@@ -207,10 +214,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private void actionDischarging(Context context)
{
if(currentChargingState != BatteryManager.BATTERY_STATUS_UNKNOWN) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
if(currentChargingState != BATTERY_STATUS_UNKNOWN) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3);
currentChargingState = BatteryManager.BATTERY_STATUS_UNKNOWN;
currentChargingState = BATTERY_STATUS_UNKNOWN;
//activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
@@ -243,7 +250,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
oneRule.activate(automationServiceRef, false);
}
this.actionCharging(context, BatteryManager.BATTERY_PLUGGED_USB);
this.actionCharging(context, BATTERY_PLUGGED_USB);
}
}
@@ -293,7 +300,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
// actually monitores several
// actually monitors several
return new Trigger_Enum[] { Trigger_Enum.batteryLevel, Trigger_Enum.charging, Trigger_Enum.usb_host_connection };
}
}
@@ -7,6 +7,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.Toast;
import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService;
@@ -149,8 +150,6 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
{
return lhs.getName().compareTo(rhs.getName());
}
;
});
}
catch(NullPointerException e)
@@ -159,6 +158,12 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
returnArray = new BluetoothDevice[] {};
}
catch(SecurityException se)
{
Toast.makeText(Miscellaneous.getAnyContext(), Miscellaneous.getAnyContext().getResources().getString(R.string.permissionRequiredBluetooth), Toast.LENGTH_SHORT).show();
returnArray = new BluetoothDevice[] {};
}
return returnArray;
}
@@ -129,7 +129,10 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
try
{
broadcastStatus = automationServiceRef.registerReceiver(broadcastReceiverInstance, broadcastIntentFilter);
if(Build.VERSION.SDK_INT >= 33)
broadcastStatus = automationServiceRef.registerReceiver(broadcastReceiverInstance, broadcastIntentFilter, Context.RECEIVER_EXPORTED);
else
broadcastStatus = automationServiceRef.registerReceiver(broadcastReceiverInstance, broadcastIntentFilter);
broadcastReceiverActive = true;
}
catch(Exception e)
@@ -14,6 +14,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
@@ -508,12 +509,20 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
Calendar now = Calendar.getInstance();
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false);
if(events.size() == 0)
{
Miscellaneous.logEvent("i", "calculateNextWakeup()", "Supposedly no future events in calendar. Reading again...", 4);
events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false);
}
if (events.size() == 0)
{
Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 4);
}
else
{
Miscellaneous.logEvent("i", "calculateNextWakeup()", String.valueOf(events.size()) + " future events in calendar. Checking if one applies.", 4);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
List<Long> wakeUpCandidatesList = new ArrayList<>();
@@ -580,7 +589,10 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
}
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter);
if(Build.VERSION.SDK_INT >= 33)
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter, Context.RECEIVER_EXPORTED);
else
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter);
calendarReceiverActive = true;
@@ -136,7 +136,12 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
// Airplane mode status has changed.
Miscellaneous.logEvent("i", "Connectivity", "Airplane mode changed.", 2);
boolean isAirplaneMode = isAirplaneMode(context);
automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode);
/*
If the user doesn't have any locations this service is probably off and therefore null.
*/
if(automationServiceRef.getLocationProvider() != null)
automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.airplaneMode);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
@@ -8,10 +8,10 @@ import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.Nullable;
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;
@@ -19,23 +19,23 @@ import com.jens.automation2.TimeObject;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
{
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;
public static void startAlarmListener(final AutomationService automationServiceRef)
{
{
DateTimeListener.startAlarmListenerInternal(automationServiceRef);
}
public static void stopAlarmListener(Context context)
@@ -47,37 +47,37 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
{
return alarmListenerActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
for(int i=0; i < allRulesWithNowInTimeFrame.size(); i++)
ArrayList<Rule> allRulesWithTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
for(int i=0; i < allRulesWithTimeFrame.size(); i++)
{
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
if(allRulesWithTimeFrame.get(i).getsGreenLight(context))
allRulesWithTimeFrame.get(i).activate(automationServiceRef, false);
}
setAlarms();
setOrResetAlarms();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setAlarms()
public static void setOrResetAlarms()
{
alarmCandidates.clear();
Calendar calNow = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
clearAlarms();
int i=0;
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
// allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
/*
* Take care of regular executions, no repetitions in between.
*/
@@ -191,18 +191,17 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
* 4. Take div result +1 and add this on top of starting time
* 5. Is this next possible execution still inside timeframe? Also consider timeframes spanning over midnight
*/
Calendar calSet;
Time setTime;
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
{
Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow);
// if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
// {
Calendar calSchedule = getNextRepeatedExecution(oneTrigger);
alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
}
// }
}
}
}
@@ -213,15 +212,15 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
}
}
}
scheduleNextAlarm();
}
private static void scheduleNextAlarm()
{
Long currentTime = System.currentTimeMillis();
long currentTime = System.currentTimeMillis();
ScheduleElement scheduleCandidate = null;
if(alarmCandidates.size() == 0)
{
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
@@ -235,46 +234,48 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
else if(alarmCandidates.size() > 1)
{
scheduleCandidate = alarmCandidates.get(0);
for(ScheduleElement alarmCandidate : alarmCandidates)
{
if(Math.abs(currentTime - alarmCandidate.time.getTimeInMillis()) < Math.abs(currentTime - scheduleCandidate.time.getTimeInMillis()))
scheduleCandidate = alarmCandidate;
}
}
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);
centralAlarmManagerInstance.setExactAndAllowWhileIdle(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");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis());
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
}
public static void clearAlarms()
{
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for(int requestCode : requestCodeList)
{
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
if(alarmPendingIntent == null)
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent);
}
requestCodeList.clear();
}
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
{
if(!alarmListenerActive)
@@ -282,12 +283,11 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
DateTimeListener.automationServiceRef = givenAutomationServiceRef;
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
alarmListenerActive = true;
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
DateTimeListener.setAlarms();
DateTimeListener.setOrResetAlarms();
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
@@ -297,23 +297,20 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
}
private static void stopAlarmListenerInternal()
{
if(alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false;
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
}
public static void reloadAlarms()
{
DateTimeListener.setAlarms();
}
@Override
public void startListener(AutomationService automationService)
{
@@ -371,46 +368,217 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
static int getNextDayIntForExecution(Trigger trigger)
{
Calendar calSet;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
Calendar now = Calendar.getInstance();
if(tf.getDayList().contains(now.get(Calendar.DAY_OF_WEEK)))
return now.get(Calendar.DAY_OF_WEEK);
else
{
int dayNumberOfNextExecution = now.get(Calendar.DAY_OF_WEEK);
while(!tf.getDayList().contains(dayNumberOfNextExecution))
{
dayNumberOfNextExecution++;
if(dayNumberOfNextExecution > 6)
dayNumberOfNextExecution = 1;
}
return dayNumberOfNextExecution;
}
}
static int getDayDelta(Calendar now, int dayNumberOfNextExecution)
{
int result = dayNumberOfNextExecution - now.get(Calendar.DAY_OF_WEEK);
if(result >= 0)
return result;
else
return 6 + result;
}
@Nullable
@RequiresApi(api = Build.VERSION_CODES.N)
public static Calendar getNextRepeatedExecution(Trigger trigger)
{
Calendar now = Calendar.getInstance();
Miscellaneous.logEvent("i", "DateTimeListener", "Checking for next repetition execution after " + Miscellaneous.formatDate(now.getTime()), 5);
Calendar calculationStart, calSchedule = null;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(trigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
else
setTime = tf.getTriggerTimeStop();
calSet = (Calendar) now.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// If the starting time is a day ahead remove 1 day.
if(calSet.getTimeInMillis() > now.getTimeInMillis())
calSet.add(Calendar.DAY_OF_MONTH, -1);
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calSet.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
long nextScheduleTimestamp = (calSet.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition());
Calendar calSchedule = Calendar.getInstance();
calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000);
/*
* Das war mal aktiviert. Allerdings: Die ganze Funktion liefert zurück, wenn die Regel NOCH nicht
* zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten.
Are we inside of the timeframe or outside?
Inside -> is this demanded?
Yes:
If last execution known, calculate from it
If not known, calculate from start of timeframe
No:
Use end-time and add repetition
Outside? -> is this demanded?
Yes:
If last execution known, calculate from it
If not known, calculate from end of timeframe
No:
Use start-time and add repetition
*/
return calSchedule;
if(areWeInTimeFrame(trigger, new Date()))
{
if(trigger.getTriggerParameter())
{
if(trigger.getParentRule().getLastExecution() != null)
{
calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone();
}
else
{
calculationStart = (Calendar) now.clone();
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours());
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0);
}
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
}
else
{
calculationStart = (Calendar) now.clone();
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours());
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0);
calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) tf.getRepetition());
}
}
else // not in timeframe
{
if (!trigger.getTriggerParameter())
{
if (trigger.getParentRule().getLastExecution() != null)
{
calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone();
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
return calSchedule;
}
else
{
calculationStart = (Calendar) now.clone();
if(tf.getDayList().contains(now.get(Calendar.DAY_OF_WEEK)))
{
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours());
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0);
calculationStart.add(Calendar.SECOND, (int) tf.getRepetition());
int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger));
calculationStart.add(Calendar.DAY_OF_WEEK, dayDelta);
}
calSchedule = (Calendar) calculationStart.clone();
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
return calSchedule;
}
/*long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));*/
}
else
{
calculationStart = (Calendar) now.clone();
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours());
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0);
calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) (tf.getRepetition()));
}
if (Miscellaneous.compareTimes(calSchedule, now) > 0)
calSchedule.add(Calendar.DAY_OF_MONTH, 1);
}
int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger));
calSchedule.add(Calendar.DAY_OF_WEEK, dayDelta);
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
}
else
Miscellaneous.logEvent("i", "DateTimeListener", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5);
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Trigger " + trigger.toString() + " is not configured to repeat.", 5);
return null;
return calSchedule;
}
public static boolean areWeInTimeFrame(Trigger trigger, Object triggeringObject)
{
/*
* Use format known from Automation
* 07:30:00/17:30:00/23456/300 <-- last parameter is optional: repetition in seconds
* Also required: inside or outside that interval
*/
Date triggeringTime;
// if(triggeringObject instanceof Date)
// triggeringTime = (Date)triggeringObject;
// else
triggeringTime = new Date();
String timeString = String.valueOf(triggeringTime.getHours()) + ":" + String.valueOf(triggeringTime.getMinutes()) + ":" + String.valueOf(triggeringTime.getSeconds());
TimeObject nowTime = TimeObject.valueOf(timeString);
Calendar calNow = Calendar.getInstance();
try
{
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK)))
{
if(
// Regular case, start time is lower than end time
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
)
||
// Other case, start time higher than end time, timeframe goes over midnight
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0
&&
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0)
)
||
// further case: start and end times are identical, meaning a 24h window
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) == 0
)
)
return true;
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "Trigger", "There was an error while checking if the time based trigger applies: " + Log.getStackTraceString(e), 1);
return false;
}
return false;
}
}
@@ -34,11 +34,11 @@ public class DeviceOrientationListener implements SensorEventListener, Automatio
static int sensorValueCounter = 0;
// Gravity rotational data
float gravity[];
float[] gravity;
// Magnetic rotational data
float magnetic[]; //for magnetic rotational data
float accels[] = new float[3];
float mags[] = new float[3];
float[] magnetic; //for magnetic rotational data
float[] accels = new float[3];
float[] mags = new float[3];
float[] values = new float[3];
boolean hasMagneticSensor=false;
@@ -53,12 +53,14 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
{
try
{
/*Broadcast Action: Wired Headset plugged in or unplugged.
The intent will have the following extra values:
state - 0 for unplugged, 1 for plugged.
name - Headset type, human readable string
microphone - 1 if headset has a microphone, 0 otherwise*/
/*
Broadcast Action: Wired Headset plugged in or unplugged.
The intent will have the following extra values:
state - 0 for unplugged, 1 for plugged.
name - Headset type, human readable string
microphone - 1 if headset has a microphone, 0 otherwise
*/
int state = intent.getExtras().getInt("state");
String name = intent.getExtras().getString("name");
@@ -8,10 +8,10 @@ import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
@@ -36,18 +36,8 @@ public class NfcReceiver
public static NfcAdapter getNfcAdapter(Context context)
{
if(nfcAdapter == null)
{
if(Build.VERSION.SDK_INT <= 10)
{
// NFC not supported until after Gingerbread.
Miscellaneous.logEvent("w", "NFC", context.getResources().getString(R.string.nfcNotSupportedInThisAndroidVersionYet), 3);
return null;
}
else
{
nfcAdapter = NfcAdapter.getDefaultAdapter(context);
}
}
nfcAdapter = NfcAdapter.getDefaultAdapter(context);
return nfcAdapter;
}
@@ -66,9 +56,9 @@ public class NfcReceiver
if(action == null)
{
Miscellaneous.logEvent("i", "NFC", "action=null", 5);
return;
return;
}
if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
{
Miscellaneous.logEvent("i", "NFC", "ACTION_NDEF_DISCOVERED", 4);
@@ -91,28 +81,6 @@ public class NfcReceiver
new NdefReaderTask().execute(tag);
}
}
// else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
// {
//
// // In case we would still use the Tech Discovered Intent
// Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// String[] techList = tag.getTechList();
// String searchedTech = Ndef.class.getName();
//
// for (String tech : techList)
// {
// if (searchedTech.equals(tech))
// {
// new NdefReaderTask().execute(tag);
// break;
// }
// }
// }
// else
// {
// // No NFC NDEF intent
// Miscellaneous.logEvent("w", "NFC", context.getResources().getString(R.string.nfcNoNdefIntentBut) + " " + action + ".", 5);
// }
}
@SuppressLint("NewApi")
@@ -307,7 +275,7 @@ public class NfcReceiver
{
format.connect();
format.format(completeMessageToWrite);
Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2);
Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2);
return true;
}
catch(IOException e)
@@ -322,7 +290,7 @@ public class NfcReceiver
Miscellaneous.logEvent("e", "NFC", "Error writing tag: " + Log.getStackTraceString(e), 2);
}
return false;
return false;
}
public static boolean checkNfcRequirements(Context context, boolean showErrorMessage)
@@ -334,15 +302,7 @@ public class NfcReceiver
return false;
}
else if(Build.VERSION.SDK_INT <= 10)
{
// NFC not supported until after Gingerbread.
if(showErrorMessage)
Toast.makeText(context, context.getResources().getString(R.string.nfcNotSupportedInThisAndroidVersionYet), Toast.LENGTH_LONG).show();
return false;
}
return true;
}
}
}
@@ -100,7 +100,7 @@ public class NotificationListener extends NotificationListenerService// implemen
synchronized boolean checkNotification(boolean created, StatusBarNotification sbn)
{
//TODO: Merge with functino in Trigger class
//TODO: Merge with function in Trigger class
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
{
lastNotification = convertNotificationToSimpleNotification(created, sbn);
@@ -146,13 +146,13 @@ public class NotificationListener extends NotificationListenerService// implemen
try
{
if (extras.containsKey(EXTRA_TEXT))
text = extras.getString(EXTRA_TEXT).toString();
text = String.valueOf(extras.getCharSequence(EXTRA_TEXT));
}
catch (NullPointerException e)
{
// in stacked notifications the "surrounding" element has no text, only a title
if (extras.containsKey(EXTRA_TEXT) && extras.get(EXTRA_TEXT) != null)
text = extras.get(EXTRA_TEXT).toString();
text = String.valueOf(extras.getCharSequence(EXTRA_TEXT));
}
SimpleNotification returnNotification = new SimpleNotification();
@@ -0,0 +1,162 @@
package com.jens.automation2.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.util.ArrayList;
public class ProximityReceiver implements AutomationListenerInterface
{
public static AutomationService automationServiceRef = null;
static float proximityLevel = -1; // initialize with a better value than this
static boolean proximityReceiverActive = false;
SensorManager sensorManager;
Sensor proximitySensor;
static ProximityReceiver proximityReceiverInstance = null;
public static float getProximityLevel()
{
return proximityLevel;
}
public static void startProximityReceiver(final AutomationService automationServiceRef)
{
if(!proximityReceiverActive)
{
ProximityReceiver.automationServiceRef = automationServiceRef;
if(proximityReceiverInstance == null)
proximityReceiverInstance = new ProximityReceiver();
proximityReceiverInstance.startListener(automationServiceRef);
proximityReceiverActive = true;
}
}
public static void stopProximityReceiver()
{
if(proximityReceiverActive)
{
if(proximityReceiverInstance != null)
{
proximityReceiverInstance = null;
}
proximityReceiverActive = false;
}
}
@Override
public void startListener(AutomationService automationService)
{
if(!proximityReceiverActive)
{
ProximityReceiver.automationServiceRef = automationServiceRef;
sensorManager = (SensorManager) automationService.getSystemService(Context.SENSOR_SERVICE);
// from sensor service we are
// calling proximity sensor
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// handling the case if the proximity
// sensor is not present in users device.
if (proximitySensor == null)
{
Miscellaneous.logEvent("w", "No proximity sensor", "Device doesn\'t seem to have a proximity sensor.", 4);
}
else
{
// registering our sensor with sensor manager.
sensorManager.registerListener(proximitySensorEventListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
}
proximityReceiverActive = true;
}
}
@Override
public void stopListener(AutomationService automationService)
{
if(proximityReceiverActive)
{
if(proximityReceiverInstance != null)
{
if(proximitySensor != null)
sensorManager.unregisterListener(proximitySensorEventListener);
proximityReceiverInstance = null;
}
proximityReceiverActive = false;
}
}
SensorEventListener proximitySensorEventListener = new SensorEventListener()
{
@Override
public void onSensorChanged(SensorEvent sensorEvent)
{
// check if the sensor type is proximity sensor.
if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY)
{
proximityLevel = (int)sensorEvent.values[0];
Miscellaneous.logEvent("i", "Proximity", String.valueOf(proximityLevel), 5);
// if (sensorEvent.values[0] == 0)
// {
//// sensorStatusTV.setText("Near");
// }
// else
// {
//// sensorStatusTV.setText("Away");
// }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.proximity);
for(Rule oneRule : ruleCandidates)
{
if(oneRule.getsGreenLight(automationServiceRef))
oneRule.activate(automationServiceRef, false);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i)
{
}
};
public static boolean haveAllPermission()
{
return ActivityPermissions.havePermission(ActivityPermissions.permissionNameProximity, Miscellaneous.getAnyContext());
}
@Override
public boolean isListenerRunning()
{
return proximityReceiverActive;
}
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
// actually monitors several
return new Trigger_Enum[] { Trigger_Enum.proximity };
}
}
@@ -76,12 +76,12 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
if(action.equals(Intent.ACTION_TIMEZONE_CHANGED))
{
Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3);
DateTimeListener.reloadAlarms();
DateTimeListener.setOrResetAlarms();
}
else if(action.equals(Intent.ACTION_TIME_CHANGED))
{
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 3);
DateTimeListener.reloadAlarms();
DateTimeListener.setOrResetAlarms();
}
}
@Override
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

+11 -11
View File
@@ -14,7 +14,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/etActivityOrActionPath"
@@ -45,7 +45,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvPoiTitle"
@@ -77,7 +77,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvRuleTitle"
@@ -109,7 +109,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvProfileTitle"
@@ -142,12 +142,12 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/toggableRules"
android:text="@string/toggleableRules"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
@@ -160,7 +160,7 @@
android:id="@+id/tvToggableHelpText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/helpTextToggable" />
android:text="@string/helpTextToggleable" />
</LinearLayout>
@@ -169,7 +169,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvTimeFrameTitle"
android:layout_width="wrap_content"
@@ -197,7 +197,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvProcessMonitoringTitle"
@@ -225,7 +225,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -251,7 +251,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -31,6 +31,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/screenBrightGoogleComment" />
<Button
android:layout_marginTop="@dimen/default_margin"
android:id="@+id/bApplyBrightness"
@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TableLayout
android:id="@+id/tlTriggerUrlAuthentication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/username" />
<EditText
android:id="@+id/etTriggerUrlUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:enabled="false"
android:inputType="text" >
</EditText>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/password" />
<EditText
android:id="@+id/etTriggerUrlPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:enabled="false"
android:inputType="textPassword" >
</EditText>
</TableRow>
</TableLayout>
<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/type" />
<Spinner
android:id="@+id/spinnerSettingDataType"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</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/settingName" />
<EditText
android:id="@+id/etSettingName"
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/settingValue" />
<EditText
android:id="@+id/etSettingValue"
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" />
<TextView
android:id="@+id/tvSetSystemSettingExamples"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/examplesWriteSecureSettings" />
<TextView
android:id="@+id/tvSetSystemSettingNoticeWriteSecureSettings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/writeSecureSettingsNotice" />
<Button
android:id="@+id/bSaveSetSystemSetting"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>
@@ -140,6 +140,17 @@
</TableRow>
<TableRow>
<TextView
android:id="@+id/tvHttpParameterExplanation"
android:layout_span="2"
android:layout_marginBottom="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -13,7 +13,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -157,9 +157,10 @@
android:layout_height="wrap_content"
android:text="@string/change" />
<TextView
android:id="@+id/tvNotificationsVolume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/volumeRingtoneNotifications"
android:text="@string/volumeNotifications"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginLeft="40dp" />
<SeekBar
@@ -167,6 +168,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp" />
<CheckBox
android:id="@+id/checkBoxChangeVolumeRingtones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/change" />
<TextView
android:id="@+id/tvRingtoneVolume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/volumeRingtone"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginLeft="40dp" />
<SeekBar
android:id="@+id/seekBarVolumeRingtones"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp" />
<CheckBox
android:id="@+id/checkBoxChangeVolumeAlarms"
@@ -337,6 +356,5 @@
</LinearLayout>
</LinearLayout>
</ScrollView>
</ScrollView>
@@ -15,7 +15,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -123,7 +123,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/barBackgroundColor"
android:background="@color/cardview_shadow_start_color"
android:orientation="horizontal">
<TextView
@@ -160,7 +160,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/barBackgroundColor"
android:background="@color/cardview_shadow_start_color"
android:orientation="horizontal">
<TextView
@@ -13,7 +13,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -31,7 +31,7 @@
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/VariableKey" />
@@ -47,21 +47,42 @@
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_gravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/variableValue" />
android:text="@string/variableValue"
android:layout_marginRight="@dimen/default_margin" />
<EditText
android:id="@+id/etVariableValueTrigger"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/etVariableValueTrigger"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/mayUseRegularExpressions" />
</LinearLayout>
</TableRow>
</TableLayout>
<CheckBox
android:id="@+id/chkTriggerVariableDirection"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:checked="true"
android:text="@string/matches" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -16,7 +16,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -83,7 +83,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/proximity"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:layout_marginBottom="@dimen/default_margin" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingRight="@dimen/default_margin"
android:text="@string/state"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.slider.RangeSlider
android:id="@+id/rsProximity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="0"
android:valueTo="10"
android:stepSize="0.1"
android:theme="@style/AppThemeCompat" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/close"
android:layout_alignParentLeft="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/far"
android:layout_alignParentRight="true"/>
</RelativeLayout>
</LinearLayout>
</TableRow>
</TableLayout>
<TextView
android:id="@+id/tvTriggerProximityHint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:textColor="@color/red"
android:text="@string/deviceDoesntHaveProximitySensor" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/testArea"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/proximitySensorHint" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/testAreaProximityComment" />
<SeekBar
android:id="@+id/sbProximityTest"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvProximityCurrentValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bTriggerProximitySave"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>
@@ -1,44 +1,48 @@
<?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="fill_parent"
android:layout_weight="30"
android:layout_margin="@dimen/default_margin" >
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_margin="@dimen/default_margin"
android:layout_weight="30">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/tvRuleTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker
android:id="@+id/tpTimeFrameStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvLastRule"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/end"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker
android:id="@+id/tpTimeFrameStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tvRuleTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker
android:id="@+id/tpTimeFrameStart"
android:descendantFocusability="blocksDescendants"
android:saveEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvLastRule"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/end"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker
android:id="@+id/tpTimeFrameStop"
android:descendantFocusability="blocksDescendants"
android:saveEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
<TextView
android:id="@+id/textView2"
@@ -47,24 +51,24 @@
android:text="@string/insideOrOutsideTimeFrames"
android:textAppearance="?android:attr/textAppearanceLarge" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radioTimeFrameEntering"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/entering" />
<RadioButton
android:id="@+id/radioTimeFrameLeaving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/leaving" />
<RadioButton
android:id="@+id/radioTimeFrameEntering"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/entering" />
<RadioButton
android:id="@+id/radioTimeFrameLeaving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/leaving" />
</RadioGroup>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
@@ -80,52 +84,52 @@
<TextView
android:id="@+id/tvDaysHint"
android:layout_marginVertical="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:textColor="@color/red" />
<CheckBox
android:id="@+id/checkMonday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/monday" />
<CheckBox
android:id="@+id/checkTuesday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tuesday" />
<CheckBox
android:id="@+id/checkWednesday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wednesday" />
<CheckBox
android:id="@+id/checkThursday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/thursday" />
<CheckBox
android:id="@+id/checkFriday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/friday" />
<CheckBox
android:id="@+id/checkSaturday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/saturday" />
<CheckBox
android:id="@+id/checkSunday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sunday" />
<CheckBox
android:id="@+id/checkMonday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/monday" />
<CheckBox
android:id="@+id/checkTuesday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tuesday" />
<CheckBox
android:id="@+id/checkWednesday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wednesday" />
<CheckBox
android:id="@+id/checkThursday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/thursday" />
<CheckBox
android:id="@+id/checkFriday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/friday" />
<CheckBox
android:id="@+id/checkSaturday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/saturday" />
<CheckBox
android:id="@+id/checkSunday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sunday" />
<ImageView
android:layout_width="match_parent"
@@ -136,7 +140,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
android:orientation="horizontal">
<CheckBox
android:id="@+id/chkRepeat"
@@ -146,22 +150,22 @@
<EditText
android:id="@+id/etRepeatEvery"
android:layout_marginLeft="@dimen/default_margin"
android:minWidth="75dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/default_margin"
android:enabled="false"
android:inputType="numberSigned" />
android:inputType="numberSigned"
android:minWidth="75dp" />
</LinearLayout>
<Button
android:id="@+id/bSaveTimeFrame"
<Button
android:id="@+id/bSaveTimeFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
android:text="@string/save" />
</LinearLayout>
</ScrollView>
+49 -59
View File
@@ -9,41 +9,48 @@
android:title="@string/generalSettings">
<CheckBoxPreference
android:key="startServiceAtSystemBoot"
android:summary="@string/onOff"
android:title="@string/startAtSystemBoot" />
android:key="startServiceAtSystemBoot"
android:summary="@string/onOff"
android:title="@string/startAtSystemBoot" />
<CheckBoxPreference
android:key="startServiceAfterAppUpdate"
android:summary="@string/startServiceAfterAppUpdate"
android:title="@string/startServiceAfterAppUpdateShort" />
<!--
<CheckBoxPreference
android:key="startNewThreadForRuleActivation"
android:summary="@string/startNewThreadForRuleExecution"
android:title="@string/newThreadRules" />
-->
<CheckBoxPreference
android:key="showIconWhenServiceIsRunning"
android:summary="@string/showIconWhenServiceIsRunning"
android:title="@string/showIcon" />
android:key="startServiceAfterAppUpdate"
android:summary="@string/startServiceAfterAppUpdate"
android:title="@string/startServiceAfterAppUpdateShort" />
<CheckBoxPreference
android:key="writeLogFile"
android:summary="@string/onOff"
android:title="@string/writeLogFile" />
android:key="showIconWhenServiceIsRunning"
android:summary="@string/showIconWhenServiceIsRunning"
android:title="@string/showIcon" />
<CheckBoxPreference
android:key="logToConsole"
android:summary="@string/onOff"
android:title="@string/logToConsole" />
<CheckBoxPreference
android:key="writeLogFile"
android:summary="@string/onOff"
android:title="@string/writeLogFile" />
<EditTextPreference
android:key="logLevel"
android:summary="@string/logLevelSummary"
android:title="@string/logLevelTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="logFileMaxSize"
android:summary="@string/logFileMaxSizeSummary"
android:title="@string/logFileMaxSizeTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<ListPreference
android:key="uiTheme"
android:title="@string/uiTheme"
android:summary="@string/uiThemeSummary"
android:entries="@array/uiThemeOptions"
android:entryValues="@array/uiThemeOptionsValues" />
<ListPreference
android:key="startScreen"
@@ -114,21 +121,11 @@
</PreferenceCategory>
<PreferenceCategory
android:summary="@string/positioningSettings"
android:title="@string/positioningSettings">
<!-- android:id="@id/lstPositioningEngine"-->
<!--
<ListPreference
android:title="@string/positioningEngine"
android:key="positioningEngine"
android:defaultValue="0"
android:entries="@array/positioningEngineOptions"
android:entryValues="@array/positioningEngineOptionsValues" />
-->
<CheckBoxPreference
<CheckBoxPreference
android:key="useWifiForPositioning"
android:summary="@string/listenToWifiState"
android:title="@string/wifiState" />
@@ -142,19 +139,19 @@
android:key="useAccelerometerAfterIdleTime"
android:summary="@string/accelerometerTimer"
android:title="@string/cellMastIdleTime"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="accelerometerMovementThreshold"
android:summary="@string/accelerometerThresholdDescription"
android:title="@string/accelerometerThreshold"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="speedMaximumTimeBetweenLocations"
android:summary="@string/speedMaximumTimeBetweenLocations"
android:title="@string/speedMaximumTime"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<CheckBoxPreference
android:key="rememberLastActivePoi"
@@ -176,37 +173,31 @@
android:key="MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE"
android:summary="@string/minimumDistanceChangeForGpsLocationUpdates"
android:title="@string/distanceForGpsUpdate"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE"
android:summary="@string/minimumDistanceChangeForNetworkLocationUpdates"
android:title="@string/distanceForNetworkUpdate"
android:inputType="number"></EditTextPreference>
<!-- We won't need this setting anymore, at least it won't be available for the user.
<EditTextPreference
android:key="SATISFACTORY_ACCURACY_GPS"
android:summary="@string/satisfactoryAccuracyGps"
android:title="@string/gpsAccuracy"
android:inputType="number"></EditTextPreference>
-->
android:inputType="number" />
<EditTextPreference
android:key="SATISFACTORY_ACCURACY_NETWORK"
android:summary="@string/satisfactoryAccuracyNetwork"
android:title="@string/networkAccuracy"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="MINIMUM_TIME_BETWEEN_UPDATE"
android:summary="@string/minimumTimeForLocationUpdates"
android:title="@string/timeForUpdate"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="gpsTimeout"
android:summary="@string/timeoutForGpsComparisonsSummary"
android:title="@string/timeoutForGpsComparisonsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number"/>
</PreferenceCategory>
@@ -218,19 +209,19 @@
android:key="timeBetweenNoiseLevelMeasurements"
android:summary="@string/timeBetweenNoiseLevelMeasurementsSummary"
android:title="@string/timeBetweenNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="lengthOfNoiseLevelMeasurements"
android:summary="@string/lengthOfNoiseLevelMeasurementsSummary"
android:title="@string/lengthOfNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="referenceValueForNoiseLevelMeasurements"
android:summary="@string/referenceValueForNoiseLevelMeasurementsSummary"
android:title="@string/referenceValueForNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
@@ -247,19 +238,19 @@
android:key="httpAttempts"
android:summary="@string/httpAttemptsSummary"
android:title="@string/httpAttemptsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="httpAttemptsTimeout"
android:summary="@string/httpAttemptsTimeoutSummary"
android:title="@string/httpAttemptsTimeoutTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="httpAttemptGap"
android:summary="@string/httpAttemptGapSummary"
android:title="@string/httpAttemptGapTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
@@ -271,7 +262,7 @@
android:key="timeBetweenProcessMonitorings"
android:summary="@string/timeBetweenProcessMonitoringsSummary"
android:title="@string/timeBetweenProcessMonitoringsTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
@@ -283,7 +274,7 @@
android:key="acceptDevicePositionSignalEveryX_MilliSeconds"
android:summary="@string/deviceOrientationTimeAcceptIntervalSummary"
android:title="@string/deviceOrientationTimeAcceptIntervalTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
@@ -295,13 +286,13 @@
android:key="activityDetectionFrequency"
android:summary="@string/activityDetectionFrequencySummary"
android:title="@string/activityDetectionFrequencyTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
<EditTextPreference
android:key="activityDetectionRequiredProbability"
android:summary="@string/activityDetectionRequiredProbabilitySummary"
android:title="@string/activityDetectionRequiredProbabilityTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
@@ -313,9 +304,8 @@
android:key="musicCheckFrequency"
android:summary="@string/musicCheckFrequencySummary"
android:title="@string/musicCheckFrequencyTitle"
android:inputType="number"></EditTextPreference>
android:inputType="number" />
</PreferenceCategory>
</PreferenceScreen>
@@ -15,7 +15,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
@@ -370,11 +370,12 @@
android:text="@string/donate" />
<TextView
android:id="@+id/tvContactNotice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:gravity="center_horizontal"
android:text="@string/emailContactNotice" />
android:text="@string/contactNotice" />
</LinearLayout>
+1 -1
View File
@@ -30,7 +30,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvRuleTitle"
@@ -34,7 +34,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvRuleTitle"
+1 -1
View File
@@ -48,7 +48,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:id="@+id/tvLastRule"
@@ -14,7 +14,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" >
android:background="@color/cardview_shadow_start_color" >
<TextView
android:layout_width="wrap_content"
+42 -9
View File
@@ -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 (&lt; 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="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 (&lt; 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[w] - Wochentag in Textform\n[F] - Monat in Textform\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[last_trigger_url_result] - Das Ergebnis der letzten Ausführung der trigger url-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>
@@ -120,12 +120,12 @@
<string name="soundSettings">Ton Einstellungen</string>
<string name="showHelp">Hilfe</string>
<string name="rules">Regeln</string>
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.\nDie Begriffe Auslöser und Bedingung werden synonym verwendet. Alle von ihnen sind Bedingungen, aber die letzte, die ihren erforderlichen Wert erfüllt, könnte als Auslöser bezeichnet werden, da sie das letzte Teil des Puzzles ist, um eine Regel auszuführen.</string>
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.\nDie Begriffe Auslöser und Bedingung werden synonym verwendet. Alle von ihnen sind Bedingungen, aber die letzte, die ihren erforderlichen Wert erfüllt, könnte als Auslöser bezeichnet werden, da sie das letzte Teil des Puzzles ist, um eine Regel auszuführen.\nWenn Sie bestimmte Werte aus einer Regel speichern und in einer anderen Regel auswerten möchten, schauen Sie sich mal den Auslöser/Aktion Variable an.</string>
<string name="timeframes">Zeiträume</string>
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
<string name="toggableRules">Unschaltbare Regeln</string>
<string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umkehrbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umkehrbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
<string name="toggleableRules">Unschaltbare Regeln</string>
<string name="helpTextToggleable">Regeln haben eine Einstellung namens \"Umkehrbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umkehrbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
<string name="helpTextProcessMonitoring">Wenn Sie eine Regel mit einer Prozess Überwachung erstellen, wird die Anwendung in regelmäßigen Abständen nach diesem Prozess schauen. Wie häufig können Sie in den Einstellungen festlegen. Das mag zwar in vielen Fällen langsam reagieren, aber eine permanente Überwachung würde zuviel Akkuleistung kosten. Und das Betriebssystem stellt dafür keinen Broadcast zur Verfügung.</string>
<string name="helpTitleEnergySaving">Energiespareinstellungen</string>
<string name="helpTextEnergySaving">Viele Gerätehersteller versuchen Energie zu sparen, indem die Hintergrundaktivitäten vieler Anwendungen eingeschränkt werden. Unglücklicherweise führt das häufig dazu, dass diese Anwendungen nicht mehr zufällig funktionieren; das gilt auch für Automation. Schauen Sie sich <a href="https://dontkillmyapp.com/">diese Seite</a> an, um herauszufinden, wie Sie Automation auf Ihrem Gerät von dieser Behandlung ausschließen können.</string>
@@ -302,7 +302,6 @@
<string name="nfcTagFoundWithText">Tag gefunden mit Bezeichner:</string>
<string name="nfcUnsupportedEncoding">Nicht unterstützte Kodierung:</string>
<string name="nfcNoNdefIntentBut">Kein NFC NDEF intent, sondern</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC wird in dieser Android Version noch nicht unterstützt.</string>
<string name="cantRunRule">Regeln können nicht ausgeführt werden.</string>
<string name="nfcApplyTagToRule">Aktuellen Tag in Regel übernehmen</string>
<string name="nfcTagReadSuccessfully">Tag erfolgreich gelesen.</string>
@@ -368,7 +367,7 @@
<string name="headsetConnected">Headset (Art: %1$s) verbunden</string>
<string name="headsetDisconnected">Headset (type: %1$s) getrennt</string>
<string name="headphoneSimple">Kopfhörer</string>
<string name="headphoneMicrophone">Mikrofon</string>
<string name="headphoneMicrophone">mit Mikrofon</string>
<string name="headphoneAny">Egal</string>
<string name="headphoneSelectType">Kopfhörer Typ auswählen</string>
<string name="whatsThis">Was ist das?</string>
@@ -388,7 +387,8 @@
<string name="notificationRingtone">Ton für Benachrichtigungen</string>
<string name="hapticFeedback">Haptische Rückmeldung (vibrieren bei Bildschirmberührung)</string>
<string name="volumeMusicVideoGameMedia">Musik, Videos, Spiele und andere Medien</string>
<string name="volumeRingtoneNotifications">Klingeltöne und Benachrichtungen</string>
<string name="volumeNotifications">Benachrichtungen</string>
<string name="volumeRingtone">Klingelton</string>
<string name="volumeAlarms">Wecker</string>
<string name="change">Ändern</string>
<string name="audibleSelection">Hörbare Auswahl (Ton bei Bildschirmauswahl)</string>
@@ -697,7 +697,7 @@
<string name="screenIs">Bildschirm ist %1$s</string>
<string name="sendEmailToDev">Email an Entwickler schicken</string>
<string name="controlCenter">Steuerungszentrale</string>
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.\nViele Fragen können nicht einfach gleich beantwortet werden, sondern erfordern eine technische Prüfung. Haben Sie also bitte etwas Geduld.</string>
<string name="contactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.\nViele Fragen können nicht einfach gleich beantwortet werden, sondern erfordern eine technische Prüfung. Haben Sie also bitte etwas Geduld.\n\nAlternativ können Sie Ihre Frage im <a href="https://forum.server47.de">Forum</a> stellen.</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Aufgrund Google\'s unendlicher Weisheit, ist die letzte Android Version, mit der diese Funktion noch funktioniert, die Version %1$s. Sie können es hier einrichten, aber vermutlich wird es keine Auswirkung haben.</string>
<string name="musicPlaying">Musik läuft</string>
<string name="selectParameters">Wählen Sie die Parameter</string>
@@ -778,6 +778,7 @@
<string name="checkVariable">Variable prüfen</string>
<string name="checkVariableExplanation">Wenn Sie den Wert der Variablen leer lassen, darf sie nicht gesetzt sein, damit die Bedingung als erfüllt gilt.</string>
<string name="variableCheckString">wenn Variable %1$s den Wert %2$s hat</string>
<string name="variableCheckStringNot">wenn die Variable %1$s nicht %2$s ist</string>
<string name="variableCheckStringDeleted">wenn Variable %1$s nicht gesetzt ist</string>
<string name="messageType">Nachrichtentyp</string>
<string name="sms">SMS</string>
@@ -813,7 +814,7 @@
<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="triggerUrlVariableHint">Das Ergebnis dieser Anfrage wird in der Variablen last_trigger_url_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>
@@ -854,5 +855,37 @@
<string name="notCharging">nicht laden</string>
<string name="triggerChargingComment">Der Typ wird nur ausgewertet, wenn das Gerät aufgeladen wird. Wenn \"Nicht laden\" ausgewählt ist, wird es bei jedem vorherigen Ladetyp ausgelöst. Wenn Sie dies auswerten möchten, sollten Sie die Verwendung der Variablen trigger/action in Betracht ziehen.</string>
<string name="helpTextProfiles">Ein Profil ist eine Sammlung von Einstellungen für Klingeltöne, Lautstärke und andere audiobezogene Einstellungen, die Sie über Regeln oder manuell anwenden können.\\n\\nEs ist auch möglich, das zuletzt aktivierte Profil als Auslöser abzufragen. Im Normalfall wird nur abgefragt, ob das Profil das zuletzt aktivierte war (unabhängig davon, ob in der Zwischenzeit bestimmte Audioeinstellungen geändert wurden). Sie können aber auch die einzelnen Einstellungen vergleichen lassen.</string>
<string name="serviceWontStartPermissions">Für keine Regel liegen vollständige Berechtigungen vor. Der Dienst kann nicht starten.</string>
<string name="serviceWontStartNoActivatedRules">Es sind keine aktivierten Regeln definiert. Der Dienst wird nicht gestartet.</string>
<string name="importChooseFolderNotice">Versuchen Sie im folgenden Dialog nicht, bestimmte Dateien auszuwählen, sondern wählen Sie den Ordner aus, in dem sich die Automation-Sicherungsdateien befinden. Wenn die Schaltfläche \"Auswählen\" deaktiviert ist, haben Sie eine Android-Einschränkung gefunden. Versuchen Sie in diesem Fall zuerst, die Dateien in ein Unterverzeichnis zu verschieben.</string>
<string name="matches">stimmt überein</string>
<string name="doesNotMatch">stimmt nicht überein</string>
<string name="logToConsole">In Konsole protokollieren (logcat)</string>
<string name="locationPermissionRequired">Um fortzufahren, ist die Standortberechtigung erforderlich.</string>
<string name="Android14TimePickerHint">Anscheinend gibt es in Android 14 einen Fehler in Bezug auf einen Zeitauswahl-Dialog. Wenn der folgende Bildschirm abstürzt, wenn Sie versuchen, die Aufwärts- und Ab-Tasten neben einem Feld zu verwenden, versuchen Sie stattdessen, Zahlen über die Tastatur einzugeben. Ich habe nie eine Lösung dafür gefunden und meine App ist nicht die einzige, die betroffen ist. Es sieht so aus, als ob dies in Android 15 behoben wurde.</string>
<string name="screenBrightGoogleComment">Da jemand bei Google anscheinend was geraucht hat, verhält sich die Einstellung der Bildschirmhelligkeit in einigen Android-Versionen sehr seltsam. Dieses Verhalten hat nichts mit dem zu tun, was Sie laut ihrer eigenen Dokumentation erwarten würden. Ich habe versucht, mich so gut wie möglich daran anzupassen, erwarte aber keine sehr genauen Einstellungen. Das bedeutet, dass die resultierende Einstellung etwas von der hier konfigurierten abweichen kann.</string>
<string name="version143StartOtherActivityHint">In Version 1.8.2 war es notwendig, die Art und Weise, wie Aktionen zum Starten anderer Programme gespeichert werden, zu überarbeiten. Die Kompatibilität konnte nicht sichergestellt werden. Bitte überprüfen und bearbeiten Sie Ihre Aktionen zum Starten anderer Aktivitäten, um sicherzustellen, dass sie noch funktionieren.</string>
<string name="disable">Deaktivieren</string>
<string name="enable">Aktivieren</string>
<string name="uiThemeClassic">Klassisches UI-Thema</string>
<string name="uiThemeCompat">Materialdesign-UI-Thema</string>
<string name="permissionForegroundServiceTypeSpecialUseRequired">Berechtigung FOREGROUND_SERVICE_TYPE_SPECIAL_USE ist erforderlich, um zu starten.</string>
<string name="uiTheme">Thema der grafischen Oberfläche</string>
<string name="uiThemeSummary">Das Thema der grafischen Oberfläche. Anwendungs-Neustart ist notwendig.</string>
<string name="proximity">Nähe</string>
<string name="testArea">Testfeld</string>
<string name="testAreaProximityComment">Nähern Sie sich Ihrem Gerät, um zu sehen, wie es sich verhält.</string>
<string name="deviceDoesntHaveProximitySensor">Ihr Gerät scheint über keinen Näherungssensor zu verfügen.</string>
<string name="proximitySensorHint">Der Näherungssensor verhält sich auf jedem Gerät anders. Auf manchen gibt er nur nah nah oder entfernt als binäre Werte zurück. Auf anderen liefert er granularere Werte. Sie können diesen Tester verwenden, um zu sehen, wie er sich auf Ihrem Gerät verhält.</string>
<string name="close">nah</string>
<string name="far">entfernt</string>
<string name="proximityText">Nähe ist zwischen \"%1$s\" und \"%2$s\"</string>
<string name="pleaseWait">Bitte warten.</string>
<string name="permissionRequiredBluetooth">Bluetooth Berechtigung ist notwendig, um diese Regel zu editieren. Beantragen Sie die Berechtigung vom Hauptbildschirm aus.</string>
<string name="settingName">Einstellungs-Name</string>
<string name="settingValue">Einstellungs-Wert</string>
<string name="enterAvalue">Geben Sie einen Wert ein.</string>
<string name="setSystemSettingCapital">Systemeinstellung setzen</string>
<string name="examplesWriteSecureSettings">Ich führe keine Liste möglicher Einstellungen. Bitte finden Sie diese Einstellungen selbst. Siehe <a href="https://developer.android.com/reference/android/provider/Settings.Secure">hier</a> für einige (unvollständige) Beispiele.</string>
<string name="httpParametersExplanation">Beginnt ein Parametername mit %1$s, während die Methode POST ist, wird er nicht wie die anderen Parameter (mit Schlüssel=Wert) übertragen, sondern als Hauptdaten übertragen. Wenn der Parameter mit 2 % endet, wird keine Codierung durchgeführt.</string>
</resources>
+43 -10
View File
@@ -32,7 +32,7 @@
<string name="thursday">Jueves</string>
<string name="friday">Viernes</string>
<string name="saturday">Sábado</string>
<string name="headphoneMicrophone">Micrófono</string>
<string name="headphoneMicrophone">con micrófono</string>
<string name="whatsThis">Qué es esto?</string>
<string name="privacyLocationingTitle">Solo usar localización privada</string>
<string name="volumeAlarms">Alarmas</string>
@@ -249,7 +249,8 @@
<string name="useAuthentication">Usar verificación de la autenticidad</string>
<string name="radiusWithUnit">Radio [m]</string>
<string name="volumes">Volumenes</string>
<string name="volumeRingtoneNotifications">Sonido polifónico ý notificaciónes</string>
<string name="volumeNotifications">notificaciónes</string>
<string name="volumeRingtone">Sonido polifónico</string>
<string name="notificationRingtone">Sonido polifónico para notificaciónes</string>
<string name="incomingCallsRingtone">Sonido de llamadas</string>
<string name="batteryLevel">Nivel de la bateria</string>
@@ -367,14 +368,14 @@
<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 (&lt; 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="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 (&lt; 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[w] - Día de la semana en forma de texto\n[F] - Mes en forma de texto\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[last_trigger_url_result] - El resultado de la última ejecución de la acción trigger url\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)\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>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlar conexiones de la app Wireguard</string>
<string name="shareConfigAndLogFilesWithDev">Adjuntar configuración y procotolo.</string>
<string name="rootExplanation">Necesita permiso root para esta función. Después encienda la función \"ejecutar regla manualmente\" para presentar el permiso superuser dialogo. Es necesario elegir \"siempre permitir root para esta app\". En caso contrario la regla no puede funcionar en segundo plano.</string>
<string name="helpTextRules">Todas las condiciones están \"Y\"-conectadas. La regla solo va a aplicarse cuando todas las condiciones se aplican. Si quiere \"O\", cree otra regla.\nLos términos desencadenante y condición se utilizan como sinónimos. Todas ellas son condiciones, pero la última en cumplir con su valor requerido podría llamarse disparador porque es la pieza final del rompecabezas para hacer que se ejecute una regla.</string>
<string name="helpTextRules">Todas las condiciones están \"Y\"-conectadas. La regla solo va a aplicarse cuando todas las condiciones se aplican. Si quiere \"O\", cree otra regla.\nLos términos desencadenante y condición se utilizan como sinónimos. Todas ellas son condiciones, pero la última en cumplir con su valor requerido podría llamarse disparador porque es la pieza final del rompecabezas para hacer que se ejecute una regla.\nSi desea guardar ciertas variables de una regla y evaluarlas en otra regla, extraiga la variable condición/actión.</string>
<string name="timeBetweenNoiseLevelMeasurementsSummary">Segundos entre dos ensayos de nivel de ruido</string>
<string name="timeBetweenNoiseLevelMeasurementsTitle">Segundos entre dos ensayos de nivel de ruido</string>
<string name="lengthOfNoiseLevelMeasurementsSummary">Duración en segundos para una prueba de nivel de ruido</string>
@@ -410,7 +411,7 @@
<string name="outgoing">saliendo</string>
<string name="noKnownWifis">No hay wifis conocidos en su dispositivo.</string>
<string name="helpTextTimeFrame">Si crea una regla con un periodo tiene dos opciones. Puede elegir entre entrar o salir de un periodo. En todo caso la regla será ejecutada solo una vez. Si crea una regla con una condición \"entrar periodo xyz\" y por ejemplo la acción \"poner el dispositivo en vibración\", el dispositivo NO va a cambiar a sonido de llamada automaticamente despues del periodo. Si desea esto tiene que crear otra regla con otro periodo.</string>
<string name="toggableRules">Reglas reversibles</string>
<string name="toggleableRules">Reglas reversibles</string>
<string name="helpTextPoi">Un sitio consiste de coordinadas GPS y un radio. Porque la localización vía red móvil terrestre es relativamente imprecisa (pero rápida y barata) no especifiqué el radio demasiado corto. La aplicación va a sugerir un radio minimo cuando cree un nuevo sitio.</string>
<string name="generalText">Para usar este programa tiene que crear reglas. Ellos tienen condiciones, por ejemplo \"está en un sitio\" o \"está en un periodo\". Despues cliquee el on/off boton en la pantalla principal.</string>
<string name="muteTextToSpeechDuringCallsSummary">Poner TextToSpeech en muto mientras dura las llamadas</string>
@@ -442,7 +443,6 @@
<string name="nfcTagFoundWithText">Tag encontrado con etiqueta:</string>
<string name="nfcUnsupportedEncoding">No hay soporte para este codigo:</string>
<string name="nfcNoNdefIntentBut">No NFC NDEF intent, pero</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC sin soporto en esta version Android, todavia no.</string>
<string name="cantRunRule">No puedo ejecutar reglas.</string>
<string name="nfcApplyTagToRule">Aplicar este tag a regla</string>
<string name="nfcTagReadSuccessfully">Tag escritoso con éxito.</string>
@@ -520,7 +520,7 @@
<string name="hint">Pista</string>
<string name="hapticFeedback">Sensación tactil (vibracion cuando toca la pantalla)</string>
<string name="helpTextSound">En la pantalla principal puede usar \"bloquear cambios de sonido\" para temporalmente evitar, basado en la norma, cambios de sonido. Por ejemplo podría estar en una situación o en un sitio donde un tono de llamada está bien, pero esta vez no es oportuno. La función se desactiva automaticamente despues del tiempo configurado. Cliquee el \"+\" boton para adicionar mas tiempo. Se puede desactivar la función antes tambien usando el boton interruptor (en consecuencia reactivar cambios de sonido, basados en normas).</string>
<string name="helpTextToggable">Las normas tienen una configuracion que se llama \\\"reversible\\\". Significa si una norma es ejecutada y despues las mismas condiciones aplican, la norma es ejecutada de forma reversible donde sea posible. Actualmente solo funciona con la condición NFC. Si toca el tag dos veces, y hay una norma reversible con este tag, la aplicación va a hacer lo contrario de la situación actual, por ejemplo desactivar wifi cuando está activo.</string>
<string name="helpTextToggleable">Las normas tienen una configuracion que se llama \\\"reversible\\\". Significa si una norma es ejecutada y despues las mismas condiciones aplican, la norma es ejecutada de forma reversible donde sea posible. Actualmente solo funciona con la condición NFC. Si toca el tag dos veces, y hay una norma reversible con este tag, la aplicación va a hacer lo contrario de la situación actual, por ejemplo desactivar wifi cuando está activo.</string>
<string name="helpTextProcessMonitoring">Si crea una norma con vigilancia del proceso, la aplicación va a revisar periodicamente si el proceso está activo. Puede ajustar la frecuencia en la configuración. Puede relentizar la reacción, pero la vigilancia permanente gasta mucha bateria. No hay un broadcast del sistema operativo para este evento.</string>
<string name="helpTextEnergySaving">Muchos fabricantes intentan conservar energia limitando las actividades de segundo plano de otras apps. Desafortunadamente el resultado es que esas aplicaciones no funcionan por completo. Automation está entre ellas. Vease <a href="https://dontkillmyapp.com/">esta pagina</a> para determinar como excluir Automation de tales medidas.</string>
<string name="speedMaximumTimeBetweenLocations">Tiempo maximo entre 2 sitios para determinar la velocidad.</string>
@@ -696,7 +696,7 @@
<string name="screenIs">pantalla esta %1$s</string>
<string name="sendEmailToDev">Enviar email al desrollador</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Debido a la infinita sabiduría de Google, la última versión de Android en la que se sabe que funciona esta función es %1$s. Puede configurarlo, pero probablemente no tendrá ningún efecto.</string>
<string name="emailContactNotice">El correo electrónico es mi método preferido de contacto para informar errores, hacer preguntas o hacer propuestas. Vaya al centro de control para obtener más información.\nMuchas preguntas no se pueden responder de inmediato, pero requieren cierta investigación técnica. Así que, por favor, tengan un poco de paciencia.</string>
<string name="contactNotice">El correo electrónico es mi método preferido de contacto para informar errores, hacer preguntas o hacer propuestas. Vaya al centro de control para obtener más información.\nMuchas preguntas no se pueden responder de inmediato, pero requieren cierta investigación técnica. Así que, por favor, tengan un poco de paciencia. \n\nAlternativamente, tiene la opción de hacer sus preguntas en el <a href="https://forum.server47.de">foro</a>.</string>
<string name="actionMediaControlNotice">Ten en cuenta que esta acción puede no funcionar con TODOS los jugadores. E incluso si lo hace, no todos los botones funcionan necesariamente.</string>
<string name="musicPlaying">Musica esta reproduciendo</string>
<string name="selectParameters">Elije parametros</string>
@@ -768,6 +768,7 @@
<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="variableCheckStringNot">Si la variable %1$s no es %2$s</string>
<string name="variableCheckStringDeleted">Si la variable %1$s no está establecida</string>
<string name="variableCheckString">Si la variable %1$s es %2$s</string>
<string name="checkVariableExplanation">Si deja el valor vacío, no se debe establecer la variable para que la condición devuelva true.</string>
@@ -800,7 +801,7 @@
<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="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>
@@ -812,7 +813,7 @@
<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="triggerUrlVariableHint">El resultado de esta solicitud se almacenará en la variable last_trigger_url_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>
@@ -853,5 +854,37 @@
<string name="notCharging">no cargando</string>
<string name="triggerChargingComment">El tipo solo se evaluará si el dispositivo se está cargando. Si se elige no cargar, se disparará en cualquier tipo de carga anterior. Si desea evaluar eso, considere la posibilidad de usar las variables trigger/action.</string>
<string name="helpTextProfiles">Un perfil es una colección de ajustes para tonos de llamada, volúmenes y otros ajustes relacionados con el audio que puede aplicar desde reglas o aplicarlo manualmente.\\n\\nTambién es posible consultar el último perfil activado como disparador. En el caso normal, solo consultará si el perfil fue el último activado (independientemente de si se han cambiado configuraciones de audio específicas mientras tanto). Pero también puede comparar los ajustes individuales.</string>
<string name="serviceWontStartPermissions">No tengo permisos completos para ninguna regla definida. El servicio no empieza.</string>
<string name="serviceWontStartNoActivatedRules">No se han definido reglas activadas. El servicio no se inicia.</string>
<string name="importChooseFolderNotice">En el siguiente diálogo, no intente seleccionar archivos específicos, sino que elija la carpeta en la que residen los archivos de copia de seguridad de Automation. Si el botón Elegir está desactivado, ha encontrado una limitación de Android. En ese caso, intente mover los archivos a un subdirectorio primero.</string>
<string name="matches">coincide</string>
<string name="doesNotMatch">no coincide</string>
<string name="logToConsole">Registrar en la consola (logcat)</string>
<string name="locationPermissionRequired">Se requiere permiso de ubicación para continuar.</string>
<string name="Android14TimePickerHint">Aparentemente, hay un error en Android 14 con respecto a un cuadro de diálogo del selector de tiempo. Si la siguiente pantalla se bloquea al intentar usar los botones arriba y abajo junto a un campo, intente ingresar números con el teclado. Nunca encontré una solución para esto y mi aplicación no es la única afectada. Parece que esto se solucionó en Android 15.</string>
<string name="screenBrightGoogleComment">Debido a que alguien en Google parece haber estado fumando algo, la configuración de brillo de la pantalla se ha comportado de manera muy extraña para algunas versiones de Android. Este comportamiento no tiene nada que ver con lo que se podría pensar que hace según su propia documentación. He intentado adaptarme a esto lo mejor que he podido, pero no espero ajustes muy precisos. Eso significa que la configuración resultante puede desviarse un poco de lo que configura aquí.</string>
<string name="version143StartOtherActivityHint">En la versión 1.8.2 fue necesario revisar la forma en que se guardaban las acciones para iniciar otros programas. No se pudo garantizar la compatibilidad. Compruebe y edite sus acciones de inicio de otras actividades para asegurarse de que siguen funcionando.</string>
<string name="disable">Desactivar</string>
<string name="enable">Activar</string>
<string name="uiThemeClassic">Tema clásico de la interfaz</string>
<string name="uiThemeCompat">Tema de la interfaz de usuario de diseño de materiales</string>
<string name="permissionForegroundServiceTypeSpecialUseRequired">Se requiere permiso FOREGROUND_SERVICE_TYPE_SPECIAL_USE para empezar.</string>
<string name="uiTheme">Tema de la interfaz</string>
<string name="uiThemeSummary">El tema de la interfaz gráfica de usuario. Se requiere solicitud.</string>
<string name="proximity">Proximidad</string>
<string name="testArea">Zona de pruebas</string>
<string name="testAreaProximityComment">Acércate a tu dispositivo para comprobar cómo reacciona.</string>
<string name="deviceDoesntHaveProximitySensor">Tu dispositivo no parece tener sensor de proximidad.</string>
<string name="proximitySensorHint">El sensor de proximidad funciona de forma diferente en cada modelo de dispositivo. En algunos solo informa valores binarios cercanos o lejanos, en otros puede mostrar valores más granulares. Puedes usar este tester para ver cómo se comporta en tu dispositivo.</string>
<string name="close">cerca</string>
<string name="far">lejos</string>
<string name="proximityText">La proximidad está entre \"%1$s\" y \"%2$s\"</string>
<string name="pleaseWait">Espera.</string>
<string name="permissionRequiredBluetooth">Se requiere permiso Bluetooth para editar esta regla. Solicita permisos desde la pantalla principal primero.</string>
<string name="settingName">Nombre de la configuratión</string>
<string name="settingValue">Valor de la configuración</string>
<string name="enterAvalue">Introduce un valor.</string>
<string name="setSystemSettingCapital">Establecer configuración del sistema</string>
<string name="examplesWriteSecureSettings">No llevo una lista de posibles configuraciones. Por favor, busca <a href="https://developer.android.com/reference/android/provider/Settings.Secure">esas</a> configuraciones por tu cuenta. Véase aquí algunos ejemplos (incompletos).</string>
<string name="httpParametersExplanation">Si el nombre de algún parámetro comienza por %1$s mientras el método es POST, no se transmitirá como los otros parámetros (con clave=valor), sino que se transferirá como datos principales. Si el parámetro termina en %2$s, no se realizará ninguna codificación.</string>
</resources>
+42 -9
View File
@@ -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 (&lt; 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 lannée, $ chiffres\n[h] - Format horaire 12heures, 2chiffres\n[H] - Format horaire 24heures, 2chiffres\n[i] - Nombre de minutes, 2chiffres\n[s] - Nombre de secondes, 2chiffres\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="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 (&lt; 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 lannée, $ chiffres\n[h] - Format horaire 12heures, 2chiffres\n[H] - Format horaire 24heures, 2chiffres\n[i] - Nombre de minutes, 2chiffres\n[s] - Nombre de secondes, 2chiffres\n[ms] - Nombre de millisecondes\n[w] - Jour de la semaine sous forme de texte\n[F] - Mois sous forme de texte\n[notificationTitle] - titre de la dernière notification\n[notificationText] - texte de la dernière notification\n[last_trigger_url_result] - Résultat de l\'exécution de la dernière action trigger url\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>
@@ -120,12 +120,12 @@
<string name="soundSettings">Réglages audio</string>
<string name="showHelp">Afficher laide</string>
<string name="rules">Règles</string>
<string name="helpTextRules">Tous les déclencheurs dune règle sont reliés par un lien logique ET, la règle ne sapplique que si tous les déclencheurs sont satisfaits. Pour un lien logique OU, créez une autre règle.\nLes termes déclencheur et condition sont utilisés comme synonymes. Toutes sont des conditions, mais la dernière à atteindre sa valeur requise pourrait être appelée déclencheur car c\'est la dernière pièce du puzzle pour provoquer l\'exécution d\'une règle.</string>
<string name="helpTextRules">Tous les déclencheurs dune règle sont reliés par un lien logique ET, la règle ne sapplique que si tous les déclencheurs sont satisfaits. Pour un lien logique OU, créez une autre règle.\nLes termes déclencheur et condition sont utilisés comme synonymes. Toutes sont des conditions, mais la dernière à atteindre sa valeur requise pourrait être appelée déclencheur car c\'est la dernière pièce du puzzle pour provoquer l\'exécution d\'une règle.\nSi vous souhaitez enregistrer certaines variables d\'une règle et les évaluer dans une autre règle, extrayez le déclencheur/l\'action de la variable.</string>
<string name="timeframes">Délais d’éxécution</string>
<string name="helpTextTimeFrame">Si vous créez une règle avec une période d’éxécution vous avez deux options. Vous pouvez choisir d’éxécuter dans la période OU hors de la période. Quel que soit votre choix laction ne sera déclenchée quune seule fois. Si vous créez une règle avec pour déclencheur \« dans la période xyz\» qui modifie votre profil audio en le passant en mode vibreur cela ne signifie pas que votre téléphone repassera automatiquement en mode sonnerie à la fin de la période. Si vous souhaitez le faire vous devez définir une autre règle avec une autre période.</string>
<string name="helpTextSound">Sur l’écran principal vous pouvez utiliser le verrouillage des modifications audio pour temporairement ne pas utiliser les règles de changement des paramètres audio. Par exemple vous pouvez êtes dans un lieu où à un moment où les sonneries peuvent être dérangeantes. Cette fonctionnalité se désactivera automatiquement une fois le temps configuré écoulé. Appuyez sur le bouton +15min pour ajouter la durée souhaitée. Une fois activé vous pouvez le désactiver en appuyant sur le bouton \« OUI\» (la règle de gestion des paramètres audio sera de nouveau active).</string>
<string name="toggableRules">Inverser la règle</string>
<string name="helpTextToggable">Les règles ont une option appelée \« Inversion\». Si une règle est exécutée et que les mêmes déclencheurs sappliquent à nouveau, la règle sera exécutée dans le sens opposé. Pour linstant, cela nest possible qu\'avec les étiquettes NFC : si vous les touchez deux fois et que loption est activée, cela fera linverse des actions demandées. Par exemple désactiver le wifi sil est actuellement actif.</string>
<string name="toggleableRules">Inverser la règle</string>
<string name="helpTextToggleable">Les règles ont une option appelée \« Inversion\». Si une règle est exécutée et que les mêmes déclencheurs sappliquent à nouveau, la règle sera exécutée dans le sens opposé. Pour linstant, cela nest possible qu\'avec les étiquettes NFC : si vous les touchez deux fois et que loption est activée, cela fera linverse des actions demandées. Par exemple désactiver le wifi sil est actuellement actif.</string>
<string name="helpTextProcessMonitoring">Si vous spécifiez une règle avec une surveillance de processus, lapplication vérifira ce processus toutes les xsecondes (vous pouvez modifier cette variable dans les réglages). Cela peut être un peu lent, mais un contrôle continu viderait la batterie trop vite, et il ny a pas de transmission de lOS pour cet événement.</string>
<string name="helpTitleEnergySaving">Économie d’énergie</string>
<string name="helpTextEnergySaving">Beaucoup de marques dappareils Android essaient d’économiser en limitant les activités des applications en arrière-plan. Malheureusement cela signifie souvent ques ces applications ne fonctionnent pas correctement, Automation en fait partie. Consultez cette <a href="https://dontkillmyapp.com/">page web</a> pour savoir comment exclure Automation de ces restrictions.</string>
@@ -305,7 +305,6 @@
<string name="nfcTagFoundWithText">Étiquette trouvée :</string>
<string name="nfcUnsupportedEncoding">Codage non pris en charge :</string>
<string name="nfcNoNdefIntentBut">Aucun NFC NDEF atteint, mais</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC non pris en charge dans cette version Android.</string>
<string name="cantRunRule">Impossible d’éxécuter les règles.</string>
<string name="nfcApplyTagToRule">Affecter l’étiquette à la règle</string>
<string name="nfcTagReadSuccessfully">Succès de lecture de l’étiquette.</string>
@@ -371,7 +370,7 @@
<string name="headsetConnected">Écouteurs (type : %1$s) est connecté</string>
<string name="headsetDisconnected">Écouteurs (type : %1$s) est déconnecté</string>
<string name="headphoneSimple">Écouteurs</string>
<string name="headphoneMicrophone">Microphone</string>
<string name="headphoneMicrophone">avec microphone</string>
<string name="headphoneAny">Tous</string>
<string name="headphoneSelectType">Choisissez le type d’écouteurs</string>
<string name="whatsThis">Quest ce que cest ?</string>
@@ -391,7 +390,8 @@
<string name="notificationRingtone">Sonnerie des notifications</string>
<string name="hapticFeedback">Vibration au toucher</string>
<string name="volumeMusicVideoGameMedia">Musiques, vidéos, jeux et autres médias</string>
<string name="volumeRingtoneNotifications">Sonnerie et notifications</string>
<string name="volumeNotifications">Notifications</string>
<string name="volumeRingtone">Sonnerie</string>
<string name="volumeAlarms">Alarmes</string>
<string name="change">Changement</string>
<string name="audibleSelection">Son de sélection (son émis lors dune sélection à l’écran)</string>
@@ -678,7 +678,7 @@
<string name="comparisonCaseInsensitive">La coparaisonn est sensible à la casse du texte</string>
<string name="profileWarning">Les paramètres que vous pouvez régler ici affectent les évènements audio sur votre télephone. Ils peuvent même annuler votre alarme de réveil. Donc, quoi que vous fassiez, il est fortement recommandé de le tester, même après les mises à jour dAndroid.</string>
<string name="ifString">si</string>
<string name="emailContactNotice">Le-mail est mon moyen de contact préféré pour signaler les bogues, poser des questions ou faire des propositions. Rendez-vous sur le centre de contrôle pour en savoir plus. Des questions multiples peuvent ne pas recevoir de réponse immédiate, mais nécessitent des recherches techniques. Veuillez donc faire preuve de patience.</string>
<string name="contactNotice">Le-mail est mon moyen de contact préféré pour signaler les bogues, poser des questions ou faire des propositions. Rendez-vous sur le centre de contrôle pour en savoir plus. Des questions multiples peuvent ne pas recevoir de réponse immédiate, mais nécessitent des recherches techniques. Veuillez donc faire preuve de patience. \n\nSinon, vous avez la possibilité de poser vos questions dans le <a href="https://forum.server47.de">forum</a>.</string>
<string name="controlCenter">Centre de contrôle</string>
<string name="sendEmailToDev">Envoyer un email au développeur</string>
<string name="screenIs">l’écran est %1$s</string>
@@ -768,6 +768,7 @@
<string name="endPhoneCall">Mettre fin à lappel téléphonique</string>
<string name="android.permission.ANSWER_PHONE_CALLS">Mettre fin à lappel téléphonique</string>
<string name="settingsReferringToRestrictedFeaturesInGoogle">Vos paramètres et/ou règles font actuellement référence à des fonctionnalités qui ne peuvent pas être fournies dans la version Google Play. Cela inclut, entre autres, tout ce qui concerne les appels téléphoniques et les messages textuels.</string>
<string name="variableCheckStringNot">si la variable %1$s n\'est pas %2$s</string>
<string name="variableCheckStringDeleted">si la variable %1$s nest pas définie</string>
<string name="variableCheckString">si la variable %1$s est %2$s</string>
<string name="checkVariableExplanation">Si vous laissez la valeur vide, la variable ne doit pas être définie pour que la condition renvoie la valeur true.</string>
@@ -812,7 +813,7 @@
<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="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>
@@ -853,5 +854,37 @@
<string name="notCharging">Ne charge pas</string>
<string name="triggerChargingComment">Le type ne sera évalué que si l\'appareil est en charge. Si l\'option Ne pas charger est sélectionnée, elle se déclenchera à n\'importe quel type de charge précédent. Si vous souhaitez évaluer cela, envisagez d\'utiliser les variables déclencheur/action.</string>
<string name="helpTextProfiles">Un profil est un ensemble de paramètres pour les sonneries, les volumes et d\'autres paramètres liés à l\'audio que vous pouvez faire appliquer à partir de règles ou appliquer manuellement.\\n\\nIl est également possible d\'interroger le dernier profil activé en tant que déclencheur. Dans le cas normal, il ne demandera que si le profil était le dernier activé (indépendamment si des paramètres audio spécifiques ont été modifiés entre-temps). Mais vous pouvez également comparer les différents paramètres.</string>
<string name="serviceWontStartPermissions">Je n\'ai pas les autorisations complètes pour une règle définie. Le service ne démarre pas.</string>
<string name="serviceWontStartNoActivatedRules">Aucune règle activée n\'a été définie. Le service ne démarre pas.</string>
<string name="version143StartOtherActivityHint">Dans la version 1.8.2, il était nécessaire de revoir la façon dont les actions pour démarrer d\'autres programmes étaient enregistrées. La compatibilité n\'a pas pu être assurée. Veuillez vérifier et modifier vos actions de démarrage d\'autres activités pour vous assurer qu\'elles fonctionnent toujours.</string>
<string name="importChooseFolderNotice">Dans la boîte de dialogue suivante, n\'essayez pas de sélectionner des fichiers spécifiques, mais choisissez le dossier dans lequel résident les fichiers de sauvegarde Automation. Si le bouton de sélection est désactivé, vous avez trouvé une limitation Android. Dans ce cas, essayez d\'abord de déplacer les fichiers dans un sous-répertoire.</string>
<string name="matches">correspond</string>
<string name="doesNotMatch">ne correspond pas</string>
<string name="logToConsole">Log vers la console (logcat)</string>
<string name="locationPermissionRequired">Une autorisation de localisation est requise pour continuer.</string>
<string name="Android14TimePickerHint">Apparemment, il y a un bogue dans Android 14 concernant une boîte de dialogue de sélection de temps. Si l\'écran suivant se bloque lorsque vous essayez d\'utiliser les boutons haut et bas en regard d\'un champ, essayez plutôt de saisir des chiffres avec le clavier. Je n\'ai jamais trouvé de solution à cela et mon application n\'est pas la seule touchée. Il semble que cela ait été corrigé dans Android 15.</string>
<string name="screenBrightGoogleComment">Parce que quelqu\'un chez Google semble avoir fumé quelque chose, le réglage de la luminosité de l\'écran se comporte très bizarrement pour certaines versions d\'Android. Ce comportement n\'a rien à voir avec ce que vous pensez qu\'il fait selon leur propre documentation. J\'ai essayé de m\'y adapter du mieux que j\'ai pu, mais je ne m\'attends pas à des réglages très précis. Cela signifie que le paramètre résultant peut s\'écarter un peu de ce que vous configurez ici.</string>
<string name="disable">Désactiver</string>
<string name="enable">Activer</string>
<string name="uiThemeClassic">Thème Classic UI</string>
<string name="uiThemeCompat">Thème de l\'interface utilisateur de conception de matériaux</string>
<string name="pleaseWait">Veuillez patienter.</string>
<string name="permissionRequiredBluetooth">Permission Bluetooth requise pour modifier cette règle. Demande d\'abord les permissions depuis l\'écran principal.</string>
<string name="settingName">Nom de l\'univers</string>
<string name="settingValue">Setting value</string>
<string name="enterAvalue">Saisissez une valeur.</string>
<string name="setSystemSettingCapital">Définir le système</string>
<string name="permissionForegroundServiceTypeSpecialUseRequired">Une autorisation FOREGROUND_SERVICE_TYPE_SPECIAL_USE est requise pour commencer.</string>
<string name="uiTheme">Thème UI</string>
<string name="uiThemeSummary">Le thème de l\'interface graphique utilisateur. Demande obligatoire.</string>
<string name="proximity">Proximité</string>
<string name="testArea">Zone d\'essai</string>
<string name="testAreaProximityComment">Approchez votre appareil pour tester sa réaction.</string>
<string name="deviceDoesntHaveProximitySensor">Votre appareil ne semble pas avoir de capteur de proximité.</string>
<string name="proximitySensorHint">Le capteur de proximité fonctionne différemment selon les modèles d\'appareils. Sur certains, il affiche simplement des valeurs binaires proches ou éloignées, sur d\'autres, il peut rapporter des valeurs plus granulaires. Vous pouvez utiliser ce testeur pour voir comment il se comporte sur votre appareil.</string>
<string name="close">proche</string>
<string name="far">loin</string>
<string name="proximityText">La proximité se situe entre \"%1$s\" et \"%2$s\"</string>
<string name="examplesWriteSecureSettings">Je ne tiens pas de liste des réglages possibles. Veuillez trouver ces réglages vous-même. Voir <a href="https://developer.android.com/reference/android/provider/Settings.Secure">ici</a> pour quelques exemples (incomplets).</string>
<string name="httpParametersExplanation">Si un nom de paramètre commence par %1$s alors que la méthode est POST, il ne sera pas transmis comme les autres paramètres (avec clé=valeur), mais transféré comme données principales. Si le paramètre se termine par %2$s, aucun codage ne sera effectué.</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More