Compare commits

...
Author SHA1 Message Date
jens 64936ce75a registerReceiver option modified 2026-08-16 18:52:18 +02:00
jens 56a766d03c registerReceiver option added 2026-08-13 18:58:55 +02:00
jens 5b86d57857 Number check fix 2026-08-09 16:12:16 +02:00
jens 4713e0d965 Changelog translations 2026-08-09 16:00:38 +02:00
jens f6876b5b1d Number check fixed 2026-08-09 15:54:16 +02:00
jens 146d36f246 Merge branch 'development-patch' into development 2026-08-09 15:04:24 +02:00
jens 2cb4a2f1d3 Deactivated unnecessary reading operations 2026-07-15 18:32:04 +02:00
jens 988b1c75a8 Added full screen intent permission 2026-06-28 17:16:04 +02:00
jens 7a9e03ed4d Removed redundant space character in notification 2026-06-11 16:51:57 +02:00
jens 4b1fd007d3 Distinction between settings 2026-06-11 16:49:04 +02:00
jens 887e6de3e4 Distinction between settings 2026-05-14 20:22:58 +02:00
jens 5417b4e739 Small bugfixes 2026-04-12 12:47:59 +02:00
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
209 changed files with 6173 additions and 3286 deletions
+15 -14
View File
@@ -3,16 +3,16 @@ plugins {
} }
android { android {
compileSdkVersion 29 compileSdkVersion 36
defaultConfig { defaultConfig {
applicationId "com.jens.automation2" applicationId "com.jens.automation2"
minSdkVersion 16 minSdkVersion 19
compileSdkVersion 33 compileSdkVersion 36
buildToolsVersion '29.0.2' buildToolsVersion '36.0.0'
useLibrary 'org.apache.http.legacy' useLibrary 'org.apache.http.legacy'
versionCode 138 versionCode 149
versionName "1.8" versionName "1.8.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -36,7 +36,7 @@ android {
{ {
dimension "version" dimension "version"
versionNameSuffix "-googlePlay" versionNameSuffix "-googlePlay"
targetSdkVersion 33 targetSdkVersion 36
} }
/* /*
@@ -63,24 +63,25 @@ android {
checkReleaseBuilds false checkReleaseBuilds false
} }
namespace 'com.jens.automation2' namespace 'com.jens.automation2'
buildToolsVersion '36.0.0'
} }
dependencies { 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.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.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 'com.linkedin.dexmaker:dexmaker:2.28.6'
implementation 'org.apache.commons:commons-lang3:3.0' implementation 'org.apache.commons:commons-lang3:3.20.0'
//implementation "androidx.security:security-crypto:1.0.0" //implementation "androidx.security:security-crypto:1.0.0"
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02" //implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1' implementation 'com.google.android.material:material:1.6.1'
testImplementation 'junit:junit:4' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
} }
+15 -19
View File
@@ -70,15 +70,18 @@
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <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_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
android:name="android.permission.WRITE_SECURE_SETTINGS" <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" />
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<!--android:maxSdkVersion="32" /> <!--android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />--> <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-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
@@ -111,20 +114,11 @@
android:name="google_analytics_ssaid_collection_enabled" android:name="google_analytics_ssaid_collection_enabled"
android:value="false" /> 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 <service
android:name=".AutomationService" android:name=".AutomationService"
android:exported="false" 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"> <receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
<intent-filter> <intent-filter>
@@ -164,6 +158,9 @@
</intent-filter> </intent-filter>
</receiver> </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=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@@ -221,7 +218,6 @@
</intent-filter> </intent-filter>
--> -->
<!-- <!--
<meta-data <meta-data
android:name="android.nfc.action.TECH_DISCOVERED" android:name="android.nfc.action.TECH_DISCOVERED"
@@ -234,15 +230,16 @@
<activity android:name=".ActivityManageActionStartActivity" /> <activity android:name=".ActivityManageActionStartActivity" />
<activity android:name=".ActivityManageTriggerNfc" /> <activity android:name=".ActivityManageTriggerNfc" />
<activity android:name=".ActivityManageActionSpeakText" /> <activity android:name=".ActivityManageActionSpeakText" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerBluetooth" /> <activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" /> <activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" /> <activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" /> <activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" /> <activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity> <activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" /> <activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" /> <activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service <service
android:name=".receivers.NotificationListener" android:name=".receivers.NotificationListener"
@@ -255,7 +252,6 @@
</service> </service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p--> <!-- 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"/> <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) protected boolean activateInternally(AutomationService automationService)
{ {
boolean isActuallyToggleable = isActuallyToggable(); boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable; boolean doToggle = ruleToggle && isActuallyToggleable;
String message; String message;
@@ -556,7 +554,8 @@ public class Rule implements Comparable<Rule>
{ {
try 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) catch(Exception e)
{ {
@@ -593,10 +592,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force) public void activate(AutomationService automationService, boolean force)
{ {
ActivateRuleTask task = new ActivateRuleTask(); ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
} }
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType) public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
+15 -18
View File
@@ -68,14 +68,18 @@
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <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_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
android:name="android.permission.WRITE_SECURE_SETTINGS" <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" />
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<!--android:maxSdkVersion="32" /> <!--android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />--> <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-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
@@ -108,20 +112,11 @@
android:name="google_analytics_ssaid_collection_enabled" android:name="google_analytics_ssaid_collection_enabled"
android:value="false" /> 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 <service
android:name=".AutomationService" android:name=".AutomationService"
android:exported="false" 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"> <receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
<intent-filter> <intent-filter>
@@ -161,6 +156,9 @@
</intent-filter> </intent-filter>
</receiver> </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=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@@ -218,7 +216,6 @@
</intent-filter> </intent-filter>
--> -->
<!-- <!--
<meta-data <meta-data
android:name="android.nfc.action.TECH_DISCOVERED" android:name="android.nfc.action.TECH_DISCOVERED"
@@ -231,15 +228,16 @@
<activity android:name=".ActivityManageActionStartActivity" /> <activity android:name=".ActivityManageActionStartActivity" />
<activity android:name=".ActivityManageTriggerNfc" /> <activity android:name=".ActivityManageTriggerNfc" />
<activity android:name=".ActivityManageActionSpeakText" /> <activity android:name=".ActivityManageActionSpeakText" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerBluetooth" /> <activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" /> <activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" /> <activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" /> <activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" /> <activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity> <activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" /> <activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" /> <activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service <service
android:name=".receivers.NotificationListener" android:name=".receivers.NotificationListener"
@@ -252,7 +250,6 @@
</service> </service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p--> <!-- 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"/> <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) protected boolean activateInternally(AutomationService automationService)
{ {
boolean isActuallyToggleable = isActuallyToggable(); boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable; boolean doToggle = ruleToggle && isActuallyToggleable;
String message; String message;
@@ -529,6 +527,7 @@ public class Rule implements Comparable<Rule>
{ {
try 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); Rule.this.getActionSet().get(i).run(automationService, doToggle);
} }
catch(Exception e) catch(Exception e)
@@ -566,10 +565,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force) public void activate(AutomationService automationService, boolean force)
{ {
ActivateRuleTask task = new ActivateRuleTask(); ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
} }
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType) public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
+20 -30
View File
@@ -66,14 +66,17 @@
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/> <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.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.hardware.sensor.proximity"/>
<uses-permission <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
android:name="android.permission.WRITE_SECURE_SETTINGS" <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" />
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--android:maxSdkVersion="32" /> <!--android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />--> <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" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -93,20 +96,15 @@
android:name="google_analytics_ssaid_collection_enabled" android:name="google_analytics_ssaid_collection_enabled"
android:value="false" /> 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 <service
android:name=".AutomationService" android:name=".AutomationService"
android:exported="false" 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" <receiver android:name=".receivers.StartupIntentReceiver"
android:enabled="true" android:enabled="true"
@@ -148,6 +146,9 @@
</intent-filter> </intent-filter>
</receiver> </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=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@@ -204,7 +205,6 @@
</intent-filter> </intent-filter>
--> -->
<!-- <!--
<meta-data <meta-data
android:name="android.nfc.action.TECH_DISCOVERED" android:name="android.nfc.action.TECH_DISCOVERED"
@@ -222,9 +222,11 @@
<activity android:name=".ActivityManageProfile" /> <activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" /> <activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" /> <activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity> <activity android:name=".ActivityPermissions" />
<activity android:name=".ActivityManageTriggerNotification" /> <activity android:name=".ActivityManageTriggerNotification" />
<activity android:name=".ActivityManageTriggerCalendar" /> <activity android:name=".ActivityManageTriggerCalendar" />
<activity android:name=".ActivityManageTriggerProximity" />
<activity android:name=".ActivityManageActionSetSystemSetting" />
<service <service
android:name=".receivers.NotificationListener" android:name=".receivers.NotificationListener"
@@ -258,18 +260,6 @@
android:exported="true" 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> </application>
</manifest> </manifest>
@@ -514,8 +514,6 @@ public class Rule implements Comparable<Rule>
protected boolean activateInternally(AutomationService automationService) protected boolean activateInternally(AutomationService automationService)
{ {
boolean isActuallyToggleable = isActuallyToggable(); boolean isActuallyToggleable = isActuallyToggable();
// boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggleable; boolean doToggle = ruleToggle && isActuallyToggleable;
String message; String message;
@@ -556,6 +554,7 @@ public class Rule implements Comparable<Rule>
{ {
try 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); Rule.this.getActionSet().get(i).run(automationService, doToggle);
} }
catch(Exception e) catch(Exception e)
@@ -593,10 +592,7 @@ public class Rule implements Comparable<Rule>
public void activate(AutomationService automationService, boolean force) public void activate(AutomationService automationService, boolean force)
{ {
ActivateRuleTask task = new ActivateRuleTask(); ActivateRuleTask task = new ActivateRuleTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, automationService, force);
else
task.execute(automationService, force);
} }
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType) public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
@@ -8,6 +8,7 @@ import android.widget.Toast;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@@ -33,13 +34,9 @@ public class Action
setWifiTethering, setWifiTethering,
setBluetoothTethering, setBluetoothTethering,
setDisplayRotation, setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl, triggerUrl,
changeSoundProfile, changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff, turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity, startOtherActivity,
waitBeforeNextAction, waitBeforeNextAction,
turnScreenOnOrOff, turnScreenOnOrOff,
@@ -60,9 +57,10 @@ public class Action
startPhoneCall, startPhoneCall,
stopPhoneCall, stopPhoneCall,
copyToClipboard, copyToClipboard,
takeScreenshot,
setLocationService, setLocationService,
sendTextMessage; sendTextMessage,
takeScreenshot,
setSystemSetting;
public String getFullName(Context context) public String getFullName(Context context)
{ {
@@ -80,14 +78,6 @@ public class Action
return context.getResources().getString(R.string.actionSetUsbTethering); return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation: case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation); 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: case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl); return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile: case changeSoundProfile:
@@ -96,14 +86,6 @@ public class Action
return context.getResources().getString(R.string.actionTurnUsbTetheringOn); return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff: case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff); 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: case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity); return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction: case waitBeforeNextAction:
@@ -150,6 +132,8 @@ public class Action
return context.getResources().getString(R.string.takeScreenshot); return context.getResources().getString(R.string.takeScreenshot);
case setLocationService: case setLocationService:
return context.getResources().getString(R.string.setLocationServiceCapital); return context.getResources().getString(R.string.setLocationServiceCapital);
case setSystemSetting:
return context.getResources().getString(R.string.setSystemSettingCapital);
default: default:
return "Unknown"; return "Unknown";
} }
@@ -493,25 +477,9 @@ public class Action
for(Action_Enum action : Action_Enum.values()) for(Action_Enum action : Action_Enum.values())
{ {
if( // exclusion for deprecated types 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("turnUsbTetheringOn")
&& &&
!action.toString().equals("turnUsbTetheringOff") !action.toString().equals("turnUsbTetheringOff")
&&
!action.toString().equals("turnWifiTetheringOn")
&&
!action.toString().equals("turnWifiTetheringOff")
&&
!action.toString().equals("enableScreenRotation")
&&
!action.toString().equals("disableScreenRotation")
) // exclusion for deprecated types ) // exclusion for deprecated types
actionTypesList.add(action.toString()); actionTypesList.add(action.toString());
} }
@@ -525,27 +493,11 @@ public class Action
for(Action_Enum action : Action_Enum.values()) for(Action_Enum action : Action_Enum.values())
{ {
if( // exclusion for deprecated types 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("turnUsbTetheringOn")
&& &&
!action.toString().equals("turnUsbTetheringOff") !action.toString().equals("turnUsbTetheringOff")
&&
!action.toString().equals("turnWifiTetheringOn")
&&
!action.toString().equals("turnWifiTetheringOff")
&&
!action.toString().equals("enableScreenRotation")
&&
!action.toString().equals("disableScreenRotation")
) // exclusion for deprecated types ) // exclusion for deprecated types
actionTypesList.add(action.getFullName(context)); actionTypesList.add(action.getFullName(context));
} }
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]); return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
@@ -572,7 +524,7 @@ public class Action
triggerUrl(context); triggerUrl(context);
break; break;
case setBluetooth: case setBluetooth:
Actions.setBluetooth(context, getParameter1(), toggleActionIfPossible); boolean result = Actions.setBluetooth(context, getParameter1(), toggleActionIfPossible);
break; break;
case setUsbTethering: case setUsbTethering:
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible); Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
@@ -687,6 +639,10 @@ public class Action
case setLocationService: case setLocationService:
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance()); Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
break; break;
case setSystemSetting:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
Actions.setSystemSetting(this.getParameter2(), AutomationService.getInstance());
break;
default: default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3); Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break; break;
@@ -734,8 +690,8 @@ public class Action
try try
{ {
url = Miscellaneous.replaceVariablesInText(url, context); url = Miscellaneous.replaceVariablesInText(url, context);
if(!StringUtils.isEmpty(params)) // if(!StringUtils.isEmpty(params))
params = Miscellaneous.replaceVariablesInText(params, context); // params = URLEncoder.encode(Miscellaneous.replaceVariablesInText(params, context), "UTF-8");
Actions myAction = new Actions(); Actions myAction = new Actions();
@@ -774,7 +730,7 @@ public class Action
if(parameters.length >= 3) if(parameters.length >= 3)
{ {
urlUsername = parameters[1]; urlUsername = parameters[1];
urlPassword = parameters[2]; urlPassword = parameters[2];
if(parameters.length >= 4) if(parameters.length >= 4)
method = parameters[3]; method = parameters[3];
@@ -783,13 +739,24 @@ public class Action
{ {
// has params // has params
String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter); String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter);
String value = "";
for(String pair : paramPairs) for(String pair : paramPairs)
{ {
String[] pieces = pair.split(Action.actionParameters2SeparatorInner); 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; 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); Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
// Either thorough checking or no encryption // 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); response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
else // else
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams); // response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
try 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.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
@@ -40,6 +41,7 @@ public class ActivityControlCenter extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_control_center); setContentView(R.layout.activity_control_center);
@@ -98,8 +100,17 @@ public class ActivityControlCenter extends Activity
@Override @Override
public void onClick(View v) public void onClick(View v)
{ {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.importChooseFolderNotice), ActivityControlCenter.this);
startActivityForResult(intent, requestCodeImport); 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); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_display_long_message); setContentView(R.layout.activity_display_long_message);
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle); tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
@@ -14,6 +14,7 @@ public class ActivityHelp extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(layout.activity_help_text); setContentView(layout.activity_help_text);
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving); TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
@@ -45,6 +45,7 @@ public class ActivityMainPoi extends ActivityGeneric
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_poi_layout); setContentView(R.layout.main_poi_layout);
instance = this; instance = this;
@@ -41,6 +41,7 @@ public class ActivityMainProfiles extends ActivityGeneric
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_profile_layout); setContentView(R.layout.main_profile_layout);
instance = this; instance = this;
@@ -49,6 +49,7 @@ public class ActivityMainRules extends ActivityGeneric
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_rule_layout); setContentView(R.layout.main_rule_layout);
instance = this; instance = this;
@@ -196,7 +197,14 @@ public class ActivityMainRules extends ActivityGeneric
{ {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithRule)); 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 @Override
public void onClick(DialogInterface dialog, int which) public void onClick(DialogInterface dialog, int which)
@@ -248,6 +256,19 @@ public class ActivityMainRules extends ActivityGeneric
deleteDialog.show(); deleteDialog.show();
break; break;
case 3: 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; ruleToEdit = ruleThisIsAbout;
if(ruleToEdit.cloneRule(ActivityMainRules.this)) if(ruleToEdit.cloneRule(ActivityMainRules.this))
{ {
@@ -11,6 +11,7 @@ import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@@ -46,7 +47,7 @@ public class ActivityMainScreen extends ActivityGeneric
ToggleButton toggleService, tbLockSound; ToggleButton toggleService, tbLockSound;
Button bShowHelp, bPrivacy, bAddSoundLockTIme, bDonate, bControlCenter; 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; ListView lvRuleHistory;
ArrayAdapter<Rule> ruleHistoryListViewAdapter; ArrayAdapter<Rule> ruleHistoryListViewAdapter;
@@ -56,6 +57,7 @@ public class ActivityMainScreen extends ActivityGeneric
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.main_overview_layout); setContentView(R.layout.main_overview_layout);
activityMainScreenInstance = this; activityMainScreenInstance = this;
@@ -83,10 +85,14 @@ public class ActivityMainScreen extends ActivityGeneric
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound); tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener); toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate); bDonate = (Button)findViewById(R.id.bDonate);
tvContactNotice = (TextView) findViewById(R.id.tvContactNotice);
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay)) if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
bDonate.setVisibility(View.VISIBLE); bDonate.setVisibility(View.VISIBLE);
// Make links clickable
tvContactNotice.setMovementMethod(LinkMovementMethod.getInstance());
toggleService.setChecked(AutomationService.isMyServiceRunning(this)); toggleService.setChecked(AutomationService.isMyServiceRunning(this));
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener() toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
{ {
@@ -122,9 +128,9 @@ public class ActivityMainScreen extends ActivityGeneric
@Override @Override
public void onClick(View v) 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); startActivity(browserIntent);
} }
}); });
@@ -533,6 +539,13 @@ public class ActivityMainScreen extends ActivityGeneric
return; 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)) if (!AutomationService.isMyServiceRunning(context))
{ {
myServiceIntent = new Intent(context, AutomationService.class); 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(); 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.noticeAndroid10WifiShown = true;
Settings.writeSettings(ActivityMainScreen.this); Settings.writeSettings(ActivityMainScreen.this);
@@ -5,6 +5,7 @@ import android.app.TabActivity;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.nfc.NfcAdapter;
import android.os.Bundle; import android.os.Bundle;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.widget.TabHost; import android.widget.TabHost;
@@ -24,6 +25,7 @@ public class ActivityMainTabLayout extends TabActivity
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Settings.readFromPersistentStorage(ActivityMainTabLayout.this); Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
if(Settings.tabsPlacement == 1) if(Settings.tabsPlacement == 1)
setContentView(R.layout.main_tab_layout_tabs_at_bottom); setContentView(R.layout.main_tab_layout_tabs_at_bottom);
@@ -60,22 +62,24 @@ public class ActivityMainTabLayout extends TabActivity
tabHost.setCurrentTab(Settings.startScreen); tabHost.setCurrentTab(Settings.startScreen);
} }
@Override @Override
protected void onResume() protected void onResume()
{ {
super.onResume(); super.onResume();
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5); // Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
NfcReceiver.checkIntentForNFC(this, getIntent()); if(!(getIntent().getAction() == null || getIntent().getAction().isEmpty()) && getIntent().getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass())); {
NfcReceiver.checkIntentForNFC(this, getIntent());
moveTaskToBack(true);
}
} }
@Override @Override
protected void onNewIntent(Intent intent) protected void onNewIntent(Intent intent)
{ {
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5); // Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5);
// setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent); NfcReceiver.checkIntentForNFC(this, intent);
} }
} }
@@ -27,6 +27,7 @@ public class ActivityManageActionBrightnessSetting extends Activity
{ {
setContentView(R.layout.activity_manage_action_brightness_settings); setContentView(R.layout.activity_manage_action_brightness_settings);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness); chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
@@ -260,6 +260,7 @@ public class ActivityManageActionCloseNotification extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_close_notification); setContentView(R.layout.activity_manage_action_close_notification);
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle); etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
@@ -20,6 +20,7 @@ public class ActivityManageActionControlMedia extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_control_media); setContentView(R.layout.activity_manage_action_control_media);
rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause); rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause);
@@ -20,6 +20,7 @@ public class ActivityManageActionCopyToClipboard extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_copy_to_clipboard); this.setContentView(R.layout.activity_manage_action_copy_to_clipboard);
bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard); bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard);
@@ -25,6 +25,7 @@ public class ActivityManageActionCreateNotification extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_create_notification); setContentView(R.layout.activity_manage_action_create_notification);
etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle); etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle);
@@ -20,6 +20,7 @@ public class ActivityManageActionLocationService extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_location_service); setContentView(R.layout.activity_manage_action_location_service);
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff); rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
@@ -22,6 +22,7 @@ public class ActivityManageActionMakePhoneCall extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_make_phone_call); setContentView(R.layout.activity_manage_action_make_phone_call);
etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber); etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber);
@@ -27,6 +27,7 @@ public class ActivityManageActionPlaySound extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_play_sound); setContentView(R.layout.activity_manage_action_play_sound);
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay); chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
@@ -29,6 +29,7 @@ public class ActivityManageActionRunExecutable extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_run_executable); setContentView(R.layout.activity_manage_action_run_executable);
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot); chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
@@ -38,6 +38,7 @@ public class ActivityManageActionSendBroadcast extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_send_broadcast); setContentView(R.layout.activity_manage_action_send_broadcast);
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend); etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
@@ -49,6 +49,7 @@ public class ActivityManageActionSendTextMessage extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_send_textmessage); this.setContentView(R.layout.activity_manage_action_send_textmessage);
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage); etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
@@ -0,0 +1,182 @@
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 spinnerSettingTarget, spinnerSettingDataType;
EditText etSettingName, etSettingValue;
Button bSaveSetSystemSetting;
TextView tvSetSystemSettingExamples, tvSetSystemSettingNoticeWriteSecureSettings;
ArrayAdapter<String> settingTargetSpinnerAdapter, settingDataTypeSpinnerAdapter;
protected final static String[] targets = { "Global", "System", "Secure" };
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);
spinnerSettingTarget = (Spinner) findViewById(R.id.spinnerSettingTarget);
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);
settingTargetSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, targets);
spinnerSettingTarget.setAdapter(settingTargetSpinnerAdapter);
settingTargetSpinnerAdapter.notifyDataSetChanged();
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);
// Make links clickable
tvSetSystemSettingNoticeWriteSecureSettings.setMovementMethod(LinkMovementMethod.getInstance());
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.isNumeric(etSettingValue.getText().toString()) || !Miscellaneous.isNumericNonDecimal(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 = targets[spinnerSettingTarget.getSelectedItemPosition()] + Action.actionParameter2Split + 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, -1);
if(components.length == 4)
{
int positionTarget = Miscellaneous.arraySearchIndexOf(targets, components[0], false, true);
int positionDataType = Miscellaneous.arraySearchIndexOf(dataTypes, components[1], false, true);
if(positionDataType >= 0)
{
spinnerSettingTarget.setSelection(positionTarget);
spinnerSettingDataType.setSelection(positionDataType);
etSettingName.setText(components[2]);
etSettingValue.setText(components[3]);
}
}
else
{
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); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_set_variable); this.setContentView(R.layout.activity_manage_action_set_variable);
etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey); etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey);
@@ -23,6 +23,7 @@ public class ActivityManageActionSpeakText extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_speak_text); this.setContentView(R.layout.activity_manage_action_speak_text);
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak); etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
@@ -32,7 +33,7 @@ public class ActivityManageActionSpeakText extends Activity
@Override @Override
public void onClick(View v) public void onClick(View v)
{ {
if(etSpeakText.getText().toString().length()>0) if(!etSpeakText.getText().toString().isEmpty())
{ {
if(resultingAction == null) if(resultingAction == null)
{ {
@@ -53,11 +53,11 @@ public class ActivityManageActionStartActivity extends Activity
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples; Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
Spinner spinnerParameterType; Spinner spinnerParameterType;
RadioGroup rgAppStartupType; RadioGroup rgAppStartupType;
boolean edit = false; // boolean edit = false;
ProgressDialog progressDialog = null; ProgressDialog progressDialog = null;
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService; 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 startByActivityString = "0";
public final static String startByBroadcastString = "1"; public final static String startByBroadcastString = "1";
public final static String startByServiceString = "2"; public final static String startByServiceString = "2";
@@ -70,6 +70,7 @@ public class ActivityManageActionStartActivity extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_start_activity); setContentView(R.layout.activity_manage_action_start_activity);
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs); lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
@@ -95,8 +96,6 @@ public class ActivityManageActionStartActivity extends Activity
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter); spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
intentTypeSpinnerAdapter.notifyDataSetChanged(); intentTypeSpinnerAdapter.notifyDataSetChanged();
etClassName.setEnabled(false);
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList); intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
bSelectApp.setOnClickListener(new OnClickListener() bSelectApp.setOnClickListener(new OnClickListener()
{ {
@@ -233,26 +232,29 @@ public class ActivityManageActionStartActivity extends Activity
String parameter2 = ""; String parameter2 = "";
if (rbStartAppSelectByActivity.isChecked()) /*
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString(); 0 = packageName
else 1 = className
{ 2 = activityName/actionName
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0) 3 = startType
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString(); 4 = parameters
else */
parameter2 += Actions.dummyPackageString + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
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()) if (rbStartAppByActivity.isChecked())
parameter2 += Action.actionParameter2Split + startByActivityString; parameter2 += startByActivityString;
else if(rbStartAppByService.isChecked()) else if(rbStartAppByService.isChecked())
parameter2 += Action.actionParameter2Split + startByServiceString; parameter2 += startByServiceString;
else if(rbStartAppByForegroundService.isChecked()) else if(rbStartAppByForegroundService.isChecked())
parameter2 += Action.actionParameter2Split + startByForegroundServiceString; parameter2 += startByForegroundServiceString;
else else
parameter2 += Action.actionParameter2Split + startByBroadcastString; parameter2 += startByBroadcastString;
for (String s : intentPairList) for (String s : intentPairList)
parameter2 += Action.actionParameter2Split + s; 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(); Intent i = getIntent();
if(i.hasExtra(ActivityManageRule.intentNameActionParameter1)) if(i.hasExtra(ActivityManageRule.intentNameActionParameter1))
loadValuesIntoGui(i); loadValuesIntoGui(i);
@@ -625,52 +610,36 @@ public class ActivityManageActionStartActivity extends Activity
rbStartAppSelectByActivity.setChecked(!selectionByAction); rbStartAppSelectByActivity.setChecked(!selectionByAction);
rbStartAppSelectByAction.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)) try
params = partsString.split(Action.actionParameter2Split); {
else String[] params;
params = partsString.split(";"); 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)); rbStartAppByActivity.setChecked(params[3].equals(startByActivityString));
rbStartAppByBroadcast.setChecked(params[3].equals(startByBroadcastString)); rbStartAppByBroadcast.setChecked(params[3].equals(startByBroadcastString));
rbStartAppByService.setChecked(params[3].equals(startByServiceString)); rbStartAppByService.setChecked(params[3].equals(startByServiceString));
rbStartAppByForegroundService.setChecked(params[3].equals(startByForegroundServiceString)); 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(); intentPairList.clear();
for(int i=startIndex; i<params.length; i++) for(int i=4; i<params.length; i++)
{ {
if(lvIntentPairs.getVisibility() != View.VISIBLE) if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE); lvIntentPairs.setVisibility(View.VISIBLE);
@@ -680,6 +649,10 @@ public class ActivityManageActionStartActivity extends Activity
updateIntentPairList(); updateIntentPairList();
} }
catch(Exception e)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.errorLoadingValues), Toast.LENGTH_LONG).show();
}
} }
private void updateIntentPairList() private void updateIntentPairList()
@@ -19,6 +19,7 @@ import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.TableLayout; import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -38,6 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
CheckBox chkTriggerUrlUseAuthentication; CheckBox chkTriggerUrlUseAuthentication;
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost; RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
TableLayout tlTriggerUrlAuthentication; TableLayout tlTriggerUrlAuthentication;
TextView tvHttpParameterExplanation;
ArrayAdapter<String> httpParametersAdapter; ArrayAdapter<String> httpParametersAdapter;
private ArrayList<String> httpParamsList = new ArrayList<>(); 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 methodGet = "GET";
public static final String methodPost = "POST"; public static final String methodPost = "POST";
// public static boolean edit = false;
// public static Action resultingAction = null;
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_action_trigger_url); this.setContentView(R.layout.activity_manage_action_trigger_url);
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl); etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
@@ -69,6 +69,7 @@ public class ActivityManageActionTriggerUrl extends Activity
etParameterName = (EditText) findViewById(R.id.etParameterName); etParameterName = (EditText) findViewById(R.id.etParameterName);
etParameterValue = (EditText)findViewById(R.id.etParameterValue); etParameterValue = (EditText)findViewById(R.id.etParameterValue);
bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam); bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam);
tvHttpParameterExplanation = (TextView)findViewById(R.id.tvHttpParameterExplanation);
etParameterName.setEnabled(false); etParameterName.setEnabled(false);
etParameterValue.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); httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList);
bSaveTriggerUrl.setOnClickListener(new OnClickListener() bSaveTriggerUrl.setOnClickListener(new OnClickListener()
@@ -2,10 +2,13 @@ package com.jens.automation2;
import android.Manifest; import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Looper;
import android.os.VibrationEffect; import android.os.VibrationEffect;
import android.os.Vibrator; import android.os.Vibrator;
import android.view.View; import android.view.View;
@@ -22,12 +25,14 @@ public class ActivityManageActionVibrate extends Activity
{ {
TextView etVibratePattern; TextView etVibratePattern;
Button bTestVibratePattern, bSaveVibratePattern; Button bTestVibratePattern, bSaveVibratePattern;
ProgressDialog pdPleaseWait = null;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) protected void onCreate(@Nullable Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_vibrate); setContentView(R.layout.activity_manage_action_vibrate);
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern); etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
@@ -59,7 +64,20 @@ public class ActivityManageActionVibrate extends Activity
if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this)) if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this))
{ {
String pattern = etVibratePattern.getText().toString(); 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; 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); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_wakelock); setContentView(R.layout.activity_manage_action_wakelock);
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate); rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
@@ -24,6 +24,7 @@ public class ActivityManageActionWifi extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_action_wifi); setContentView(R.layout.activity_manage_action_wifi);
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot); chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
@@ -35,14 +36,14 @@ public class ActivityManageActionWifi extends Activity
Intent input = getIntent(); Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameActionParameter1)) if(input.hasExtra(ActivityManageRule.intentNameActionParameter1))
{
rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true)); rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
rbActionWifiOff.setChecked(!input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
}
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2)) if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
chkWifiRunAsRoot.setChecked(Boolean.parseBoolean(input.getStringExtra(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) if(getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
tvWifiExplanation1.setVisibility(View.VISIBLE); tvWifiExplanation1.setVisibility(View.VISIBLE);
else else
@@ -1,5 +1,6 @@
package com.jens.automation2; package com.jens.automation2;
import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
@@ -7,6 +8,7 @@ import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria; import android.location.Criteria;
import android.location.Location; import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
@@ -23,6 +25,9 @@ import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.PermissionChecker;
import com.jens.automation2.receivers.ConnectivityReceiver; import com.jens.automation2.receivers.ConnectivityReceiver;
import java.util.Calendar; import java.util.Calendar;
@@ -40,6 +45,7 @@ public class ActivityManagePoi extends Activity
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius; EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
Calendar locationSearchStart = null; Calendar locationSearchStart = null;
Timer timer = null; Timer timer = null;
int requestCodeGetLocationPermission = 1293;
final static int defaultRadius = 250; final static int defaultRadius = 250;
final static int searchTimeout = 120; final static int searchTimeout = 120;
@@ -60,6 +66,7 @@ public class ActivityManagePoi extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_specific_poi); this.setContentView(R.layout.activity_manage_specific_poi);
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
@@ -77,7 +84,15 @@ public class ActivityManagePoi extends Activity
public void onClick(View v) public void onClick(View v)
{ {
hideKeyboard(); 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();
} }
}); });
@@ -112,6 +127,19 @@ public class ActivityManagePoi extends Activity
// new Poi to be created // 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() private void createPoi()
{ {
myLocationManager.removeUpdates(myLocationListenerGps); myLocationManager.removeUpdates(myLocationListenerGps);
@@ -314,20 +342,20 @@ public class ActivityManagePoi extends Activity
public void onClick(DialogInterface dialog, int which) public void onClick(DialogInterface dialog, int which)
{ {
progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true); progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
if(Build.VERSION.SDK_INT >= 31) // if(Build.VERSION.SDK_INT >= 31)
{ // {
AlertDialog dia = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.locationNotWorkingOn12), ActivityManagePoi.this); // AlertDialog dia = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.locationNotWorkingOn12), ActivityManagePoi.this);
dia.setOnDismissListener(new DialogInterface.OnDismissListener() // dia.setOnDismissListener(new DialogInterface.OnDismissListener()
{ // {
@Override // @Override
public void onDismiss(DialogInterface dialogInterface) // public void onDismiss(DialogInterface dialogInterface)
{ // {
getLocation(); // getLocation();
} // }
}); // });
dia.show(); // dia.show();
} // }
else // else
getLocation(); getLocation();
} }
}; };
@@ -1,7 +1,6 @@
package com.jens.automation2; package com.jens.automation2;
import android.app.Activity; import android.app.Activity;
import android.app.NotificationManager;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
@@ -28,8 +27,6 @@ import android.widget.Toast;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import java.io.File;
public class ActivityManageProfile extends Activity public class ActivityManageProfile extends Activity
{ {
private static ProgressDialog progressDialog; private static ProgressDialog progressDialog;
@@ -37,12 +34,13 @@ public class ActivityManageProfile extends Activity
final static int intentCodeRingtonePickerCallsRingtone = 9011; final static int intentCodeRingtonePickerCallsRingtone = 9011;
final static int intentCodeRingtonePickerNotificationsFile = 9020; final static int intentCodeRingtonePickerNotificationsFile = 9020;
final static int intentCodeRingtonePickerNotificationsRingtone = 9021; 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; Spinner spinnerSoundMode, spinnerDndMode;
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms; SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms, seekBarVolumeRingtones;
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile; Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
TextView tvIncomingCallsRingtone, tvNotificationsRingtone; TextView tvIncomingCallsRingtone, tvNotificationsRingtone, tvRingtoneVolume, tvNotificationsVolume;
EditText etName; EditText etName;
boolean guiUpdate = false; boolean guiUpdate = false;
@@ -87,12 +85,14 @@ public class ActivityManageProfile extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
this.setContentView(R.layout.activity_manage_specific_profile); this.setContentView(R.layout.activity_manage_specific_profile);
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode); checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
checkBoxChangeDnd = (CheckBox)findViewById(R.id.checkBoxChangeDnd); checkBoxChangeDnd = (CheckBox)findViewById(R.id.checkBoxChangeDnd);
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia); checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications); checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications);
checkBoxChangeVolumeRingtone = (CheckBox)findViewById(R.id.checkBoxChangeVolumeRingtones);
checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms); checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms);
checkBoxChangeIncomingCallsRingtone = (CheckBox)findViewById(R.id.checkBoxChangeIncomingCallsRingtone); checkBoxChangeIncomingCallsRingtone = (CheckBox)findViewById(R.id.checkBoxChangeIncomingCallsRingtone);
checkBoxChangeNotificationRingtone = (CheckBox)findViewById(R.id.checkBoxChangeNotificationRingtone); checkBoxChangeNotificationRingtone = (CheckBox)findViewById(R.id.checkBoxChangeNotificationRingtone);
@@ -108,11 +108,14 @@ public class ActivityManageProfile extends Activity
spinnerDndMode = (Spinner)findViewById(R.id.spinnerDndMode); spinnerDndMode = (Spinner)findViewById(R.id.spinnerDndMode);
seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic); seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic);
seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications); seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications);
seekBarVolumeRingtones = (SeekBar)findViewById(R.id.seekBarVolumeRingtones);
seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms); seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms);
bChangeSoundIncomingCalls = (Button)findViewById(R.id.bChangeSoundIncomingCalls); bChangeSoundIncomingCalls = (Button)findViewById(R.id.bChangeSoundIncomingCalls);
bChangeSoundNotifications = (Button)findViewById(R.id.bChangeSoundNotifications); bChangeSoundNotifications = (Button)findViewById(R.id.bChangeSoundNotifications);
tvIncomingCallsRingtone = (TextView)findViewById(R.id.tvIncomingCallsRingtone); tvIncomingCallsRingtone = (TextView)findViewById(R.id.tvIncomingCallsRingtone);
tvNotificationsRingtone = (TextView)findViewById(R.id.tvNotificationsRingtone); tvNotificationsRingtone = (TextView)findViewById(R.id.tvNotificationsRingtone);
tvRingtoneVolume = (TextView)findViewById(R.id.tvRingtoneVolume);
tvNotificationsVolume = (TextView)findViewById(R.id.tvNotificationsVolume);
bSaveProfile = (Button)findViewById(R.id.bSaveProfile); bSaveProfile = (Button)findViewById(R.id.bSaveProfile);
etName = (EditText)findViewById(R.id.etName); etName = (EditText)findViewById(R.id.etName);
@@ -124,6 +127,7 @@ public class ActivityManageProfile extends Activity
spinnerDndMode.setEnabled(false); spinnerDndMode.setEnabled(false);
seekBarVolumeMusic.setEnabled(false); seekBarVolumeMusic.setEnabled(false);
seekBarVolumeNotifications.setEnabled(false); seekBarVolumeNotifications.setEnabled(false);
seekBarVolumeRingtones.setEnabled(false);
seekBarVolumeAlarms.setEnabled(false); seekBarVolumeAlarms.setEnabled(false);
bChangeSoundIncomingCalls.setEnabled(false); bChangeSoundIncomingCalls.setEnabled(false);
bChangeSoundNotifications.setEnabled(false); bChangeSoundNotifications.setEnabled(false);
@@ -138,10 +142,35 @@ public class ActivityManageProfile extends Activity
spinnerDndMode.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 // Scale SeekBars to the system's maximum volume values
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE); AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
seekBarVolumeMusic.setMax(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)); seekBarVolumeMusic.setMax(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION)); seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
seekBarVolumeRingtones.setMax(am.getStreamMaxVolume(AudioManager.STREAM_RING));
seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM)); seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM));
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[] 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); seekBarVolumeNotifications.setEnabled(isChecked);
} }
}); });
checkBoxChangeVolumeRingtone.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
seekBarVolumeRingtones.setEnabled(isChecked);
}
});
checkBoxChangeVolumeAlarms.setOnCheckedChangeListener(new OnCheckedChangeListener() checkBoxChangeVolumeAlarms.setOnCheckedChangeListener(new OnCheckedChangeListener()
{ {
@Override @Override
@@ -336,7 +373,7 @@ public class ActivityManageProfile extends Activity
}); });
if(ActivityMainProfiles.profileToEdit != null) if(ActivityMainProfiles.profileToEdit != null)
editProfile(ActivityMainProfiles.profileToEdit); loadValuesIntoGui(ActivityMainProfiles.profileToEdit);
//else //else
// new Profile to be created // 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; guiUpdate = true;
@@ -378,6 +415,7 @@ public class ActivityManageProfile extends Activity
checkBoxChangeDnd.setChecked(ActivityMainProfiles.profileToEdit.getChangeDndMode()); checkBoxChangeDnd.setChecked(ActivityMainProfiles.profileToEdit.getChangeDndMode());
checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia()); checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia());
checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications()); checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications());
checkBoxChangeVolumeRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeRingtones());
checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms()); checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms());
checkBoxChangeIncomingCallsRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeIncomingCallsRingtone()); checkBoxChangeIncomingCallsRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeIncomingCallsRingtone());
checkBoxChangeNotificationRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeNotificationRingtone()); checkBoxChangeNotificationRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeNotificationRingtone());
@@ -390,6 +428,7 @@ public class ActivityManageProfile extends Activity
spinnerDndMode.setSelection(ActivityMainProfiles.profileToEdit.getDndMode()-1); spinnerDndMode.setSelection(ActivityMainProfiles.profileToEdit.getDndMode()-1);
seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic()); seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic());
seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications()); seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications());
seekBarVolumeRingtones.setProgress(ActivityMainProfiles.profileToEdit.getVolumeRingtones());
seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms()); seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms());
checkBoxAudibleSelection.setChecked(ActivityMainProfiles.profileToEdit.audibleSelection); checkBoxAudibleSelection.setChecked(ActivityMainProfiles.profileToEdit.audibleSelection);
checkBoxScreenLockUnlockSound.setChecked(ActivityMainProfiles.profileToEdit.screenLockUnlockSound); checkBoxScreenLockUnlockSound.setChecked(ActivityMainProfiles.profileToEdit.screenLockUnlockSound);
@@ -414,6 +453,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setChangeDndMode(checkBoxChangeDnd.isChecked()); ActivityMainProfiles.profileToEdit.setChangeDndMode(checkBoxChangeDnd.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked()); ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked()); ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeRingtones(checkBoxChangeVolumeRingtone.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked()); ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked());
ActivityMainProfiles.profileToEdit.setChangeIncomingCallsRingtone(checkBoxChangeIncomingCallsRingtone.isChecked()); ActivityMainProfiles.profileToEdit.setChangeIncomingCallsRingtone(checkBoxChangeIncomingCallsRingtone.isChecked());
ActivityMainProfiles.profileToEdit.setChangeNotificationRingtone(checkBoxChangeNotificationRingtone.isChecked()); ActivityMainProfiles.profileToEdit.setChangeNotificationRingtone(checkBoxChangeNotificationRingtone.isChecked());
@@ -430,6 +470,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setDndMode(spinnerDndMode.getSelectedItemPosition()+1); ActivityMainProfiles.profileToEdit.setDndMode(spinnerDndMode.getSelectedItemPosition()+1);
ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress()); ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress()); ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeRingtones(seekBarVolumeRingtones.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress()); ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress());
ActivityMainProfiles.profileToEdit.setIncomingCallsRingtone(incomingCallsRingtone); ActivityMainProfiles.profileToEdit.setIncomingCallsRingtone(incomingCallsRingtone);
ActivityMainProfiles.profileToEdit.setNotificationRingtone(notificationsRingtone); ActivityMainProfiles.profileToEdit.setNotificationRingtone(notificationsRingtone);
@@ -147,6 +147,10 @@ public class ActivityManageRule extends Activity
final static int requestCodeTriggerCalendarEventEdit = 834; final static int requestCodeTriggerCalendarEventEdit = 834;
final static int requestCodeTriggerChargingAdd = 835; final static int requestCodeTriggerChargingAdd = 835;
final static int requestCodeTriggerChargingEdit = 836; 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() public static ActivityManageRule getInstance()
{ {
@@ -161,6 +165,7 @@ public class ActivityManageRule extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_specific_rule); setContentView(R.layout.activity_manage_specific_rule);
context = this; context = this;
@@ -363,6 +368,12 @@ public class ActivityManageRule extends Activity
chargingStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2()); chargingStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(chargingStateEditor, requestCodeTriggerChargingEdit); startActivityForResult(chargingStateEditor, requestCodeTriggerChargingEdit);
break; 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: default:
break; break;
} }
@@ -501,6 +512,12 @@ public class ActivityManageRule extends Activity
actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2()); actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit); startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit);
break; 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: default:
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4); Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
break; break;
@@ -541,7 +558,7 @@ public class ActivityManageRule extends Activity
public void onClick(View v) public void onClick(View v)
{ {
// Open help popup // 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)); items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Trigger_Enum.phoneCall.toString())) 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)); items.add(new Item(typesLong[i].toString(), R.drawable.phone));
} }
else if(types[i].toString().equals(Trigger_Enum.nfcTag.toString())) 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())) else if(types[i].toString().equals(Trigger_Enum.checkVariable.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.variable)); items.add(new Item(typesLong[i].toString(), R.drawable.variable));
else if(types[i].toString().equals(Trigger_Enum.calendarEvent.toString())) 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 else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
} }
@@ -722,6 +742,13 @@ public class ActivityManageRule extends Activity
startActivityForResult(triggerChargingIntent, requestCodeTriggerChargingAdd); startActivityForResult(triggerChargingIntent, requestCodeTriggerChargingAdd);
return; 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) else if(triggerType == Trigger_Enum.musicPlaying)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection) else if(triggerType == Trigger_Enum.usb_host_connection)
@@ -1483,19 +1510,43 @@ public class ActivityManageRule extends Activity
this.refreshTriggerList(); 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) else if(requestCode == requestCodeTriggerChargingEdit)
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
Trigger responseTimeFrame = new Trigger(); Trigger chargingStateTrigger = new Trigger();
responseTimeFrame.setTriggerType(Trigger_Enum.charging); chargingStateTrigger.setTriggerType(Trigger_Enum.charging);
responseTimeFrame.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true)); chargingStateTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
responseTimeFrame.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2)); chargingStateTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
responseTimeFrame.setParentRule(ruleToEdit); chargingStateTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, responseTimeFrame); ruleToEdit.getTriggerSet().set(editIndex, chargingStateTrigger);
this.refreshTriggerList(); 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) else if(requestCode == requestCodeActionStartActivityAdd)
{ {
// manage start of other activity // manage start of other activity
@@ -2174,6 +2225,32 @@ public class ActivityManageRule extends Activity
this.refreshActionList(); 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() protected AlertDialog getActionTypeDialog()
@@ -2235,27 +2312,33 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.script)); items.add(new Item(typesLong[i].toString(), R.drawable.script));
else if(types[i].toString().equals(Action_Enum.startPhoneCall.toString())) 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)); items.add(new Item(typesLong[i].toString(), R.drawable.phone));
} }
else if(types[i].toString().equals(Action_Enum.stopPhoneCall.toString())) 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)); items.add(new Item(typesLong[i].toString(), R.drawable.phone));
} }
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString())) 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)); items.add(new Item(typesLong[i].toString(), R.drawable.message));
} }
else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString())) else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.clipboard)); 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())) else if(types[i].toString().equals(Action_Enum.setVariable.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.variable)); items.add(new Item(typesLong[i].toString(), R.drawable.variable));
else if(types[i].toString().equals(Action_Enum.setLocationService.toString())) else if(types[i].toString().equals(Action_Enum.setLocationService.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.compass_small)); 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 else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
} }
@@ -2288,28 +2371,28 @@ public class ActivityManageRule extends Activity
{ {
newAction = new Action(); 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; //launch other activity to enter a url and parameters;
newAction.setAction(Action_Enum.triggerUrl); newAction.setAction(Action_Enum.triggerUrl);
// ActivityManageActionTriggerUrl.resultingAction = null;
Intent editTriggerIntent = new Intent(context, ActivityManageActionTriggerUrl.class); Intent editTriggerIntent = new Intent(context, ActivityManageActionTriggerUrl.class);
startActivityForResult(editTriggerIntent, requestCodeActionTriggerUrlAdd); 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); newAction.setAction(Action_Enum.setWifi);
Intent editSetWifiIntent = new Intent(context, ActivityManageActionWifi.class); Intent editSetWifiIntent = new Intent(context, ActivityManageActionWifi.class);
startActivityForResult(editSetWifiIntent, requestCodeActionSetWifiAdd); 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)) if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();; Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
newAction.setAction(Action_Enum.setBluetooth); newAction.setAction(Action_Enum.setBluetooth);
getActionParameter1Dialog(ActivityManageRule.this).show(); 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); newAction.setAction(Action_Enum.setUsbTethering);
getActionParameter1Dialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
@@ -2317,12 +2400,12 @@ public class ActivityManageRule extends Activity
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) 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(); 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); newAction.setAction(Action_Enum.setWifiTethering);
getActionParameter1Dialog(ActivityManageRule.this).show(); 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); newAction.setAction(Action_Enum.setBluetoothTethering);
getActionParameter1Dialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
@@ -2333,12 +2416,12 @@ public class ActivityManageRule extends Activity
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O) 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(); 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); newAction.setAction(Action_Enum.setDisplayRotation);
getActionParameter1Dialog(ActivityManageRule.this).show(); 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) if(Profile.getProfileCollection().size() > 0)
{ {
@@ -2348,23 +2431,23 @@ public class ActivityManageRule extends Activity
else else
Toast.makeText(context, getResources().getString(R.string.noProfilesCreateOneFirst), Toast.LENGTH_LONG).show(); 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); newAction.setAction(Action_Enum.startOtherActivity);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
startActivityForResult(intent, requestCodeActionStartActivityAdd); 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); newAction.setAction(Action_Enum.waitBeforeNextAction);
getActionWaitBeforeNextActionDialog(ActivityManageRule.this).show(); 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); newAction.setAction(Action_Enum.turnScreenOnOrOff);
getActionParameter1Dialog(ActivityManageRule.this).show(); 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); newAction.setAction(Action_Enum.setAirplaneMode);
getActionParameter1Dialog(ActivityManageRule.this).show(); 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(); 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); newAction.setAction(Action_Enum.setDataConnection);
getActionParameter1Dialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
Miscellaneous.messageBox(getResources().getString(R.string.actionDataConnection), getResources().getString(R.string.rootExplanation), 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; //launch other activity to enter a url and parameters;
newAction.setAction(Action_Enum.speakText); newAction.setAction(Action_Enum.speakText);
@@ -2387,9 +2470,9 @@ public class ActivityManageRule extends Activity
Intent editTriggerIntent = new Intent(context, ActivityManageActionSpeakText.class); Intent editTriggerIntent = new Intent(context, ActivityManageActionSpeakText.class);
startActivityForResult(editTriggerIntent, requestCodeActionSpeakTextAdd); 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; //launch other activity to enter parameters;
newAction.setAction(Action_Enum.sendTextMessage); newAction.setAction(Action_Enum.sendTextMessage);
@@ -2398,102 +2481,108 @@ public class ActivityManageRule extends Activity
startActivityForResult(editTriggerIntent, requestCodeActionSendTextMessageAdd); 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); newAction.setAction(Action_Enum.playMusic);
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
refreshActionList(); 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); newAction.setAction(Action_Enum.vibrate);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
startActivityForResult(intent, requestCodeActionVibrateAdd); 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); newAction.setAction(Action_Enum.sendBroadcast);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
startActivityForResult(intent, requestCodeActionSendBroadcastAdd); 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); newAction.setAction(Action_Enum.runExecutable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
startActivityForResult(intent, requestCodeActionRunExecutableAdd); 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); newAction.setAction(Action_Enum.startPhoneCall);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionMakePhoneCall.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionMakePhoneCall.class);
startActivityForResult(intent, requestCodeActionMakePhoneCallAdd); 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); newAction.setAction(Action_Enum.setVariable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSetVariable.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSetVariable.class);
startActivityForResult(intent, requestCodeActionSetVariableAdd); 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); newAction.setAction(Action_Enum.stopPhoneCall);
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
refreshActionList(); 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); newAction.setAction(Action_Enum.wakelock);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
startActivityForResult(intent, requestCodeActionWakeLockAdd); 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); newAction.setAction(Action_Enum.controlMediaPlayback);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionControlMedia.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionControlMedia.class);
startActivityForResult(intent, requestCodeActionControlMediaAdd); 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); newAction.setAction(Action_Enum.createNotification);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCreateNotification.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCreateNotification.class);
startActivityForResult(intent, requestCodeActionCreateNotificationAdd); 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); newAction.setAction(Action_Enum.closeNotification);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCloseNotification.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCloseNotification.class);
startActivityForResult(intent, requestCodeActionCloseNotificationAdd); 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); newAction.setAction(Action_Enum.setScreenBrightness);
Intent actionScreenBrightnessIntent = new Intent(context, ActivityManageActionBrightnessSetting.class); Intent actionScreenBrightnessIntent = new Intent(context, ActivityManageActionBrightnessSetting.class);
startActivityForResult(actionScreenBrightnessIntent, requestCodeActionScreenBrightnessAdd); 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); newAction.setAction(Action_Enum.playSound);
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class); Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundAdd); 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); newAction.setAction(Action_Enum.copyToClipboard);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd); 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); newAction.setAction(Action_Enum.takeScreenshot);
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
refreshActionList(); 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); newAction.setAction(Action_Enum.setLocationService);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class); Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class);
startActivityForResult(intent, requestCodeActionSetLocationServiceAdd); 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; package com.jens.automation2;
import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@@ -16,23 +18,27 @@ import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import com.jens.automation2.receivers.BluetoothReceiver; import com.jens.automation2.receivers.BluetoothReceiver;
public class ActivityManageTriggerBluetooth extends Activity public class ActivityManageTriggerBluetooth extends Activity
{ {
final static int requestPermissionCodeBluetoothConnect = 4711;
protected static Trigger editedBluetoothTrigger; protected static Trigger editedBluetoothTrigger;
RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange; RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange;
Button bSaveBluetoothTrigger; Button bSaveBluetoothTrigger;
Spinner spinnerBluetoothDevices; Spinner spinnerBluetoothDevices;
TextView tvBluetoothNotPresentNotice; TextView tvBluetoothNotPresentNotice;
ArrayAdapter<String> bluetoothDevicesSpinnerAdapter; ArrayAdapter<String> bluetoothDevicesSpinnerAdapter = null;
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_bluetooth); setContentView(R.layout.activity_manage_trigger_bluetooth);
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice); radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
@@ -46,8 +52,6 @@ public class ActivityManageTriggerBluetooth extends Activity
spinnerBluetoothDevices = (Spinner)findViewById(R.id.spinnerBluetoothDevices); spinnerBluetoothDevices = (Spinner)findViewById(R.id.spinnerBluetoothDevices);
tvBluetoothNotPresentNotice = (TextView)findViewById(R.id.tvBluetoothNotPresentNotice); 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)) if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
tvBluetoothNotPresentNotice.setVisibility(View.VISIBLE); tvBluetoothNotPresentNotice.setVisibility(View.VISIBLE);
else else
@@ -75,16 +79,36 @@ public class ActivityManageTriggerBluetooth extends Activity
} }
}); });
refreshBluetoothDeviceSpinner(); if(Miscellaneous.getTargetSDK(ActivityManageTriggerBluetooth.this) >= 31 && !ActivityPermissions.havePermission(Manifest.permission.BLUETOOTH_CONNECT, ActivityManageTriggerBluetooth.this))
spinnerBluetoothDevices.setEnabled(false); requestPermissions(new String[] {Manifest.permission.BLUETOOTH_CONNECT }, requestPermissionCodeBluetoothConnect);
else
refreshBluetoothDeviceSpinner();
spinnerBluetoothDevices.setEnabled(false);
if(editedBluetoothTrigger.getBluetoothDeviceAddress() != null && editedBluetoothTrigger.getBluetoothDeviceAddress().length() > 0) if(editedBluetoothTrigger.getBluetoothDeviceAddress() != null && editedBluetoothTrigger.getBluetoothDeviceAddress().length() > 0)
loadVariableIntoGui(); 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); 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) if(spinnerBluetoothDevices.getAdapter() == null)
{ {
spinnerBluetoothDevices.setAdapter(bluetoothDevicesSpinnerAdapter); spinnerBluetoothDevices.setAdapter(bluetoothDevicesSpinnerAdapter);
@@ -29,6 +29,7 @@ public class ActivityManageTriggerBroadcast extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_broadcasts); setContentView(R.layout.activity_manage_trigger_broadcasts);
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions); bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
@@ -51,6 +51,7 @@ public class ActivityManageTriggerCalendar extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_calendar); setContentView(R.layout.activity_manage_trigger_calendar);
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive); chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
@@ -10,12 +10,7 @@ import android.widget.RadioButton;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.jens.automation2.ActivityManageRule; import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.R;
import com.jens.automation2.Trigger;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerCharging extends Activity public class ActivityManageTriggerCharging extends Activity
{ {
@@ -27,6 +22,7 @@ public class ActivityManageTriggerCharging extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_charging); setContentView(R.layout.activity_manage_trigger_charging);
rbChargingOn = (RadioButton) findViewById(R.id.rbChargingOn); rbChargingOn = (RadioButton) findViewById(R.id.rbChargingOn);
@@ -69,13 +65,13 @@ public class ActivityManageTriggerCharging extends Activity
String param2 = ""; String param2 = "";
if(rbChargingTypeAny.isChecked()) if(rbChargingTypeAny.isChecked())
param2 = "0"; param2 = String.valueOf(BatteryReceiver.batteryChargingTypeAny);
else if(rbChargingTypeAc.isChecked()) else if(rbChargingTypeAc.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_AC); param2 = String.valueOf(BatteryReceiver.batteryChargingTypeAc);
else if(rbChargingTypeUsb.isChecked()) else if(rbChargingTypeUsb.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_USB); param2 = String.valueOf(BatteryReceiver.batteryChargingTypeUsb);
else if(rbChargingTypeWireless.isChecked()) else if(rbChargingTypeWireless.isChecked())
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_WIRELESS); param2 = String.valueOf(BatteryReceiver.batteryChargingTypeWireless);
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, param2); response.putExtra(ActivityManageRule.intentNameTriggerParameter2, param2);
@@ -5,6 +5,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -14,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerCheckVariable extends Activity public class ActivityManageTriggerCheckVariable extends Activity
{ {
EditText etVariableKeyTrigger, etVariableValueTrigger; EditText etVariableKeyTrigger, etVariableValueTrigger;
CheckBox chkTriggerVariableDirection;
Button bTriggerVariableSave; Button bTriggerVariableSave;
@Override @Override
@@ -21,13 +24,19 @@ public class ActivityManageTriggerCheckVariable extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_check_variable); setContentView(R.layout.activity_manage_trigger_check_variable);
etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger); etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger);
etVariableValueTrigger = (EditText) findViewById(R.id.etVariableValueTrigger); etVariableValueTrigger = (EditText) findViewById(R.id.etVariableValueTrigger);
chkTriggerVariableDirection = (CheckBox)findViewById(R.id.chkTriggerVariableDirection);
bTriggerVariableSave = (Button) findViewById(R.id.bTriggerVariableSave); bTriggerVariableSave = (Button) findViewById(R.id.bTriggerVariableSave);
Intent input = getIntent(); Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
chkTriggerVariableDirection.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2)) if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{ {
String[] conditions = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split); String[] conditions = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
@@ -36,13 +45,26 @@ public class ActivityManageTriggerCheckVariable extends Activity
etVariableValueTrigger.setText(conditions[1]); 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() bTriggerVariableSave.setOnClickListener(new View.OnClickListener()
{ {
@Override @Override
public void onClick(View view) public void onClick(View view)
{ {
Intent response = new Intent(); Intent response = new Intent();
// response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbTetheringOn.isChecked());
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkTriggerVariableDirection.isChecked());
if(StringUtils.isEmpty(etVariableValueTrigger.getText().toString())) if(StringUtils.isEmpty(etVariableValueTrigger.getText().toString()))
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, etVariableKeyTrigger.getText().toString()); response.putExtra(ActivityManageRule.intentNameTriggerParameter2, etVariableKeyTrigger.getText().toString());
@@ -105,6 +105,7 @@ public class ActivityManageTriggerDeviceOrientation extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_device_orientation); setContentView(R.layout.activity_manage_trigger_device_orientation);
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth); currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
@@ -40,6 +40,7 @@ public class ActivityManageTriggerNfc extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_nfc); setContentView(R.layout.activity_manage_trigger_nfc);
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue); etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
@@ -150,7 +151,12 @@ public class ActivityManageTriggerNfc extends Activity
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass()); final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 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]; IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{}; String[][] techList = new String[][]{};
@@ -185,7 +191,7 @@ public class ActivityManageTriggerNfc extends Activity
@Override @Override
protected void onPause() protected void onPause()
{ {
/** /*
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well. * Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/ */
disableForegroundDispatch(this); disableForegroundDispatch(this);
@@ -197,7 +203,7 @@ public class ActivityManageTriggerNfc extends Activity
protected void onResume() protected void onResume()
{ {
super.onResume(); super.onResume();
/** /*
* It's important, that the activity is in the foreground (resumed). Otherwise * It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown. * an IllegalStateException is thrown.
*/ */
@@ -232,9 +238,17 @@ public class ActivityManageTriggerNfc extends Activity
{ {
generatedId = NfcReceiver.readTag(discoveredTag); generatedId = NfcReceiver.readTag(discoveredTag);
if(generatedId != null && generatedId.length() > 0) if(generatedId != null && generatedId.length() > 0)
tvCurrentNfcId.setText(generatedId); {
tvCurrentNfcId.setText(generatedId);
bReadNfcTag.setEnabled(true);
bUseValueCurrentlyStored.setEnabled(true);
}
else 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) else if(currentStatus == 1)
{ {
@@ -259,6 +259,7 @@ public class ActivityManageTriggerNotification extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_notification); setContentView(R.layout.activity_manage_trigger_notification);
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle); etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
@@ -36,6 +36,7 @@ public class ActivityManageTriggerPhoneCall extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_phone_call); setContentView(R.layout.activity_manage_trigger_phone_call);
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber); etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
@@ -32,6 +32,7 @@ public class ActivityManageTriggerProfile extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_profile); setContentView(R.layout.activity_manage_trigger_profile);
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile); 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); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_subsystemstate); setContentView(R.layout.activity_manage_trigger_subsystemstate);
rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi); rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi);
@@ -27,6 +27,7 @@ public class ActivityManageTriggerTethering extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_tethering); setContentView(R.layout.activity_manage_trigger_tethering);
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn); rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@@ -36,8 +37,18 @@ public class ActivityManageTriggerTimeFrame extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); 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); 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); startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop); stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
startPicker.setIs24HourView(true); startPicker.setIs24HourView(true);
@@ -15,7 +15,6 @@ import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@@ -54,6 +53,7 @@ public class ActivityManageTriggerWifi extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_manage_trigger_wifi); setContentView(R.layout.activity_manage_trigger_wifi);
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected); rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
@@ -74,7 +74,7 @@ public class ActivityManageTriggerWifi extends Activity
if( if(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29 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); tvWifiTriggerNameLocationNotice.setVisibility(View.VISIBLE);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import android.Manifest; import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
@@ -11,6 +12,8 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
@@ -25,9 +28,9 @@ import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; 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.ArrayList;
import java.util.Arrays; 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 permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
public final static String permissionNameGoogleActivityDetection = "com.google.android.gms.permission.ACTIVITY_RECOGNITION"; 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 permissionNameSuperuser = "android.permission.ACCESS_SUPERUSER";
public final static String permissionNameProximity = "android.hardware.sensor.proximity";
public static ActivityPermissions getInstance() public static ActivityPermissions getInstance()
{ {
@@ -84,6 +88,7 @@ public class ActivityPermissions extends Activity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.permissions_activity); setContentView(R.layout.permissions_activity);
bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions); bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions);
@@ -276,6 +281,19 @@ public class ActivityPermissions extends Activity
return false; 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) public static boolean havePermission(String s, Context context)
{ {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
@@ -314,9 +332,20 @@ public class ActivityPermissions extends Activity
{ {
return haveAccessibilityAccess(Miscellaneous.getAnyContext()); 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 else
{ {
int res = context.checkCallingOrSelfPermission(s); // int res = context.checkCallingOrSelfPermission(s);
int res = ContextCompat.checkSelfPermission(context, s);
return (res == PackageManager.PERMISSION_GRANTED); 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)) if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions); 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_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions); addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
if(Build.VERSION.SDK_INT >= 31)
addToArrayListUnique(Manifest.permission.BLUETOOTH_CONNECT, requiredPermissions);
break; break;
case charging: case charging:
// addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions); // addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
@@ -565,7 +601,10 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions); addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
break; break;
case timeFrame: 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); addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
break; break;
case usb_host_connection: case usb_host_connection:
@@ -579,7 +618,7 @@ public class ActivityPermissions extends Activity
( (
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29 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 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) if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions); addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
break; break;
// Proximity permission cannot be requested, but is always granted.
case proximity:
// addToArrayListUnique(ActivityPermissions.permissionNameProximity, requiredPermissions);
break;
default: default:
break; break;
} }
@@ -611,12 +654,6 @@ public class ActivityPermissions extends Activity
if(targetProfile.changeIncomingCallsRingtone || targetProfile.changeNotificationRingtone) if(targetProfile.changeIncomingCallsRingtone || targetProfile.changeNotificationRingtone)
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions); addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
break; break;
case disableScreenRotation:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case enableScreenRotation:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case playMusic: case playMusic:
break; break;
case controlMediaPlayback: case controlMediaPlayback:
@@ -640,6 +677,8 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions); addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
if(Build.VERSION.SDK_INT >= 31)
addToArrayListUnique(Manifest.permission.BLUETOOTH_CONNECT, requiredPermissions);
break; break;
case setDataConnection: case setDataConnection:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
@@ -695,15 +734,18 @@ public class ActivityPermissions extends Activity
action.getParameter2().contains(Actions.wireguard_tunnel_refresh) action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
) )
addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions); addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions);
// if(
// action.getParameter2().contains("eu.faircode.netguard.START_PORT_FORWARD") if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34)
// || {
// action.getParameter2().contains("eu.faircode.netguard.STOP_PORT_FORWARD") if(action.getParameter2().contains(Actions.alarm_set))
// ) {
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions); addToArrayListUnique(Manifest.permission.SET_ALARM, requiredPermissions);
addToArrayListUnique(Manifest.permission.USE_FULL_SCREEN_INTENT, requiredPermissions);
}
}
if(Build.VERSION.SDK_INT >= 29) if(Build.VERSION.SDK_INT >= 29)
{ {
String parts[]; String[] parts;
if(action.getParameter2().contains(Action.actionParameter2Split)) if(action.getParameter2().contains(Action.actionParameter2Split))
parts = action.getParameter2().split(Action.actionParameter2Split); parts = action.getParameter2().split(Action.actionParameter2Split);
else else
@@ -711,7 +753,15 @@ public class ActivityPermissions extends Activity
// Permission only required for starts of activity, not broadcasts or services // 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); addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
} }
break; break;
@@ -719,40 +769,12 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions); addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions); getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions);
break; 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: case turnUsbTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break; break;
case turnUsbTetheringOn: case turnUsbTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break; 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: case waitBeforeNextAction:
break; break;
case playSound: case playSound:
@@ -778,7 +800,22 @@ public class ActivityPermissions extends Activity
addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions); addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions);
break; break;
case setLocationService: case setLocationService:
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions); case setSystemSetting:
String[] parts = action.getParameter2().split(Action.actionParameter2Split, -1);
if(parts.length < 4)
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
else
{
if(parts[0].equals(ActivityManageActionSetSystemSetting.targets[0]))
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
else if(parts[0].equals(ActivityManageActionSetSystemSetting.targets[1]))
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
else if(parts[0].equals(ActivityManageActionSetSystemSetting.targets[2]))
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
}
break;
case setScreenBrightness:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break; break;
default: default:
break; break;
@@ -789,7 +826,7 @@ public class ActivityPermissions extends Activity
return requiredPermissions; return requiredPermissions;
} }
protected ArrayList<String> getRulesUsing(Trigger.Trigger_Enum triggerType) protected ArrayList<String> getRulesAsStringUsing(Trigger.Trigger_Enum triggerType)
{ {
ArrayList<String> returnList = new ArrayList<>(); ArrayList<String> returnList = new ArrayList<>();
@@ -808,7 +845,7 @@ public class ActivityPermissions extends Activity
return returnList; return returnList;
} }
protected ArrayList<String> getRulesUsing(Action.Action_Enum actionType) protected ArrayList<String> getRulesAsStringUsing(Action.Action_Enum actionType)
{ {
ArrayList<String> returnList = new ArrayList<>(); ArrayList<String> returnList = new ArrayList<>();
@@ -827,6 +864,44 @@ public class ActivityPermissions extends Activity
return returnList; return returnList;
} }
protected ArrayList<Rule> getRulesUsing(Trigger.Trigger_Enum triggerType)
{
ArrayList<Rule> returnList = new ArrayList<>();
for (Rule rule : Rule.getRuleCollection())
{
if (rule.isRuleActive())
{
for (Trigger trigger : rule.getTriggerSet())
{
if(trigger.getTriggerType().equals(triggerType))
returnList.add(rule);
}
}
}
return returnList;
}
protected ArrayList<Rule> getRulesUsing(Action.Action_Enum actionType)
{
ArrayList<Rule> returnList = new ArrayList<>();
for (Rule rule : Rule.getRuleCollection())
{
if (rule.isRuleActive())
{
for (Action action : rule.getActionSet())
{
if(action.getAction().equals(actionType))
returnList.add(rule);
}
}
}
return returnList;
}
public ArrayList<String> getReasonForPermission(String permission) public ArrayList<String> getReasonForPermission(String permission)
{ {
ArrayList<String> usingElements = new ArrayList<String>(); ArrayList<String> usingElements = new ArrayList<String>();
@@ -843,163 +918,139 @@ public class ActivityPermissions extends Activity
usingElements.add(getResources().getString(R.string.storeSettings)); usingElements.add(getResources().getString(R.string.storeSettings));
break; break;
case Manifest.permission.SCHEDULE_EXACT_ALARM: case Manifest.permission.SCHEDULE_EXACT_ALARM:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.timeFrame)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.timeFrame))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.calendarEvent))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE: case Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.notification)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.notification))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.closeNotification)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.closeNotification))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case permissionNameGoogleActivityDetection: case permissionNameGoogleActivityDetection:
case Manifest.permission.ACTIVITY_RECOGNITION: case Manifest.permission.ACTIVITY_RECOGNITION:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.activityDetection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ACCESS_COARSE_LOCATION: case Manifest.permission.ACCESS_COARSE_LOCATION:
case Manifest.permission.ACCESS_FINE_LOCATION: case Manifest.permission.ACCESS_FINE_LOCATION:
usingElements.add(getResources().getString(R.string.manageLocations)); usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ACCESS_BACKGROUND_LOCATION: case Manifest.permission.ACCESS_BACKGROUND_LOCATION:
usingElements.add(getResources().getString(R.string.googleLocationChicanery)); usingElements.add(getResources().getString(R.string.googleLocationChicanery));
usingElements.add(getResources().getString(R.string.wifiMonitoringAlsoRequiresThis)); usingElements.add(getResources().getString(R.string.wifiMonitoringAlsoRequiresThis));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ACCESS_NETWORK_STATE: case Manifest.permission.ACCESS_NETWORK_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.airplaneMode)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.airplaneMode))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.roaming)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.roaming))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.wifiConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setAirplaneMode)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setAirplaneMode))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setBluetooth))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setDataConnection)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setDataConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setWifi)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setWifi))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setWifiTethering)) for(String ruleName : getRulesAsStringUsing(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)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ACCESS_WIFI_STATE: case Manifest.permission.ACCESS_WIFI_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.wifiConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.BLUETOOTH_ADMIN: 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:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection)) case Manifest.permission.BLUETOOTH_CONNECT:
for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth)) for(String ruleName : getRulesAsStringUsing(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)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.GET_TASKS: case Manifest.permission.GET_TASKS:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.process_started_stopped)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.process_started_stopped))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.INTERNET: case Manifest.permission.INTERNET:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.triggerUrl)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.triggerUrl))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.NFC: case Manifest.permission.NFC:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.nfcTag)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.nfcTag))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.PROCESS_OUTGOING_CALLS: case Manifest.permission.PROCESS_OUTGOING_CALLS:
case Manifest.permission.READ_CALL_LOG: case Manifest.permission.READ_CALL_LOG:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.phoneCall)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.phoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.READ_PHONE_STATE: case Manifest.permission.READ_PHONE_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.batteryLevel)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.batteryLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.charging)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.charging))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.headsetPlugged)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.headsetPlugged))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.phoneCall)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.phoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.usb_host_connection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.RECORD_AUDIO: case Manifest.permission.RECORD_AUDIO:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.noiseLevel)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.noiseLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.SEND_SMS: case Manifest.permission.SEND_SMS:
for(String ruleName : getRulesUsing(Action.Action_Enum.sendTextMessage)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.sendTextMessage))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.CALL_PHONE: case Manifest.permission.CALL_PHONE:
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.startPhoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.SYSTEM_ALERT_WINDOW: case Manifest.permission.SYSTEM_ALERT_WINDOW:
for(String ruleName : getRulesUsing(Action.Action_Enum.startOtherActivity)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.startOtherActivity))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.startPhoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ANSWER_PHONE_CALLS: case Manifest.permission.ANSWER_PHONE_CALLS:
for(String ruleName : getRulesUsing(Action.Action_Enum.stopPhoneCall)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.stopPhoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.FOREGROUND_SERVICE: case Manifest.permission.FOREGROUND_SERVICE:
usingElements.add(getResources().getString(R.string.startAutomationAsService)); usingElements.add(getResources().getString(R.string.startAutomationAsService));
break; break;
case Manifest.permission.READ_EXTERNAL_STORAGE: case Manifest.permission.READ_EXTERNAL_STORAGE:
for(String ruleName : getRulesUsing(Action.Action_Enum.playSound)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.playSound))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.changeSoundProfile)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.changeSoundProfile))
{ {
Rule tempRule = Rule.getByName(ruleName); Rule tempRule = Rule.getByName(ruleName);
if(tempRule != null) if(tempRule != null)
@@ -1026,7 +1077,7 @@ public class ActivityPermissions extends Activity
break; break;
case Manifest.permission.BIND_DEVICE_ADMIN: case Manifest.permission.BIND_DEVICE_ADMIN:
for(String ruleName : getRulesUsing(Action.Action_Enum.turnScreenOnOrOff)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.turnScreenOnOrOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: case Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS:
@@ -1036,17 +1087,58 @@ public class ActivityPermissions extends Activity
usingElements.add(getResources().getString(R.string.queryAllPackages)); usingElements.add(getResources().getString(R.string.queryAllPackages));
break; break;
case Manifest.permission.BIND_ACCESSIBILITY_SERVICE: case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
for(String ruleName : getRulesUsing(Action.Action_Enum.takeScreenshot)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.takeScreenshot))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.WRITE_SECURE_SETTINGS: case Manifest.permission.WRITE_SECURE_SETTINGS:
for(String ruleName : getRulesUsing(Action.Action_Enum.setLocationService)) for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setLocationService))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesAsStringUsing(Action.Action_Enum.setSystemSetting))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.READ_CALENDAR: case Manifest.permission.READ_CALENDAR:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent)) for(String ruleName : getRulesAsStringUsing(Trigger.Trigger_Enum.calendarEvent))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; 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;
case Manifest.permission.SET_ALARM:
if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34)
{
outerLoop:
for (Rule rule : getRulesUsing(Action.Action_Enum.startOtherActivity))
{
for(Action action : rule.getActionSet())
{
if(action.getParameter2().contains(Actions.alarm_set))
{
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), rule.getName()));
continue outerLoop;
}
}
}
}
break;
case Manifest.permission.USE_FULL_SCREEN_INTENT:
if(Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 34)
{
outerLoop:
for (Rule rule : getRulesUsing(Action.Action_Enum.startOtherActivity))
{
for(Action action : rule.getActionSet())
{
if(action.getParameter2().contains(Actions.alarm_set))
{
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), rule.getName()));
continue outerLoop;
}
}
}
}
break;
} }
return usingElements; return usingElements;
@@ -1064,7 +1156,7 @@ public class ActivityPermissions extends Activity
required permissions have been granted. required permissions have been granted.
*/ */
super.onActivityResult(requestCode, resultCode, data); // super.onActivityResult(requestCode, resultCode, data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{ {
@@ -1127,16 +1219,16 @@ public class ActivityPermissions extends Activity
ArrayList<String> permissionList = new ArrayList<String>(); ArrayList<String> permissionList = new ArrayList<String>();
for(String permission : permissionNames) 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); 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); permissionList.add(permission);
} }
@@ -1305,7 +1397,7 @@ public class ActivityPermissions extends Activity
{ {
if(requiredPermissions.contains(Manifest.permission.PROCESS_OUTGOING_CALLS)) 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()) Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
) )
@@ -1316,7 +1408,7 @@ public class ActivityPermissions extends Activity
} }
if(requiredPermissions.contains(Manifest.permission.SEND_SMS)) 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); requiredPermissions.remove(Manifest.permission.SEND_SMS);
@@ -1686,12 +1778,53 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK); 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(); PackageManager pm = context.getPackageManager();
try try
{ {
PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS); PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] requestedPermissions = null; String[] requestedPermissions = null;
if (packageInfo != null) if (packageInfo != null)
{ {
@@ -17,6 +17,13 @@ public class ActivitySettings extends PreferenceActivity
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); 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); addPreferencesFromResource(layout.activity_settings);
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk)) if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
@@ -31,6 +31,7 @@ public class ActivityVolumeTest extends Activity
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
Miscellaneous.setUiTheme(this);
setContentView(R.layout.activity_volume_calibration); setContentView(R.layout.activity_volume_calibration);
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume); tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
@@ -1,5 +1,7 @@
package com.jens.automation2; package com.jens.automation2;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ActivityManager; import android.app.ActivityManager;
@@ -12,6 +14,7 @@ import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Binder; import android.os.Binder;
import android.os.Build; import android.os.Build;
@@ -156,6 +159,15 @@ public class AutomationService extends Service implements OnInitListener
ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE); ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE);
return false; 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 ( if (
@@ -168,6 +180,17 @@ public class AutomationService extends Service implements OnInitListener
Rule.getRuleCollection().size() == 0 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) if (startAtBoot)
{ {
/* /*
@@ -243,7 +266,7 @@ public class AutomationService extends Service implements OnInitListener
updateNotification(); updateNotification();
if (isMainActivityRunning(this)) if(isMainActivityRunning(this))
ActivityMainScreen.updateMainScreen(); ActivityMainScreen.updateMainScreen();
this.isRunning = true; this.isRunning = true;
@@ -254,7 +277,7 @@ public class AutomationService extends Service implements OnInitListener
/* /*
On normal phones the app is supposed to automatically restart in case of any problems. On normal phones the app is supposed to automatically restart in case of any problems.
In the emulator we want it to stop to be able to better pinpoint the root cause. In the emulator we want it to stop to be able to better pinpoint the root cause of sudden stops.
*/ */
if(Miscellaneous.isAndroidEmulator()) if(Miscellaneous.isAndroidEmulator())
return START_NOT_STICKY; return START_NOT_STICKY;
@@ -320,8 +343,10 @@ public class AutomationService extends Service implements OnInitListener
ReceiverCoordinator.applySettingsAndRules(); ReceiverCoordinator.applySettingsAndRules();
DateTimeListener.reloadAlarms(); DateTimeListener.setOrResetAlarms();
CalendarReceiver.armOrRearmTimer();
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 @Override
@@ -390,6 +415,20 @@ public class AutomationService extends Service implements OnInitListener
r.activate(AutomationService.this, false); 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.serviceStartDone = true;
Settings.deviceStartDone = true; Settings.deviceStartDone = true;
} }
@@ -476,7 +515,12 @@ public class AutomationService extends Service implements OnInitListener
if(Miscellaneous.googleToBlameForLocation(true)) if(Miscellaneous.googleToBlameForLocation(true))
{ {
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class); 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); 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); Intent myServiceIntent = new Intent(context, AutomationService.class);
myServiceIntent.putExtra("startAtBoot", startAtBoot); myServiceIntent.putExtra("startAtBoot", startAtBoot);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(myServiceIntent); context.startForegroundService(myServiceIntent);
else else
@@ -528,42 +573,6 @@ public class AutomationService extends Service implements OnInitListener
Settings.serviceStartDone = false; 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() protected static NotificationCompat.Builder createServiceNotificationBuilder()
{ {
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
@@ -612,6 +621,9 @@ public class AutomationService extends Service implements OnInitListener
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void updateNotification() public static void updateNotification()
{ {
if(!Settings.showIconWhenServiceIsRunning && Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return;
AutomationService instance = getInstance(); AutomationService instance = getInstance();
if(instance != null) if(instance != null)
@@ -660,7 +672,11 @@ public class AutomationService extends Service implements OnInitListener
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a."; lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
} }
String textToDisplay = bodyText + " " + lastRuleString; String textToDisplay;
if(bodyText.length() > 0)
textToDisplay = bodyText + " " + lastRuleString;
else
textToDisplay = lastRuleString;
if(notificationBuilder == null) if(notificationBuilder == null)
notificationBuilder = createServiceNotificationBuilder(); notificationBuilder = createServiceNotificationBuilder();
@@ -677,7 +693,10 @@ public class AutomationService extends Service implements OnInitListener
myNotification.flags |= Notification.FLAG_NO_CLEAR; myNotification.flags |= Notification.FLAG_NO_CLEAR;
// notificationManager.notify(notificationId, myNotification); // 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,9 +92,11 @@ import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@@ -126,10 +128,36 @@ import eu.chainfire.libsuperuser.Shell;
public class Miscellaneous extends Service public class Miscellaneous extends Service
{ {
protected static String writeableFolderStringCache = null; 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 Context startupContext;
public static final String lineSeparator = System.getProperty("line.separator"); 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) public static String downloadURL(String url, String username, String password, String method, Map<String, String> httpParams)
{ {
HttpClient httpclient = new DefaultHttpClient(); HttpClient httpclient = new DefaultHttpClient();
@@ -144,9 +172,21 @@ public class Miscellaneous extends Service
HttpURLConnection connection; HttpURLConnection connection;
if(url.toLowerCase().contains("https")) 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 else
connection = (HttpURLConnection) urlObject.openConnection(); connection = (HttpURLConnection) urlObject.openConnection();
@@ -161,9 +201,10 @@ public class Miscellaneous extends Service
else if(method.equals(ActivityManageActionTriggerUrl.methodPost)) else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
if(httpParams.size() > 0) if(httpParams.size() > 0)
{ {
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoInput(true); connection.setDoInput(true);
connection.setDoOutput(true); connection.setDoOutput(true);
@@ -173,8 +214,8 @@ public class Miscellaneous extends Service
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key))); paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
OutputStream os = connection.getOutputStream(); OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, httpEncoding));
writer.write(getQuery(paramPairs)); writer.write(getQuery(paramPairs, method));
writer.flush(); writer.flush();
writer.close(); writer.close();
} }
@@ -198,27 +239,58 @@ public class Miscellaneous extends Service
// immediate deallocation of all system resources // immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown(); httpclient.getConnectionManager().shutdown();
if(errorFound) if(errorFound)
return "httpError"; return http_error_string;
else else
return responseBody.toString(); 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(); StringBuilder result = new StringBuilder();
boolean first = true; boolean first = true;
for (NameValuePair pair : params) for (NameValuePair pair : params)
{ {
if (first) if (method.equals(ActivityManageActionTriggerUrl.methodGet))
first = false; {
else if (first)
result.append("&"); 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("=");
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(); return result.toString();
@@ -273,8 +345,8 @@ public class Miscellaneous extends Service
} }
catch(Exception e) catch(Exception e)
{ {
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3); Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
return "httpError"; return http_error_string;
} }
// finally // finally
// { // {
@@ -313,14 +385,17 @@ public class Miscellaneous extends Service
header = "Automation"; header = "Automation";
} }
if(type.equals("e")) if(Settings.logToConsole)
Log.e(header, description); {
if (type.equals("e"))
Log.e(header, description);
if(type.equals("w")) if (type.equals("w"))
Log.w(header, description); Log.w(header, description);
if(type.equals("i")) if (type.equals("i"))
Log.i(header, description); Log.i(header, description);
}
if(Settings.writeLogFile && Settings.logLevel >= logLevel) if(Settings.writeLogFile && Settings.logLevel >= logLevel)
{ {
@@ -585,7 +660,45 @@ public class Miscellaneous extends Service
Miscellaneous.logEvent("i", "TimeCompare", "Default return code. Shouldn't be here.", 5); Miscellaneous.logEvent("i", "TimeCompare", "Default return code. Shouldn't be here.", 5);
return 0; 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) public static String convertStreamToString(InputStream is)
@@ -679,7 +792,9 @@ public class Miscellaneous extends Service
source.contains("[H]") || source.contains("[H]") ||
source.contains("[i]") || source.contains("[i]") ||
source.contains("[s]") || source.contains("[s]") ||
source.contains("[ms]") source.contains("[ms]") ||
source.contains("[w]") ||
source.contains("[F]")
) )
{ {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
@@ -747,6 +862,24 @@ public class Miscellaneous extends Service
{ {
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND))); 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]")) if(source.contains("[notificationTitle]"))
@@ -756,7 +889,7 @@ public class Miscellaneous extends Service
String notificationTitle = NotificationListener.getLastNotification().getTitle(); String notificationTitle = NotificationListener.getLastNotification().getTitle();
if (notificationTitle != null && notificationTitle.length() > 0) if (notificationTitle != null && notificationTitle.length() > 0)
source = source.replace("[notificationTitle]", escapeStringForUrl(notificationTitle)); source = source.replace("[notificationTitle]", notificationTitle);
else else
{ {
source = source.replace("[notificationTitle]", "notificationTitle unknown"); source = source.replace("[notificationTitle]", "notificationTitle unknown");
@@ -777,7 +910,8 @@ public class Miscellaneous extends Service
String notificationText = NotificationListener.getLastNotification().getText(); String notificationText = NotificationListener.getLastNotification().getText();
if (notificationText != null && notificationText.length() > 0) if (notificationText != null && notificationText.length() > 0)
source = source.replace("[notificationText]", escapeStringForUrl(notificationText)); //source = source.replace("[notificationText]", escapeStringForUrl(notificationText));
source = source.replace("[notificationText]", notificationText);
else else
{ {
source = source.replace("[notificationText]", "notificationText unknown"); source = source.replace("[notificationText]", "notificationText unknown");
@@ -791,15 +925,15 @@ public class Miscellaneous extends Service
} }
} }
if(source.contains("[last_trigger_url_result]")) if(source.contains("[" + last_trigger_url_result_string + "]"))
{ {
try 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) 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);
} }
} }
@@ -981,28 +1115,34 @@ public class Miscellaneous extends Service
} }
} }
// executes a command on the system // executes a command on the system
private static boolean canExecuteCommand(String command) private static boolean canExecuteCommand(String command)
{ {
boolean executedSuccesfully; boolean executedSuccesfully;
try try
{ {
Runtime.getRuntime().exec(command); Runtime.getRuntime().exec(command);
executedSuccesfully = true; executedSuccesfully = true;
} }
catch (Exception e) catch (Exception e)
{ {
executedSuccesfully = false; executedSuccesfully = false;
} }
return executedSuccesfully;
}
public static char getDecimalSeparator()
{
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault());
return symbols.getDecimalSeparator(); // ',' or '.'
}
return executedSuccesfully;
}
public static boolean isNumericDecimal(String strNum) public static boolean isNumericDecimal(String strNum)
{ {
if (strNum == null) if (strNum == null)
{
return false; return false;
}
try try
{ {
double d = Double.parseDouble(strNum); double d = Double.parseDouble(strNum);
@@ -1014,6 +1154,26 @@ public class Miscellaneous extends Service
return true; return true;
} }
public static boolean isNumericNonDecimal(String number)
{
if (number == null)
return false;
try
{
int temp = Integer.parseInt(number);
}
catch (Exception e)
{
return false;
}
if(number.contains(String.valueOf(getDecimalSeparator())))
return false;
else
return true;
}
public static boolean isNumeric(String str) public static boolean isNumeric(String str)
{ {
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal. return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
@@ -1281,7 +1441,8 @@ public class Miscellaneous extends Service
builder.setOnlyAlertOnce(true); builder.setOnlyAlertOnce(true);
if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE)) //if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
if(notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
{ {
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay)) if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
builder.setSmallIcon(R.drawable.crane); builder.setSmallIcon(R.drawable.crane);
@@ -2014,6 +2175,50 @@ public class Miscellaneous extends Service
return formattedDate; 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) public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
{ {
if(matchFullLine) if(matchFullLine)
@@ -2133,6 +2338,22 @@ public class Miscellaneous extends Service
return context.getApplicationContext().getApplicationInfo().targetSdkVersion; 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) public static void setDisplayLanguage(Context context)
{ {
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage)) if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
@@ -38,6 +38,9 @@ public class Profile implements Comparable<Profile>
protected boolean changeVolumeNotifications; protected boolean changeVolumeNotifications;
protected int volumeNotifications; protected int volumeNotifications;
protected boolean changeVolumeRingtones;
protected int volumeRingtones;
protected boolean changeVolumeAlarms; protected boolean changeVolumeAlarms;
protected int volumeAlarms; protected int volumeAlarms;
@@ -145,6 +148,26 @@ public class Profile implements Comparable<Profile>
return volumeNotifications; 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) public void setChangeVolumeAlarms(boolean changeVolumeAlarms)
{ {
this.changeVolumeAlarms = changeVolumeAlarms; this.changeVolumeAlarms = changeVolumeAlarms;
@@ -520,52 +543,92 @@ public class Profile implements Comparable<Profile>
{ {
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE); AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
if(changeSoundMode) if(changeSoundMode)
Actions.setSound(context, soundMode); {
Miscellaneous.logEvent("i", "Profile", "Setting sound mode to " + String.valueOf(soundMode), 4);
Actions.setSound(context, soundMode);
}
if(changeDndMode) if(changeDndMode)
Actions.setDoNotDisturb(context, dndMode); {
Miscellaneous.logEvent("i", "Profile", "Setting DND mode to " + String.valueOf(dndMode), 4);
Actions.setDoNotDisturb(context, dndMode);
}
if(changeVolumeMusicVideoGameMedia) 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) 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) 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(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(changeVibrateWhenRinging)
{ {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 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); android.provider.Settings.System.putInt(context.getContentResolver(), "vibrate_when_ringing", vibrateWhenRinging?1:0);
} }
else else
{ {
Miscellaneous.logEvent("i", "Profile", "Setting vibrate when ringing to " + String.valueOf(vibrateWhenRinging), 4);
if (vibrateWhenRinging) if (vibrateWhenRinging)
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON); am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
else else
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF); am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
} }
} }
if(changeNotificationRingtone) 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) 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); android.provider.Settings.System.putInt(context.getContentResolver(), "lockscreen_sounds_enabled" , screenLockUnlockSound ? 1 : 0);
} }
if(changeAudibleSelection) 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 android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED, 1); // enable
else else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED, 0); // dissable 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(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 android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED, 1); // enable
else else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED, 0); // disable 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 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); List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.profileActive);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
@@ -637,6 +703,15 @@ public class Profile implements Comparable<Profile>
return false; return false;
} }
if(Build.VERSION.SDK_INT >= 34)
{
if (changeVolumeRingtones)
{
if (am.getStreamVolume(AudioManager.STREAM_RING) != volumeRingtones)
return false;
}
}
if (changeVolumeAlarms) if (changeVolumeAlarms)
{ {
if (am.getStreamVolume(AudioManager.STREAM_ALARM) != volumeAlarms) if (am.getStreamVolume(AudioManager.STREAM_ALARM) != volumeAlarms)
@@ -1,5 +1,6 @@
package com.jens.automation2; package com.jens.automation2;
import android.Manifest;
import android.os.Build; import android.os.Build;
import android.util.Log; 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.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener; import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener; import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ProximityReceiver;
import com.jens.automation2.receivers.ScreenStateReceiver; import com.jens.automation2.receivers.ScreenStateReceiver;
import com.jens.automation2.receivers.SubSystemStateReceiver; import com.jens.automation2.receivers.SubSystemStateReceiver;
import com.jens.automation2.receivers.TetheringReceiver; import com.jens.automation2.receivers.TetheringReceiver;
@@ -212,8 +214,11 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState)) if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance()); 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()); CalendarReceiver.startCalendarReceiver(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.proximity))
ProximityReceiver.startProximityReceiver(AutomationService.getInstance());
} }
public static void stopAllReceivers() public static void stopAllReceivers()
@@ -233,6 +238,7 @@ public class ReceiverCoordinator
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance()); DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance()); TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
SubSystemStateReceiver.getInstance().stopListener(AutomationService.getInstance()); SubSystemStateReceiver.getInstance().stopListener(AutomationService.getInstance());
ProximityReceiver.stopProximityReceiver();
try 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()) if(!CalendarReceiver.getInstance().isListenerRunning())
CalendarReceiver.getInstance().startListener(AutomationService.getInstance()); CalendarReceiver.getInstance().startListener(AutomationService.getInstance());
@@ -19,8 +19,9 @@ public class Settings implements SharedPreferences
public static final String folderName = "Automation"; public static final String folderName = "Automation";
public static final String zipFileName = "automation.zip"; public static final String zipFileName = "automation.zip";
public static final String constNewsOptInDone ="newsOptInDone"; public static final String constNewsOptInDone = "newsOptInDone";
public static final String constNotificationChannelCleanupApk118 ="notificationChannelCleanupApk118"; public static final String constNotificationChannelCleanupApk118 = "notificationChannelCleanupApk118";
public static final String constVersion143StartOtherProgramConfigEditHint = "constVersion143StartOtherProgramConfigEditHint";
public static long minimumDistanceChangeForGpsUpdate; public static long minimumDistanceChangeForGpsUpdate;
public static long minimumDistanceChangeForNetworkUpdate; public static long minimumDistanceChangeForNetworkUpdate;
@@ -29,6 +30,7 @@ public class Settings implements SharedPreferences
public static int gpsTimeout; public static int gpsTimeout;
public static long minimumTimeBetweenUpdate; public static long minimumTimeBetweenUpdate;
public static boolean startServiceAtSystemBoot; public static boolean startServiceAtSystemBoot;
public static boolean logToConsole;
public static boolean writeLogFile; public static boolean writeLogFile;
public static long logLevel; public static long logLevel;
public static int logFileMaxSize; public static int logFileMaxSize;
@@ -61,6 +63,7 @@ public class Settings implements SharedPreferences
public static int activityDetectionFrequency; public static int activityDetectionFrequency;
public static int activityDetectionRequiredProbability; public static int activityDetectionRequiredProbability;
public static boolean privacyLocationing; public static boolean privacyLocationing;
public static int uiTheme;
public static int startScreen; public static int startScreen;
public static int tabsPlacement; public static int tabsPlacement;
public static boolean executeRulesAndProfilesWithSingleClick; public static boolean executeRulesAndProfilesWithSingleClick;
@@ -97,6 +100,7 @@ public class Settings implements SharedPreferences
public static final int default_gpsTimeout = 300; // seconds public static final int default_gpsTimeout = 300; // seconds
public static final long default_minimumTimeBetweenUpdate = 30000; // in Milliseconds public static final long default_minimumTimeBetweenUpdate = 30000; // in Milliseconds
public static final boolean default_startServiceAtSystemBoot = false; public static final boolean default_startServiceAtSystemBoot = false;
public static final boolean default_logToConsole = false;
public static final boolean default_writeLogFile = false; public static final boolean default_writeLogFile = false;
public static final long default_logLevel = 2; public static final long default_logLevel = 2;
public static final int default_logFileMaxSize = 10; 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_activityDetectionFrequency = 60;
public static final int default_activityDetectionRequiredProbability = 75; public static final int default_activityDetectionRequiredProbability = 75;
public static final boolean default_privacyLocationing = false; 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_startScreen = 0;
public static final int default_tabsPlacement = 0; public static final int default_tabsPlacement = 0;
public static final boolean default_executeRulesAndProfilesWithSingleClick = false; public static final boolean default_executeRulesAndProfilesWithSingleClick = false;
@@ -198,6 +203,7 @@ public class Settings implements SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
startServiceAtSystemBoot = prefs.getBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot); startServiceAtSystemBoot = prefs.getBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot);
logToConsole = prefs.getBoolean("logToConsole", default_logToConsole);
writeLogFile = prefs.getBoolean("writeLogFile", default_writeLogFile); writeLogFile = prefs.getBoolean("writeLogFile", default_writeLogFile);
boolean useTextToSpeech = false; boolean useTextToSpeech = false;
@@ -260,6 +266,7 @@ public class Settings implements SharedPreferences
activityDetectionRequiredProbability = Integer.parseInt(prefs.getString("activityDetectionRequiredProbability", String.valueOf(default_activityDetectionRequiredProbability))); activityDetectionRequiredProbability = Integer.parseInt(prefs.getString("activityDetectionRequiredProbability", String.valueOf(default_activityDetectionRequiredProbability)));
privacyLocationing = prefs.getBoolean("privacyLocationing", default_privacyLocationing); 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))); startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement))); tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
@@ -339,6 +346,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("startServiceAtSystemBoot") || force) if(!prefs.contains("startServiceAtSystemBoot") || force)
editor.putBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot); editor.putBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot);
if(!prefs.contains("logToConsole") || force)
editor.putBoolean("logToConsole", default_logToConsole);
if(!prefs.contains("writeLogFile") || force) if(!prefs.contains("writeLogFile") || force)
editor.putBoolean("writeLogFile", default_writeLogFile); editor.putBoolean("writeLogFile", default_writeLogFile);
@@ -453,6 +463,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("privacyLocationing") || force) if(!prefs.contains("privacyLocationing") || force)
editor.putBoolean("privacyLocationing", default_privacyLocationing); editor.putBoolean("privacyLocationing", default_privacyLocationing);
if(!prefs.contains("uiTheme") || force)
editor.putString("uiTheme", String.valueOf(default_uiTheme));
if(!prefs.contains("startScreen") || force) if(!prefs.contains("startScreen") || force)
editor.putString("startScreen", String.valueOf(default_startScreen)); editor.putString("startScreen", String.valueOf(default_startScreen));
@@ -514,6 +527,7 @@ public class Settings implements SharedPreferences
Editor editor = prefs.edit(); Editor editor = prefs.edit();
editor.putBoolean("startServiceAtSystemBoot", startServiceAtSystemBoot); editor.putBoolean("startServiceAtSystemBoot", startServiceAtSystemBoot);
editor.putBoolean("logToConsole", logToConsole);
editor.putBoolean("writeLogFile", writeLogFile); editor.putBoolean("writeLogFile", writeLogFile);
// editor.putBoolean("useTextToSpeech", useTextToSpeech); // editor.putBoolean("useTextToSpeech", useTextToSpeech);
editor.putBoolean("useTextToSpeechOnNormal", useTextToSpeechOnNormal); editor.putBoolean("useTextToSpeechOnNormal", useTextToSpeechOnNormal);
@@ -552,6 +566,7 @@ public class Settings implements SharedPreferences
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency)); editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability)); editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
editor.putBoolean("privacyLocationing", privacyLocationing); editor.putBoolean("privacyLocationing", privacyLocationing);
editor.putString("uiTheme", String.valueOf(uiTheme));
editor.putString("startScreen", String.valueOf(startScreen)); editor.putString("startScreen", String.valueOf(startScreen));
editor.putString("tabsPlacement", String.valueOf(tabsPlacement)); editor.putString("tabsPlacement", String.valueOf(tabsPlacement));
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick); editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
@@ -2,6 +2,7 @@ package com.jens.automation2;
import java.sql.Time; import java.sql.Time;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
public class TimeFrame public class TimeFrame
{ {
@@ -20,18 +21,19 @@ public class TimeFrame
public void setDayList(ArrayList<Integer> dayList) public void setDayList(ArrayList<Integer> dayList)
{ {
this.dayList = dayList; this.dayList = dayList;
Collections.sort(dayList);
} }
public void setDayListFromString(String dayListString) public void setDayListFromString(String dayListString)
{ {
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray(); char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>(); dayList = new ArrayList<Integer>();
for(char item : dayListCharArray) for(char item : dayListCharArray)
{ {
// Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item))); dayList.add(Integer.parseInt(String.valueOf(item)));
} }
Collections.sort(dayList);
} }
public TimeObject getTriggerTimeStart() public TimeObject getTriggerTimeStart()
@@ -17,6 +17,7 @@ import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.BroadcastListener; import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.CalendarReceiver; import com.jens.automation2.receivers.CalendarReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver; import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.DeviceOrientationListener; import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener; import com.jens.automation2.receivers.HeadphoneJackListener;
import com.jens.automation2.receivers.MediaPlayerListener; 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.NotificationListener;
import com.jens.automation2.receivers.PhoneStatusListener; import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener; import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ProximityReceiver;
import com.jens.automation2.receivers.ScreenStateReceiver; import com.jens.automation2.receivers.ScreenStateReceiver;
import com.jens.automation2.receivers.TetheringReceiver; import com.jens.automation2.receivers.TetheringReceiver;
@@ -66,6 +68,7 @@ public class Trigger
tethering, tethering,
subSystemState, subSystemState,
checkVariable, checkVariable,
proximity,
calendarEvent, calendarEvent,
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy 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); return context.getResources().getString(R.string.subSystemState);
case checkVariable: case checkVariable:
return context.getResources().getString(R.string.checkVariable); return context.getResources().getString(R.string.checkVariable);
case proximity:
return context.getResources().getString(R.string.proximity);
case calendarEvent: case calendarEvent:
return context.getResources().getString(R.string.calendarEventCapital); return context.getResources().getString(R.string.calendarEventCapital);
default: 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 }; public static enum subSystemStates { wifi, bluetooth };
Rule parentRule = null; Rule parentRule = null;
@@ -261,6 +295,10 @@ public class Trigger
if(!checkCalendarEvent(false)) if(!checkCalendarEvent(false))
result = false; result = false;
break; break;
case proximity:
if(!checkProximity())
result = false;
break;
default: default:
break; break;
} }
@@ -293,17 +331,17 @@ public class Trigger
{ {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 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 myApp = params[0];
String myTitleDir = params[1]; String myTitleDir = params[1];
String requiredTitle = params[2]; String requiredTitle = params[2];
String myTextDir = params[3]; String myTextDir = params[3];
String requiredText; // String requiredText;
if (params.length >= 5) // if (params.length >= 5)
requiredText = params[4]; String requiredText = params[4];
else // else
requiredText = ""; // requiredText = "";
if(this.getTriggerParameter()) if(this.getTriggerParameter())
{ {
@@ -562,16 +600,42 @@ public class Trigger
boolean checkHeadsetPlugged() boolean checkHeadsetPlugged()
{ {
if(HeadphoneJackListener.isHeadsetConnected() != this.getTriggerParameter()) /*
return false; Wenn verbunden:
else - either -> true
if(this.getHeadphoneType() != 2 && this.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType()) - 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); if(this.getTriggerParameter()) // connection demanded
return false; {
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() boolean checkSubSystemState()
@@ -613,8 +677,14 @@ public class Trigger
{ {
if (map.containsKey(conditions[0])) if (map.containsKey(conditions[0]))
{ {
if (map.get(conditions[0]).equals(conditions[1])) if(Miscellaneous.isRegularExpression(conditions[1]))
return true; {
return (map.get(conditions[0]).matches(conditions[1]) == this.getTriggerParameter());
}
else
{
return (map.get(conditions[0]).equals(conditions[1]) == this.getTriggerParameter());
}
} }
} }
} }
@@ -660,7 +730,7 @@ public class Trigger
public boolean checkCalendarEvent(CalendarReceiver.CalendarEvent event, boolean ignoreActive) public boolean checkCalendarEvent(CalendarReceiver.CalendarEvent event, boolean ignoreActive)
{ {
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split); String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false); // List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
/* /*
0 = titleDir 0 = titleDir
@@ -677,8 +747,8 @@ public class Trigger
11 = calendars list 11 = calendars list
*/ */
boolean isActive = getTriggerParameter(); boolean shouldBeActive = getTriggerParameter();
if (!ignoreActive && isActive != event.isCurrentlyActive()) if (!ignoreActive && shouldBeActive != event.isCurrentlyActive())
{ {
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event.title + " has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5); Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event.title + " has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5);
return false; return false;
@@ -761,6 +831,27 @@ public class Trigger
return true; 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() boolean checkBluetooth()
{ {
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Checking for bluetooth...", this.getParentRule().getName()), 4); 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. // 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(this.getPointOfInterest() != null)
{ {
// if(activePoi.equals(oneTrigger.getPointOfInterest()))
// {
if(!this.getTriggerParameter()) 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); 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); 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; return false;
} }
// }
} }
else if(this.getPointOfInterest() == null) else if(this.getPointOfInterest() == null)
{ {
@@ -1152,6 +1240,12 @@ public class Trigger
public boolean hasStateNotAppliedSinceLastRuleExecution() 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) 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); 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; int desiredType;
String[] typeParams = getTriggerParameter2().split(triggerParameter2Split, -1); String[] typeParams = getTriggerParameter2().split(triggerParameter2Split, -1);
desiredType = Integer.parseInt(typeParams[0]); desiredType = Integer.parseInt(typeParams[0]);
if(desiredType == BatteryReceiver.getCurrentChargingType()) if(desiredType == BatteryReceiver.batteryChargingTypeAny)
return true;
else if(desiredType == BatteryReceiver.getCurrentChargingType())
return true; return true;
} }
} }
@@ -1224,7 +1320,7 @@ public class Trigger
return false; return false;
} }
public boolean checkDateTime(Object triggeringObject, boolean checkifStateChangedSinceLastRuleExecution) public boolean checkDateTime(Object triggeringObject, boolean checkIfStateChangedSinceLastRuleExecution)
{ {
/* /*
* Use format known from Automation * Use format known from Automation
@@ -1246,142 +1342,52 @@ public class Trigger
{ {
TimeFrame tf = new TimeFrame(getTriggerParameter2()); TimeFrame tf = new TimeFrame(getTriggerParameter2());
if(tf.getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK))) if (DateTimeListener.areWeInTimeFrame(this, triggeringObject) != this.getTriggerParameter())
{ {
if( if (triggerParameter)
// Regular case, start time is lower than end time 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.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0 Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + tf.toString() + "), but demanded is outside.", 4);
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0 return false;
) }
||
// Other case, start time higher than end time, timeframe goes over midnight // We are inside or outside of the timeframe as demanded by the trigger
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0 if (tf.getRepetition() > 0)
&& {
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0 if (!isSupposedToRepeatSinceLastExecution(Calendar.getInstance()))
||
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
)
)
{ {
// We are in the timeframe Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " applies, but repetition is not due, yet.", 4);
Miscellaneous.logEvent("i", "Trigger", "TimeFrame: We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + tf.toString() + ").", 4); return false;
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;
}
} }
else else
{ Miscellaneous.logEvent("i", "TimeFrame", "TimeFrame: Trigger of rule " + this.getParentRule().getName() + " would apply because repetition is due.", 4);
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;
}
}
} }
else 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); if (checkIfStateChangedSinceLastRuleExecution)
return false; {
/*
* 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) 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); Miscellaneous.logEvent("e", "Trigger", "There was an error while checking if the time based trigger applies: " + Log.getStackTraceString(e), 1);
return false; return false;
} }
}
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now) return true;
{
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;
} }
boolean isSupposedToRepeatSinceLastExecution(Calendar now) boolean isSupposedToRepeatSinceLastExecution(Calendar now)
@@ -1435,7 +1406,7 @@ public class Trigger
// the simple stuff: // the simple stuff:
if(lastExec == null) // rule never run, go any way if(lastExec == null) // rule never ran, go in any case
return true; return true;
else if(tf.getRepetition() <= 0) // is not set to repeat at all else if(tf.getRepetition() <= 0) // is not set to repeat at all
return false; return false;
@@ -1446,42 +1417,18 @@ public class Trigger
* we're inside the specified timeframe. * we're inside the specified timeframe.
*/ */
Calendar timeSupposedToRunNext = getNextRepeatedExecutionAfter(this, lastExec); Calendar lastRepetitionNotExecutedYet = DateTimeListener.getNextRepeatedExecution(this);
if(now.getTimeInMillis() > timeSupposedToRunNext.getTimeInMillis()) 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 true;
return false; 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() public int getHeadphoneType()
{ {
return headphoneType; return headphoneType;
@@ -1787,7 +1734,7 @@ public class Trigger
try try
{ {
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath); 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. // This type doesn't have an activate/deactivate equivalent, at least not yet.
returnString.append(Miscellaneous.runMethodReflective(ActivityManageRule.activityDetectionClassPath, "getDescription", new Object[]{getActivityDetectionType()})); 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)); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deactivated));
break; break;
case checkVariable: case checkVariable:
if (triggerParameter2.contains(triggerParameter2Split)) if(triggerParameter)
{ {
String[] parts = triggerParameter2.split(triggerParameter2Split); if (triggerParameter2.contains(triggerParameter2Split))
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckString), parts[0], parts[1])); {
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 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; break;
case calendarEvent: case calendarEvent:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent)); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent));
@@ -2040,6 +1995,10 @@ public class Trigger
returnString.append(")"); returnString.append(")");
break; 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: default:
returnString.append("error"); returnString.append("error");
break; break;
@@ -149,6 +149,13 @@ public class XmlFileInterface
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getVolumeNotifications())); serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getVolumeNotifications()));
serializer.endTag(null, "volumeNotifications"); 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.startTag(null, "changeVolumeAlarms");
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeVolumeAlarms())); serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeVolumeAlarms()));
serializer.endTag(null, "changeVolumeAlarms");// serializer.endTag(null, "changeVolumeAlarms");//
@@ -619,8 +626,12 @@ public class XmlFileInterface
newProfile.setVolumeMusic(Integer.parseInt(readTag(parser, "volumeMusic"))); newProfile.setVolumeMusic(Integer.parseInt(readTag(parser, "volumeMusic")));
else if (name.equals("changeVolumeNotifications")) else if (name.equals("changeVolumeNotifications"))
newProfile.setChangeVolumeNotifications(Boolean.parseBoolean(readTag(parser, "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")) else if (name.equals("volumeNotifications"))
newProfile.setVolumeNotifications(Integer.parseInt(readTag(parser, "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")) else if (name.equals("changeVolumeAlarms"))
newProfile.setChangeVolumeAlarms(Boolean.parseBoolean(readTag(parser, "changeVolumeAlarms"))); newProfile.setChangeVolumeAlarms(Boolean.parseBoolean(readTag(parser, "changeVolumeAlarms")));
else if (name.equals("volumeAlarms")) else if (name.equals("volumeAlarms"))
@@ -700,7 +711,7 @@ public class XmlFileInterface
private static Rule readRule(XmlPullParser parser) throws XmlPullParserException, IOException private static Rule readRule(XmlPullParser parser) throws XmlPullParserException, IOException
{ {
/* FILE EXAMPE: /* FILE EXAMPLE:
* ***************** * *****************
* <Automation> * <Automation>
* <PointOfInterestCollection> * <PointOfInterestCollection>
@@ -1084,7 +1095,7 @@ public class XmlFileInterface
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
{ {
/* FILE EXAMPE: /* FILE EXAMPLE:
* ***************** * *****************
* <Automation> * <Automation>
* <PointOfInterestCollection> * <PointOfInterestCollection>
@@ -1135,28 +1146,10 @@ public class XmlFileInterface
// *** deprecated // *** deprecated
//else //else
if(actionNameString.equals("turnWifiOn")) if(actionNameString.equals("turnUsbTetheringOn"))
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"))
newAction.setAction(Action_Enum.turnUsbTetheringOn); newAction.setAction(Action_Enum.turnUsbTetheringOn);
else if(actionNameString.equals("turnUsbTetheringOff")) else if(actionNameString.equals("turnUsbTetheringOff"))
newAction.setAction(Action_Enum.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")) else if(actionNameString.equals("playMusic"))
{ {
newAction.setAction(Action_Enum.controlMediaPlayback); newAction.setAction(Action_Enum.controlMediaPlayback);
@@ -1175,31 +1168,7 @@ public class XmlFileInterface
else if (name.equals("ActionParameter1")) else if (name.equals("ActionParameter1"))
{ {
// exclusion for deprecated types // exclusion for deprecated types
if(newAction.getAction().equals(Action_Enum.turnWifiOn)) if(newAction.getAction().equals(Action_Enum.turnUsbTetheringOn))
{
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))
{ {
newAction.setAction(Action_Enum.setUsbTethering); newAction.setAction(Action_Enum.setUsbTethering);
newAction.setParameter1(true); newAction.setParameter1(true);
@@ -1211,36 +1180,6 @@ public class XmlFileInterface
newAction.setParameter1(false); newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on 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()) 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()) 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 // we will be using wifiReceiver, deactivate AccelerometerTimer if applicable
SensorActivity.stopAccelerometerTimer(); SensorActivity.stopAccelerometerTimer();
@@ -88,7 +88,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
catch(NullPointerException ne) catch(NullPointerException ne)
{ {
// Nothing to do, there is no last activated rule. Wifi hasn't been activated so we don't // 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 else
@@ -363,10 +363,10 @@ public class CellLocationChangedReceiver extends PhoneStateListener
// Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4); // Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4);
} }
else 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 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) catch(Exception ex)
@@ -64,36 +64,36 @@ public class SensorActivity implements SensorEventListener
{ {
} }
public void onSensorChanged(SensorEvent event) public void onSensorChanged(SensorEvent event)
{ {
// Device has been moved // Device has been moved
float x = event.values[0]; float x = event.values[0];
float y = event.values[1]; float y = event.values[1];
float z = event.values[2]; float z = event.values[2];
if(mInitialized) if(mInitialized)
{ {
deltaX = Math.abs(lastX-x); deltaX = Math.abs(lastX-x);
deltaY = Math.abs(lastY-y); deltaY = Math.abs(lastY-y);
deltaZ = Math.abs(lastZ-z); deltaZ = Math.abs(lastZ-z);
//Wenn das jetzt einen gewissen Grenzwert übersteigt, müßten wir den CellListener wieder aktivieren // If that exceeds a certain delta we need to start CellLocationListener again
if(deltaX > Settings.accelerometerMovementThreshold | deltaY > Settings.accelerometerMovementThreshold | deltaZ > Settings.accelerometerMovementThreshold) 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); String text = "Device has been moved. " + String.valueOf(deltaX)+" / "+String.valueOf(deltaY)+" / "+String.valueOf(deltaZ);
Miscellaneous.logEvent("i", "Accelerometer", text, 5); Miscellaneous.logEvent("i", "Accelerometer", text, 5);
CellLocationChangedReceiver.resetFollowUpdate(); CellLocationChangedReceiver.resetFollowUpdate();
CellLocationChangedReceiver.startCellLocationChangedReceiver(); CellLocationChangedReceiver.startCellLocationChangedReceiver();
} }
} }
else else
{ {
lastX = x; lastX = x;
lastY = y; lastY = y;
lastZ = z; lastZ = z;
mInitialized = true; mInitialized = true;
} }
} }
protected static void startAccelerometerReceiver() protected static void startAccelerometerReceiver()
{ {
@@ -7,6 +7,7 @@ import android.content.IntentFilter;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log; import android.util.Log;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
@@ -213,7 +214,12 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
wifiBrInstance = new WifiBroadcastReceiver(); wifiBrInstance = new WifiBroadcastReceiver();
WifiBroadcastReceiver.parentLocationProvider = loc; WifiBroadcastReceiver.parentLocationProvider = loc;
} }
loc.getParentService().registerReceiver(wifiBrInstance, wifiListenerIntentFilter);
if(Build.VERSION.SDK_INT >= 26)
loc.getParentService().registerReceiver(wifiBrInstance, wifiListenerIntentFilter, Context.RECEIVER_EXPORTED);
else
loc.getParentService().registerReceiver(wifiBrInstance, wifiListenerIntentFilter);
wifiListenerActive = true; wifiListenerActive = true;
} }
} }
@@ -1,11 +1,14 @@
package com.jens.automation2.receivers; package com.jens.automation2.receivers;
import static android.os.BatteryManager.*;
import android.os.BatteryManager;
import android.Manifest; import android.Manifest;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.BatteryManager; import android.os.Build;
import android.util.Log; import android.util.Log;
import com.jens.automation2.ActivityPermissions; import com.jens.automation2.ActivityPermissions;
@@ -18,12 +21,17 @@ import java.util.ArrayList;
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface 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; public static AutomationService automationServiceRef = null;
static int batteryLevel = -1; // initialize with a better value than this static int batteryLevel = -1; // initialize with a better value than this
static boolean usbHostConnected = false; static boolean usbHostConnected = false;
static boolean batteryReceiverActive = false; static boolean batteryReceiverActive = false;
static IntentFilter batteryIntentFilter = null; static IntentFilter batteryIntentFilter = null;
static Intent batteryStatus = null; static Intent batteryStatusReceiverIntent = null;
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
private static int currentChargingType = 0; //AC, wireless, USB private static int currentChargingType = 0; //AC, wireless, USB
@@ -45,7 +53,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW); batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
} }
batteryStatus = automationServiceRef.registerReceiver(batteryInfoReceiverInstance, batteryIntentFilter); if(Build.VERSION.SDK_INT >= 26)
batteryStatusReceiverIntent = automationServiceRef.registerReceiver(batteryInfoReceiverInstance, batteryIntentFilter, Context.RECEIVER_EXPORTED);
else
batteryStatusReceiverIntent = automationServiceRef.registerReceiver(batteryInfoReceiverInstance, batteryIntentFilter);
batteryReceiverActive = true; batteryReceiverActive = true;
} }
@@ -102,7 +113,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
{ {
try try
{ {
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); batteryLevel = intent.getIntExtra(EXTRA_LEVEL, -1);
// int scale = -1; // int scale = -1;
// int voltage = -1; // int voltage = -1;
// int temp = -1; // int temp = -1;
@@ -112,36 +123,36 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
Log.i("Battery", "Level: " + String.valueOf(batteryLevel)); Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
this.actionBatteryLevel(context); this.actionBatteryLevel(context);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); int status = intent.getIntExtra(EXTRA_STATUS, -1);
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); int statusPlugged = intent.getIntExtra(EXTRA_PLUGGED, -1);
Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged), 5); Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged), 5);
switch(statusPlugged) switch(statusPlugged)
{ {
case BatteryManager.BATTERY_PLUGGED_AC: case BATTERY_PLUGGED_AC:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show(); // Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5); Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
this.actionCharging(context, statusPlugged); this.actionCharging(context, statusPlugged);
break; break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS: case BATTERY_PLUGGED_WIRELESS:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show(); // Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "BatteryReceiver", "Wireless charging.", 5); Miscellaneous.logEvent("i", "BatteryReceiver", "Wireless charging.", 5);
this.actionCharging(context, statusPlugged); this.actionCharging(context, statusPlugged);
break; break;
case BatteryManager.BATTERY_PLUGGED_USB: case BATTERY_PLUGGED_USB:
this.actionUsbConnected(context); this.actionUsbConnected(context);
break; break;
} }
switch(status) switch(status)
{ {
case BatteryManager.BATTERY_STATUS_CHARGING: case BATTERY_STATUS_CHARGING:
case BatteryManager.BATTERY_STATUS_FULL: case BATTERY_STATUS_FULL:
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5); // Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
this.actionCharging(context, statusPlugged); this.actionCharging(context, statusPlugged);
break; break;
case BatteryManager.BATTERY_STATUS_DISCHARGING: case BATTERY_STATUS_DISCHARGING:
case BatteryManager.BATTERY_STATUS_NOT_CHARGING: case BATTERY_STATUS_NOT_CHARGING:
this.actionDischarging(context); this.actionDischarging(context);
break; break;
} }
@@ -163,7 +174,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
case 1: case 1:
Miscellaneous.logEvent("i", "ChargingInfo", "Device is discharging.", 3); Miscellaneous.logEvent("i", "ChargingInfo", "Device is discharging.", 3);
break; break;
case BatteryManager.BATTERY_STATUS_CHARGING: case BATTERY_STATUS_CHARGING:
Miscellaneous.logEvent("i", "ChargingInfo", "Device is charging.", 3); Miscellaneous.logEvent("i", "ChargingInfo", "Device is charging.", 3);
break; break;
} }
@@ -178,10 +189,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private void actionCharging(Context context, int statusPlugged) 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); Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING; currentChargingState = BATTERY_STATUS_CHARGING;
currentChargingType = statusPlugged; currentChargingType = statusPlugged;
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
@@ -207,10 +218,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private void actionDischarging(Context context) 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); Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3);
currentChargingState = BatteryManager.BATTERY_STATUS_UNKNOWN; currentChargingState = BATTERY_STATUS_UNKNOWN;
//activate rule(s) //activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false); // ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
@@ -243,7 +254,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
oneRule.activate(automationServiceRef, false); oneRule.activate(automationServiceRef, false);
} }
this.actionCharging(context, BatteryManager.BATTERY_PLUGGED_USB); this.actionCharging(context, BATTERY_PLUGGED_USB);
} }
} }
@@ -293,7 +304,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
@Override @Override
public Trigger_Enum[] getMonitoredTrigger() 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 }; return new Trigger_Enum[] { Trigger_Enum.batteryLevel, Trigger_Enum.charging, Trigger_Enum.usb_host_connection };
} }
} }
@@ -1,12 +1,16 @@
package com.jens.automation2.receivers; package com.jens.automation2.receivers;
import static android.content.Context.RECEIVER_EXPORTED;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Build;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import com.jens.automation2.ActivityPermissions; import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
@@ -56,7 +60,11 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
{ {
Miscellaneous.logEvent("i", "BluetoothReceiver", "Starting BluetoothReceiver", 4); Miscellaneous.logEvent("i", "BluetoothReceiver", "Starting BluetoothReceiver", 4);
bluetoothReceiverActive = true; bluetoothReceiverActive = true;
AutomationService.getInstance().registerReceiver(bluetoothReceiverInstance, bluetoothReceiverIntentFilter);
if(Build.VERSION.SDK_INT >= 26)
AutomationService.getInstance().registerReceiver(bluetoothReceiverInstance, bluetoothReceiverIntentFilter, Context.RECEIVER_EXPORTED);
else
AutomationService.getInstance().registerReceiver(bluetoothReceiverInstance, bluetoothReceiverIntentFilter);
} }
} }
catch(Exception ex) catch(Exception ex)
@@ -149,8 +157,6 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
{ {
return lhs.getName().compareTo(rhs.getName()); return lhs.getName().compareTo(rhs.getName());
} }
;
}); });
} }
catch(NullPointerException e) catch(NullPointerException e)
@@ -159,6 +165,12 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
returnArray = new BluetoothDevice[] {}; 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; return returnArray;
} }
@@ -57,7 +57,14 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
{ {
for (String key : intent.getExtras().keySet()) for (String key : intent.getExtras().keySet())
{ {
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4); try
{
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
}
catch(NullPointerException e)
{
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + "unknown class", 4);
}
} }
} }
@@ -129,7 +136,11 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
try 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; broadcastReceiverActive = true;
} }
catch(Exception e) catch(Exception e)
@@ -14,6 +14,7 @@ import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous; import com.jens.automation2.Miscellaneous;
@@ -508,12 +509,20 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false); 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) if (events.size() == 0)
{ {
Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 4); Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 4);
} }
else 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<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
List<Long> wakeUpCandidatesList = new ArrayList<>(); List<Long> wakeUpCandidatesList = new ArrayList<>();
@@ -580,7 +589,10 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
calendarIntentFilter.addDataAuthority("com.android.calendar", null); 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; calendarReceiverActive = true;
@@ -57,7 +57,11 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
{ {
Miscellaneous.logEvent("i", "Wifi Listener", "Starting connectivityReceiver", 4); Miscellaneous.logEvent("i", "Wifi Listener", "Starting connectivityReceiver", 4);
connectivityReceiverActive = true; connectivityReceiverActive = true;
automationServiceRef.registerReceiver(connectivityReceiverInstance, connectivityIntentFilter);
if(Build.VERSION.SDK_INT >= 26)
automationServiceRef.registerReceiver(connectivityReceiverInstance, connectivityIntentFilter, Context.RECEIVER_EXPORTED);
else
automationServiceRef.registerReceiver(connectivityReceiverInstance, connectivityIntentFilter);
} }
} }
catch(Exception ex) catch(Exception ex)
@@ -136,7 +140,12 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
// Airplane mode status has changed. // Airplane mode status has changed.
Miscellaneous.logEvent("i", "Connectivity", "Airplane mode changed.", 2); Miscellaneous.logEvent("i", "Connectivity", "Airplane mode changed.", 2);
boolean isAirplaneMode = isAirplaneMode(context); 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.findRuleCandidates(Trigger_Enum.airplaneMode);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode); // ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
@@ -8,10 +8,10 @@ import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
import com.jens.automation2.BuildConfig;
import com.jens.automation2.Miscellaneous; import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule; import com.jens.automation2.Rule;
import com.jens.automation2.TimeFrame; import com.jens.automation2.TimeFrame;
@@ -19,17 +19,17 @@ import com.jens.automation2.TimeObject;
import com.jens.automation2.Trigger; import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum; import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
{ {
private static AutomationService automationServiceRef; private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance; private static AlarmManager centralAlarmManagerInstance;
private static boolean alarmListenerActive = false; private static boolean alarmListenerActive=false;
private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>(); private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>();
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>(); private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
static PendingIntent alarmPendingIntent = null; static PendingIntent alarmPendingIntent = null;
@@ -53,18 +53,18 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
{ {
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2); Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame); ArrayList<Rule> allRulesWithTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
for(int i=0; i < allRulesWithNowInTimeFrame.size(); i++) for(int i=0; i < allRulesWithTimeFrame.size(); i++)
{ {
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context)) if(allRulesWithTimeFrame.get(i).getsGreenLight(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false); allRulesWithTimeFrame.get(i).activate(automationServiceRef, false);
} }
setAlarms(); setOrResetAlarms();
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setAlarms() public static void setOrResetAlarms()
{ {
alarmCandidates.clear(); alarmCandidates.clear();
@@ -77,7 +77,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>(); ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame); allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
// allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
/* /*
* Take care of regular executions, no repetitions in between. * 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 * 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 * 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()); TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
if(tf.getRepetition() > 0) if(tf.getRepetition() > 0)
{ {
if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext())) // if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
{ // {
Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow); Calendar calSchedule = getNextRepeatedExecution(oneTrigger);
alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString())); alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
} // }
} }
} }
} }
@@ -219,7 +218,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
private static void scheduleNextAlarm() private static void scheduleNextAlarm()
{ {
Long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
ScheduleElement scheduleCandidate = null; ScheduleElement scheduleCandidate = null;
if(alarmCandidates.size() == 0) if(alarmCandidates.size() == 0)
@@ -251,27 +250,29 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 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 else
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent); centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis()); 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() public static void clearAlarms()
{ {
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4); Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for(int requestCode : requestCodeList) for(int requestCode : requestCodeList)
{ {
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class); Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
if(alarmPendingIntent == null) if(alarmPendingIntent == null)
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0); alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent); centralAlarmManagerInstance.cancel(alarmPendingIntent);
} }
requestCodeList.clear(); requestCodeList.clear();
} }
@@ -282,11 +283,10 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4); Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
DateTimeListener.automationServiceRef = givenAutomationServiceRef; DateTimeListener.automationServiceRef = givenAutomationServiceRef;
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE); centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
alarmListenerActive = true; alarmListenerActive = true;
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4); Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
DateTimeListener.setAlarms(); DateTimeListener.setOrResetAlarms();
// // get a Calendar object with current time // // get a Calendar object with current time
// Calendar cal = Calendar.getInstance(); // Calendar cal = Calendar.getInstance();
@@ -304,16 +304,13 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
{ {
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4); Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms(); clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent); centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false; alarmListenerActive = false;
} }
else else
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5); Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
} }
public static void reloadAlarms()
{
DateTimeListener.setAlarms();
}
@Override @Override
public void startListener(AutomationService automationService) public void startListener(AutomationService automationService)
{ {
@@ -371,46 +368,217 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
} }
} }
@RequiresApi(api = Build.VERSION_CODES.N) static int getNextDayIntForExecution(Trigger trigger)
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{ {
Calendar calSet; TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
TimeObject setTime; 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()); TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0) 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 Are we inside of the timeframe or outside?
* zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten.
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 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; static int sensorValueCounter = 0;
// Gravity rotational data // Gravity rotational data
float gravity[]; float[] gravity;
// Magnetic rotational data // Magnetic rotational data
float magnetic[]; //for magnetic rotational data float[] magnetic; //for magnetic rotational data
float accels[] = new float[3]; float[] accels = new float[3];
float mags[] = new float[3]; float[] mags = new float[3];
float[] values = new float[3]; float[] values = new float[3];
boolean hasMagneticSensor=false; boolean hasMagneticSensor=false;
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Build;
import android.util.Log; import android.util.Log;
import com.jens.automation2.ActivityPermissions; import com.jens.automation2.ActivityPermissions;
@@ -53,12 +54,14 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
{ {
try try
{ {
/*Broadcast Action: Wired Headset plugged in or unplugged. /*
The intent will have the following extra values: Broadcast Action: Wired Headset plugged in or unplugged.
The intent will have the following extra values:
state - 0 for unplugged, 1 for plugged. state - 0 for unplugged, 1 for plugged.
name - Headset type, human readable string name - Headset type, human readable string
microphone - 1 if headset has a microphone, 0 otherwise*/ microphone - 1 if headset has a microphone, 0 otherwise
*/
int state = intent.getExtras().getInt("state"); int state = intent.getExtras().getInt("state");
String name = intent.getExtras().getString("name"); String name = intent.getExtras().getString("name");
@@ -103,7 +106,11 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
{ {
Miscellaneous.logEvent("i", "HeadsetJackListener", "Starting HeadsetJackListener", 4); Miscellaneous.logEvent("i", "HeadsetJackListener", "Starting HeadsetJackListener", 4);
headphoneJackListenerActive = true; headphoneJackListenerActive = true;
automationService.registerReceiver(this, headphoneJackListenerIntentFilter);
if(Build.VERSION.SDK_INT >= 26)
automationService.registerReceiver(this, headphoneJackListenerIntentFilter, Context.RECEIVER_EXPORTED);
else
automationService.registerReceiver(this, headphoneJackListenerIntentFilter);
} }
} }
catch(Exception ex) catch(Exception ex)
@@ -8,10 +8,10 @@ import android.nfc.NdefMessage;
import android.nfc.NdefRecord; import android.nfc.NdefRecord;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.nfc.Tag; import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.Ndef; import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable; import android.nfc.tech.NdefFormatable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
@@ -36,18 +36,8 @@ public class NfcReceiver
public static NfcAdapter getNfcAdapter(Context context) public static NfcAdapter getNfcAdapter(Context context)
{ {
if(nfcAdapter == null) if(nfcAdapter == null)
{ nfcAdapter = NfcAdapter.getDefaultAdapter(context);
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);
}
}
return nfcAdapter; return nfcAdapter;
} }
@@ -66,7 +56,7 @@ public class NfcReceiver
if(action == null) if(action == null)
{ {
Miscellaneous.logEvent("i", "NFC", "action=null", 5); Miscellaneous.logEvent("i", "NFC", "action=null", 5);
return; return;
} }
if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
@@ -91,28 +81,6 @@ public class NfcReceiver
new NdefReaderTask().execute(tag); 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") @SuppressLint("NewApi")
@@ -307,7 +275,7 @@ public class NfcReceiver
{ {
format.connect(); format.connect();
format.format(completeMessageToWrite); format.format(completeMessageToWrite);
Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2); Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2);
return true; return true;
} }
catch(IOException e) catch(IOException e)
@@ -322,7 +290,7 @@ public class NfcReceiver
Miscellaneous.logEvent("e", "NFC", "Error writing tag: " + Log.getStackTraceString(e), 2); Miscellaneous.logEvent("e", "NFC", "Error writing tag: " + Log.getStackTraceString(e), 2);
} }
return false; return false;
} }
public static boolean checkNfcRequirements(Context context, boolean showErrorMessage) public static boolean checkNfcRequirements(Context context, boolean showErrorMessage)
@@ -334,14 +302,6 @@ public class NfcReceiver
return false; 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; return true;
} }
@@ -100,7 +100,7 @@ public class NotificationListener extends NotificationListenerService// implemen
synchronized boolean checkNotification(boolean created, StatusBarNotification sbn) 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) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
{ {
lastNotification = convertNotificationToSimpleNotification(created, sbn); lastNotification = convertNotificationToSimpleNotification(created, sbn);
@@ -146,13 +146,13 @@ public class NotificationListener extends NotificationListenerService// implemen
try try
{ {
if (extras.containsKey(EXTRA_TEXT)) if (extras.containsKey(EXTRA_TEXT))
text = extras.getString(EXTRA_TEXT).toString(); text = String.valueOf(extras.getCharSequence(EXTRA_TEXT));
} }
catch (NullPointerException e) catch (NullPointerException e)
{ {
// in stacked notifications the "surrounding" element has no text, only a title // in stacked notifications the "surrounding" element has no text, only a title
if (extras.containsKey(EXTRA_TEXT) && extras.get(EXTRA_TEXT) != null) 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(); SimpleNotification returnNotification = new SimpleNotification();
@@ -285,7 +285,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
if(!outgoingCallsReceiverActive) if(!outgoingCallsReceiverActive)
{ {
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->outgoingCallsReceiver", 4); Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->outgoingCallsReceiver", 4);
automationService.registerReceiver(outgoingCallsReceiverInstance, outgoingCallsIntentFilter);
if(Build.VERSION.SDK_INT >= 26)
automationService.registerReceiver(outgoingCallsReceiverInstance, outgoingCallsIntentFilter, Context.RECEIVER_EXPORTED);
else
automationService.registerReceiver(outgoingCallsReceiverInstance, outgoingCallsIntentFilter);
outgoingCallsReceiverActive = true; outgoingCallsReceiverActive = true;
} }
} }
@@ -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 };
}
}
@@ -71,7 +71,10 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
// Intent.ACTION_USER_UNLOCKED // Intent.ACTION_USER_UNLOCKED
} }
screenStatusIntent = automationServiceRef.registerReceiver(screenStateReceiverInstance, screenStateIntentFilter); if(Build.VERSION.SDK_INT >= 26)
screenStatusIntent = automationServiceRef.registerReceiver(screenStateReceiverInstance, screenStateIntentFilter, Context.RECEIVER_EXPORTED);
else
screenStatusIntent = automationServiceRef.registerReceiver(screenStateReceiverInstance, screenStateIntentFilter);
screenStateReceiverActive = true; screenStateReceiverActive = true;
} }
@@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous; import com.jens.automation2.Miscellaneous;
@@ -116,7 +117,10 @@ public class SubSystemStateReceiver extends BroadcastReceiver implements Automat
subSystemStateIntentFilter.addAction(stateBluetooth); subSystemStateIntentFilter.addAction(stateBluetooth);
} }
subSystemStatusIntent = automationServiceRef.registerReceiver(subSystemStateReceiverInstance, subSystemStateIntentFilter); if(Build.VERSION.SDK_INT >= 26)
subSystemStatusIntent = automationServiceRef.registerReceiver(subSystemStateReceiverInstance, subSystemStateIntentFilter, Context.RECEIVER_EXPORTED);
else
subSystemStatusIntent = automationServiceRef.registerReceiver(subSystemStateReceiverInstance, subSystemStateIntentFilter);
subSystemStateReceiverActive = true; subSystemStateReceiverActive = true;
} }
@@ -162,7 +162,11 @@ public class TetheringReceiver extends android.content.BroadcastReceiver impleme
try try
{ {
automationServiceRef.registerReceiver(receiverInstance, intentFilter); if(Build.VERSION.SDK_INT >= 26)
automationServiceRef.registerReceiver(receiverInstance, intentFilter, Context.RECEIVER_EXPORTED);
else
automationServiceRef.registerReceiver(receiverInstance, intentFilter);
receiverActive = true; receiverActive = true;
} }
catch(Exception e) catch(Exception e)
@@ -4,6 +4,7 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Build;
import android.util.Log; import android.util.Log;
import com.jens.automation2.AutomationService; import com.jens.automation2.AutomationService;
@@ -44,7 +45,10 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
timezoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED); timezoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
} }
automationService.registerReceiver(timeZoneListenerInstance, timezoneListenerIntentFilter); if(Build.VERSION.SDK_INT >= 26)
automationService.registerReceiver(timeZoneListenerInstance, timezoneListenerIntentFilter, Context.RECEIVER_EXPORTED);
else
automationService.registerReceiver(timeZoneListenerInstance, timezoneListenerIntentFilter);
} }
} }
catch(Exception ex) catch(Exception ex)
@@ -76,12 +80,12 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
if(action.equals(Intent.ACTION_TIMEZONE_CHANGED)) if(action.equals(Intent.ACTION_TIMEZONE_CHANGED))
{ {
Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3); Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3);
DateTimeListener.reloadAlarms(); DateTimeListener.setOrResetAlarms();
} }
else if(action.equals(Intent.ACTION_TIME_CHANGED)) else if(action.equals(Intent.ACTION_TIME_CHANGED))
{ {
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 3); Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 3);
DateTimeListener.reloadAlarms(); DateTimeListener.setOrResetAlarms();
} }
} }
@Override @Override
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

+11 -11
View File
@@ -14,7 +14,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/etActivityOrActionPath" android:id="@+id/etActivityOrActionPath"
@@ -45,7 +45,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvPoiTitle" android:id="@+id/tvPoiTitle"
@@ -77,7 +77,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvRuleTitle" android:id="@+id/tvRuleTitle"
@@ -109,7 +109,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvProfileTitle" android:id="@+id/tvProfileTitle"
@@ -142,12 +142,12 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:text="@string/toggableRules" android:text="@string/toggleableRules"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout> </LinearLayout>
@@ -160,7 +160,7 @@
android:id="@+id/tvToggableHelpText" android:id="@+id/tvToggableHelpText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/helpTextToggable" /> android:text="@string/helpTextToggleable" />
</LinearLayout> </LinearLayout>
@@ -169,7 +169,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvTimeFrameTitle" android:id="@+id/tvTimeFrameTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -197,7 +197,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvProcessMonitoringTitle" android:id="@+id/tvProcessMonitoringTitle"
@@ -225,7 +225,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -251,7 +251,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -31,6 +31,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> 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 <Button
android:layout_marginTop="@dimen/default_margin" android:layout_marginTop="@dimen/default_margin"
android:id="@+id/bApplyBrightness" android:id="@+id/bApplyBrightness"
@@ -0,0 +1,171 @@
<?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/target" />
<Spinner
android:id="@+id/spinnerSettingTarget"
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/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>
<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 <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@@ -13,7 +13,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -157,9 +157,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/change" /> android:text="@string/change" />
<TextView <TextView
android:id="@+id/tvNotificationsVolume"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/volumeRingtoneNotifications" android:text="@string/volumeNotifications"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginLeft="40dp" /> android:layout_marginLeft="40dp" />
<SeekBar <SeekBar
@@ -168,6 +169,24 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="40dp" /> 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 <CheckBox
android:id="@+id/checkBoxChangeVolumeAlarms" android:id="@+id/checkBoxChangeVolumeAlarms"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -338,5 +357,4 @@
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
@@ -15,7 +15,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -123,7 +123,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:background="@color/barBackgroundColor" android:background="@color/cardview_shadow_start_color"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
@@ -160,7 +160,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:background="@color/barBackgroundColor" android:background="@color/cardview_shadow_start_color"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
@@ -13,7 +13,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -31,7 +31,7 @@
<TextView <TextView
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin" android:layout_marginRight="@dimen/default_margin"
android:text="@string/VariableKey" /> android:text="@string/VariableKey" />
@@ -47,21 +47,42 @@
android:layout_marginTop="@dimen/default_margin"> android:layout_marginTop="@dimen/default_margin">
<TextView <TextView
android:layout_gravity="center_vertical" android:layout_gravity="top"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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 <LinearLayout
android:id="@+id/etVariableValueTrigger" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
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> </TableRow>
</TableLayout> </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 <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -16,7 +16,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -83,7 +83,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" 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"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_weight="30" android:layout_margin="@dimen/default_margin"
android:layout_margin="@dimen/default_margin" > android:layout_weight="30">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:orientation="vertical">
<TextView <TextView
android:id="@+id/tvRuleTitle" android:id="@+id/tvRuleTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/start" android:text="@string/start"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker <TimePicker
android:id="@+id/tpTimeFrameStart" android:id="@+id/tpTimeFrameStart"
android:layout_width="wrap_content" android:descendantFocusability="blocksDescendants"
android:layout_height="wrap_content" /> android:saveEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView <TextView
android:id="@+id/tvLastRule" android:id="@+id/tvLastRule"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/end" android:text="@string/end"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge" />
<TimePicker <TimePicker
android:id="@+id/tpTimeFrameStop" android:id="@+id/tpTimeFrameStop"
android:layout_width="wrap_content" android:descendantFocusability="blocksDescendants"
android:layout_height="wrap_content" /> android:saveEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_margin="10dp" android:layout_margin="10dp"
android:background="#aa000000" /> android:background="#aa000000" />
<TextView <TextView
android:id="@+id/textView2" android:id="@+id/textView2"
@@ -47,22 +51,22 @@
android:text="@string/insideOrOutsideTimeFrames" android:text="@string/insideOrOutsideTimeFrames"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge" />
<RadioGroup <RadioGroup
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<RadioButton <RadioButton
android:id="@+id/radioTimeFrameEntering" android:id="@+id/radioTimeFrameEntering"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:checked="true"
android:text="@string/entering" /> android:text="@string/entering" />
<RadioButton <RadioButton
android:id="@+id/radioTimeFrameLeaving" android:id="@+id/radioTimeFrameLeaving"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/leaving" /> android:text="@string/leaving" />
</RadioGroup> </RadioGroup>
<ImageView <ImageView
@@ -80,52 +84,52 @@
<TextView <TextView
android:id="@+id/tvDaysHint" android:id="@+id/tvDaysHint"
android:layout_marginVertical="@dimen/default_margin"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:textColor="@color/red" /> android:textColor="@color/red" />
<CheckBox <CheckBox
android:id="@+id/checkMonday" android:id="@+id/checkMonday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/monday" /> android:text="@string/monday" />
<CheckBox <CheckBox
android:id="@+id/checkTuesday" android:id="@+id/checkTuesday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/tuesday" /> android:text="@string/tuesday" />
<CheckBox <CheckBox
android:id="@+id/checkWednesday" android:id="@+id/checkWednesday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/wednesday" /> android:text="@string/wednesday" />
<CheckBox <CheckBox
android:id="@+id/checkThursday" android:id="@+id/checkThursday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/thursday" /> android:text="@string/thursday" />
<CheckBox <CheckBox
android:id="@+id/checkFriday" android:id="@+id/checkFriday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/friday" /> android:text="@string/friday" />
<CheckBox <CheckBox
android:id="@+id/checkSaturday" android:id="@+id/checkSaturday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/saturday" /> android:text="@string/saturday" />
<CheckBox <CheckBox
android:id="@+id/checkSunday" android:id="@+id/checkSunday"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/sunday" /> android:text="@string/sunday" />
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -136,7 +140,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:orientation="horizontal">
<CheckBox <CheckBox
android:id="@+id/chkRepeat" android:id="@+id/chkRepeat"
@@ -146,21 +150,21 @@
<EditText <EditText
android:id="@+id/etRepeatEvery" android:id="@+id/etRepeatEvery"
android:layout_marginLeft="@dimen/default_margin"
android:minWidth="75dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/default_margin"
android:enabled="false" android:enabled="false"
android:inputType="numberSigned" /> android:inputType="numberSigned"
android:minWidth="75dp" />
</LinearLayout> </LinearLayout>
<Button <Button
android:id="@+id/bSaveTimeFrame" android:id="@+id/bSaveTimeFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin" android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content" android:text="@string/save" />
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout> </LinearLayout>
+49 -59
View File
@@ -9,41 +9,48 @@
android:title="@string/generalSettings"> android:title="@string/generalSettings">
<CheckBoxPreference <CheckBoxPreference
android:key="startServiceAtSystemBoot" android:key="startServiceAtSystemBoot"
android:summary="@string/onOff" android:summary="@string/onOff"
android:title="@string/startAtSystemBoot" /> android:title="@string/startAtSystemBoot" />
<CheckBoxPreference <CheckBoxPreference
android:key="startServiceAfterAppUpdate" android:key="startServiceAfterAppUpdate"
android:summary="@string/startServiceAfterAppUpdate" android:summary="@string/startServiceAfterAppUpdate"
android:title="@string/startServiceAfterAppUpdateShort" /> 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" />
<CheckBoxPreference <CheckBoxPreference
android:key="writeLogFile" android:key="showIconWhenServiceIsRunning"
android:summary="@string/onOff" android:summary="@string/showIconWhenServiceIsRunning"
android:title="@string/writeLogFile" /> 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 <EditTextPreference
android:key="logLevel" android:key="logLevel"
android:summary="@string/logLevelSummary" android:summary="@string/logLevelSummary"
android:title="@string/logLevelTitle" android:title="@string/logLevelTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="logFileMaxSize" android:key="logFileMaxSize"
android:summary="@string/logFileMaxSizeSummary" android:summary="@string/logFileMaxSizeSummary"
android:title="@string/logFileMaxSizeTitle" 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 <ListPreference
android:key="startScreen" android:key="startScreen"
@@ -114,21 +121,11 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:summary="@string/positioningSettings" android:summary="@string/positioningSettings"
android:title="@string/positioningSettings"> android:title="@string/positioningSettings">
<!-- android:id="@id/lstPositioningEngine"--> <CheckBoxPreference
<!--
<ListPreference
android:title="@string/positioningEngine"
android:key="positioningEngine"
android:defaultValue="0"
android:entries="@array/positioningEngineOptions"
android:entryValues="@array/positioningEngineOptionsValues" />
-->
<CheckBoxPreference
android:key="useWifiForPositioning" android:key="useWifiForPositioning"
android:summary="@string/listenToWifiState" android:summary="@string/listenToWifiState"
android:title="@string/wifiState" /> android:title="@string/wifiState" />
@@ -142,19 +139,19 @@
android:key="useAccelerometerAfterIdleTime" android:key="useAccelerometerAfterIdleTime"
android:summary="@string/accelerometerTimer" android:summary="@string/accelerometerTimer"
android:title="@string/cellMastIdleTime" android:title="@string/cellMastIdleTime"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="accelerometerMovementThreshold" android:key="accelerometerMovementThreshold"
android:summary="@string/accelerometerThresholdDescription" android:summary="@string/accelerometerThresholdDescription"
android:title="@string/accelerometerThreshold" android:title="@string/accelerometerThreshold"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="speedMaximumTimeBetweenLocations" android:key="speedMaximumTimeBetweenLocations"
android:summary="@string/speedMaximumTimeBetweenLocations" android:summary="@string/speedMaximumTimeBetweenLocations"
android:title="@string/speedMaximumTime" android:title="@string/speedMaximumTime"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<CheckBoxPreference <CheckBoxPreference
android:key="rememberLastActivePoi" android:key="rememberLastActivePoi"
@@ -176,37 +173,31 @@
android:key="MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE" android:key="MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE"
android:summary="@string/minimumDistanceChangeForGpsLocationUpdates" android:summary="@string/minimumDistanceChangeForGpsLocationUpdates"
android:title="@string/distanceForGpsUpdate" android:title="@string/distanceForGpsUpdate"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE" android:key="MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE"
android:summary="@string/minimumDistanceChangeForNetworkLocationUpdates" android:summary="@string/minimumDistanceChangeForNetworkLocationUpdates"
android:title="@string/distanceForNetworkUpdate" android:title="@string/distanceForNetworkUpdate"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<!-- 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>
-->
<EditTextPreference <EditTextPreference
android:key="SATISFACTORY_ACCURACY_NETWORK" android:key="SATISFACTORY_ACCURACY_NETWORK"
android:summary="@string/satisfactoryAccuracyNetwork" android:summary="@string/satisfactoryAccuracyNetwork"
android:title="@string/networkAccuracy" android:title="@string/networkAccuracy"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="MINIMUM_TIME_BETWEEN_UPDATE" android:key="MINIMUM_TIME_BETWEEN_UPDATE"
android:summary="@string/minimumTimeForLocationUpdates" android:summary="@string/minimumTimeForLocationUpdates"
android:title="@string/timeForUpdate" android:title="@string/timeForUpdate"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="gpsTimeout" android:key="gpsTimeout"
android:summary="@string/timeoutForGpsComparisonsSummary" android:summary="@string/timeoutForGpsComparisonsSummary"
android:title="@string/timeoutForGpsComparisonsTitle" android:title="@string/timeoutForGpsComparisonsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number"/>
</PreferenceCategory> </PreferenceCategory>
@@ -218,19 +209,19 @@
android:key="timeBetweenNoiseLevelMeasurements" android:key="timeBetweenNoiseLevelMeasurements"
android:summary="@string/timeBetweenNoiseLevelMeasurementsSummary" android:summary="@string/timeBetweenNoiseLevelMeasurementsSummary"
android:title="@string/timeBetweenNoiseLevelMeasurementsTitle" android:title="@string/timeBetweenNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="lengthOfNoiseLevelMeasurements" android:key="lengthOfNoiseLevelMeasurements"
android:summary="@string/lengthOfNoiseLevelMeasurementsSummary" android:summary="@string/lengthOfNoiseLevelMeasurementsSummary"
android:title="@string/lengthOfNoiseLevelMeasurementsTitle" android:title="@string/lengthOfNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="referenceValueForNoiseLevelMeasurements" android:key="referenceValueForNoiseLevelMeasurements"
android:summary="@string/referenceValueForNoiseLevelMeasurementsSummary" android:summary="@string/referenceValueForNoiseLevelMeasurementsSummary"
android:title="@string/referenceValueForNoiseLevelMeasurementsTitle" android:title="@string/referenceValueForNoiseLevelMeasurementsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
@@ -247,19 +238,19 @@
android:key="httpAttempts" android:key="httpAttempts"
android:summary="@string/httpAttemptsSummary" android:summary="@string/httpAttemptsSummary"
android:title="@string/httpAttemptsTitle" android:title="@string/httpAttemptsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="httpAttemptsTimeout" android:key="httpAttemptsTimeout"
android:summary="@string/httpAttemptsTimeoutSummary" android:summary="@string/httpAttemptsTimeoutSummary"
android:title="@string/httpAttemptsTimeoutTitle" android:title="@string/httpAttemptsTimeoutTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="httpAttemptGap" android:key="httpAttemptGap"
android:summary="@string/httpAttemptGapSummary" android:summary="@string/httpAttemptGapSummary"
android:title="@string/httpAttemptGapTitle" android:title="@string/httpAttemptGapTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
@@ -271,7 +262,7 @@
android:key="timeBetweenProcessMonitorings" android:key="timeBetweenProcessMonitorings"
android:summary="@string/timeBetweenProcessMonitoringsSummary" android:summary="@string/timeBetweenProcessMonitoringsSummary"
android:title="@string/timeBetweenProcessMonitoringsTitle" android:title="@string/timeBetweenProcessMonitoringsTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
@@ -283,7 +274,7 @@
android:key="acceptDevicePositionSignalEveryX_MilliSeconds" android:key="acceptDevicePositionSignalEveryX_MilliSeconds"
android:summary="@string/deviceOrientationTimeAcceptIntervalSummary" android:summary="@string/deviceOrientationTimeAcceptIntervalSummary"
android:title="@string/deviceOrientationTimeAcceptIntervalTitle" android:title="@string/deviceOrientationTimeAcceptIntervalTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
@@ -295,13 +286,13 @@
android:key="activityDetectionFrequency" android:key="activityDetectionFrequency"
android:summary="@string/activityDetectionFrequencySummary" android:summary="@string/activityDetectionFrequencySummary"
android:title="@string/activityDetectionFrequencyTitle" android:title="@string/activityDetectionFrequencyTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
<EditTextPreference <EditTextPreference
android:key="activityDetectionRequiredProbability" android:key="activityDetectionRequiredProbability"
android:summary="@string/activityDetectionRequiredProbabilitySummary" android:summary="@string/activityDetectionRequiredProbabilitySummary"
android:title="@string/activityDetectionRequiredProbabilityTitle" android:title="@string/activityDetectionRequiredProbabilityTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
@@ -313,9 +304,8 @@
android:key="musicCheckFrequency" android:key="musicCheckFrequency"
android:summary="@string/musicCheckFrequencySummary" android:summary="@string/musicCheckFrequencySummary"
android:title="@string/musicCheckFrequencyTitle" android:title="@string/musicCheckFrequencyTitle"
android:inputType="number"></EditTextPreference> android:inputType="number" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
@@ -15,7 +15,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -370,11 +370,12 @@
android:text="@string/donate" /> android:text="@string/donate" />
<TextView <TextView
android:id="@+id/tvContactNotice"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin" android:layout_marginTop="@dimen/default_margin"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:text="@string/emailContactNotice" /> android:text="@string/contactNotice" />
</LinearLayout> </LinearLayout>
+1 -1
View File
@@ -30,7 +30,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvRuleTitle" android:id="@+id/tvRuleTitle"
@@ -34,7 +34,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/barBackgroundColor" > android:background="@color/cardview_shadow_start_color" >
<TextView <TextView
android:id="@+id/tvRuleTitle" android:id="@+id/tvRuleTitle"

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