Compare commits

...
172 Commits
Author SHA1 Message Date
jens 2a067507ae new release 1.7.2 2022-01-10 10:33:49 +01:00
jens 1c8eec735d code cleanups 2022-01-09 21:43:49 +01:00
jens 53f46c10da translations 2022-01-09 14:55:52 +01:00
jens c5f04afe85 translations 2022-01-09 14:01:38 +01:00
jens 4d7fa711f9 profile trigger 2022-01-09 13:51:38 +01:00
jens 4bea2113fa profile trigger 2022-01-09 13:48:12 +01:00
jens 890260b8eb startApp 2022-01-08 19:00:06 +01:00
jens 230521149f startApp 2022-01-08 14:46:01 +01:00
jens 9a50da550a bugs and translations 2022-01-05 23:27:27 +01:00
jens 941bb3e1af profile trigger 2022-01-05 18:06:26 +01:00
jens 5653a9c70e profile trigger 2022-01-04 17:51:27 +01:00
jens 8c6331237d Cosmetics 2022-01-04 16:14:13 +01:00
jens 1bbf04d548 Exclusion from battery optimization 2022-01-03 23:24:34 +01:00
jens a2d93d27cb Cosmetics 2022-01-03 19:50:57 +01:00
jens 0463e0aa19 Silent mode bug 2021-12-27 13:58:43 +01:00
jens 41cf907be3 Merge remote-tracking branch 'origin/development' 2021-12-24 01:50:44 +01:00
jens acae282a0d New changelog 2021-12-24 01:50:33 +01:00
jens ebfceee69f Translations 2021-12-24 01:38:42 +01:00
jens 69283c5fea Translations 2021-12-21 20:02:13 +01:00
jens fff0bde9d8 Merge remote-tracking branch 'origin/development' into development 2021-12-20 19:58:56 +01:00
jens f9c76ba951 Rework 2021-12-20 19:58:43 +01:00
jens d1263b46b6 Refactoring 2021-12-19 22:31:05 +01:00
jens 64801d8ff2 Rework 2021-12-19 17:12:24 +01:00
jens 3d8257aeec Rework 2021-12-19 14:47:46 +01:00
jens 67b2a81647 Rework 2021-12-19 12:58:33 +01:00
jens 3e9590d7d2 Rework 2021-12-18 13:29:47 +01:00
jens 21b8c6c7ec Rework 2021-12-18 02:43:04 +01:00
jens dc8cc14d20 Rework 2021-12-13 20:03:26 +01:00
jens 4fc1f8a2a9 Rework 2021-12-13 20:03:00 +01:00
jens d7e1cd44e8 Rework 2021-12-12 20:03:53 +01:00
jens c1139e1cb8 Rework 2021-12-11 14:15:05 +01:00
jens 03c8a1ff60 Rework 2021-12-11 02:04:45 +01:00
jens 20acd563e7 Refactoring 2021-12-09 22:54:34 +01:00
jens 5ae193847e Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Actions.java
2021-12-09 18:05:58 +01:00
jens 391479b164 Rework 2021-12-09 18:03:00 +01:00
jens fa578b175d Refactoring 2021-12-08 23:08:05 +01:00
jens 0008642044 Rework 2021-12-08 19:57:27 +01:00
jens 359dd545c7 Merge remote-tracking branch 'origin/transfer_applies_to_trigger' into development 2021-12-08 17:22:33 +01:00
jens 89ac69fd4b Rework 2021-12-08 17:22:18 +01:00
jens b88801500f Refactoring 2021-12-07 23:10:37 +01:00
jens 128116025f Rework 2021-12-07 16:45:05 +01:00
jens 5d3e89595f description 2021-12-05 22:28:30 +01:00
jens 8e5ad15c34 Rework 2021-12-05 17:24:47 +01:00
jens 8b29dd0985 Rework 2021-12-05 14:51:00 +01:00
jens c34ec83425 Rework 2021-12-04 13:24:43 +01:00
jens cdf1a8baa8 Rework 2021-12-04 02:39:37 +01:00
jens d28ee8d00d Fixed infinite loop 2021-12-03 22:30:34 +01:00
jens 2bb6f81596 Position trigger 2021-11-30 18:25:51 +01:00
jens 6f0dbc9555 Position trigger 2021-11-29 20:14:09 +01:00
jens a9bd7b9561 Position trigger 2021-11-28 20:01:58 +01:00
jens 81d6ab7b5f Position trigger 2021-11-27 20:22:13 +01:00
jens 034c76fe30 Translations and integrated BT tethering 2021-11-27 02:03:51 +01:00
jens 15637e914d Translations and integrated BT tethering 2021-11-27 01:52:57 +01:00
jens cd6ed7543c Translations and integrated BT tethering 2021-11-26 19:26:42 +01:00
jens f991325566 Merge remote-tracking branch 'origin/BT_tethering' into development 2021-11-26 18:56:28 +01:00
jens b744e76b07 Negative location coordinates allowed 2021-11-23 13:27:09 +01:00
jens 06d63826e6 Donate button 2021-11-20 16:14:21 +01:00
jens fb87d5e42d BT tethering 2021-11-17 21:46:56 +01:00
jens 17109b12d4 BT tethering 2021-11-15 20:28:38 +01:00
jens 92ca6d6cb4 BT tethering 2021-11-13 14:48:56 +01:00
jens 5fdc68e396 Merge remote-tracking branch 'origin/reoccuring_time_trigger' into development 2021-11-13 12:31:27 +01:00
jens ab0f2d88b4 Reoccuring time trigger 2021-11-13 02:32:39 +01:00
jens 06a6651fae Reoccuring time trigger 2021-11-13 02:17:36 +01:00
jens 473c464bf7 BT tethering 2021-11-13 01:00:36 +01:00
jens a5b9ced9ba line break 2021-11-11 10:28:46 +01:00
jens 9cea3f4285 reocc time 2021-11-10 21:47:09 +01:00
jens 0438a58f3e translation 2021-11-09 11:10:06 +01:00
jens 97f32bd012 Reoccuring time 2021-11-08 20:13:11 +01:00
jens 6588443459 reoccuring time 2021-11-07 17:29:00 +01:00
jens 604ab0eb43 miscellaneous 2021-11-07 15:38:42 +01:00
jens 31c4f6c1d1 Fixed crash of edit wifi trigger 2021-11-07 02:09:09 +01:00
jens 0c646b55fc Fixed infinite loop 2021-11-05 22:47:48 +01:00
jens 88cdc366c5 Changelogs 2021-11-04 18:01:30 +01:00
jens 2bd94e8a3d Changelogs 2021-11-03 15:30:49 +01:00
jens 074f75ed20 permission for play sound 2021-11-03 15:25:21 +01:00
jens d988e1f43d permission for play sound 2021-11-03 15:15:26 +01:00
jens 23502f52bb permission for play sound 2021-11-03 15:15:06 +01:00
jens 9a6083247f permission for play sound 2021-10-31 13:27:45 +01:00
jens ba2a340bdf permission for play sound 2021-10-28 17:58:55 +02:00
jens 9e2f7c16f6 vibrateWhenRinging 2021-10-09 02:19:34 +02:00
jens d042b3f35a Translations 2021-10-04 20:18:09 +02:00
jens 220d2d316e Fix in data switch 2021-10-03 21:38:33 +02:00
jens 4aa095e801 Fix in data switch 2021-10-03 21:20:47 +02:00
jens b5bd332ff5 data with root 2021-10-03 15:09:07 +02:00
jens 969937f8a0 vibrate for calls 2021-09-27 20:12:40 +02:00
jens e3598cc475 DND 2021-09-26 19:54:17 +02:00
jens e63d97be0c DND 2021-09-26 13:58:48 +02:00
jens e60fb1535a bugspray 2021-09-25 02:03:44 +02:00
jens 8563234db3 bugspray 2021-09-24 19:15:41 +02:00
jens 448942e4e8 bugspray 2021-09-20 19:58:11 +02:00
jens dcdb770d9f bugspray 2021-09-15 21:58:18 +02:00
jens b5040cedb3 var replacement 2021-09-14 17:56:45 +02:00
jens 423839fa43 Sound settings 2021-09-12 20:05:12 +02:00
jens a6edab75ce Location without Cell Radio 2021-09-07 17:30:45 +02:00
jens cb430b957f fixes 2021-09-07 10:01:30 +02:00
jens b6a0f6dd91 fixes 2021-09-02 17:56:17 +02:00
jens bc32cbc179 encoding related typos 2021-09-02 10:48:50 +02:00
jens d9cc604bdd gradle update 2021-09-01 21:28:36 +02:00
jens db21011b7f Notification fixed 2021-08-31 23:13:59 +02:00
jens dc35c8b7fb stacked notification almost fixed 2021-08-31 18:53:26 +02:00
jens 5a7cbfcdc9 Enabled http cleartext traffic 2021-08-21 11:48:04 +02:00
jens 913a37a320 disallow http again because wouldn't compile 2021-08-20 13:46:04 +02:00
jens 14655fe55d allow http 2021-08-20 13:25:36 +02:00
jens cfc145c6c4 allow http 2021-08-18 10:00:41 +02:00
jens 325bff305c Wifi fix 2021-08-14 14:11:19 +02:00
jens 4371fb56f7 Merge remote-tracking branch 'origin/master' into development 2021-08-14 01:55:50 +02:00
jens 6593f6c923 Compile fix 2021-08-14 01:53:48 +02:00
jens 7fbac92360 New release 2021-07-29 14:19:20 +02:00
jens 7415830dd7 New release 2021-07-29 14:14:20 +02:00
jens dce68d79bd New release 2021-07-29 14:05:57 +02:00
jens 397dadd8c7 Translation 2021-07-28 11:49:13 +02:00
jens c51c46707b Translation 2021-07-21 13:06:42 +02:00
jens d699285b5a Translation 2021-07-16 18:33:25 +02:00
jens cf3db22ffb Translation 2021-07-08 22:41:58 +02:00
jens f53abe2b23 TabLayout 2021-07-08 17:57:33 +02:00
jens ba2f96713d TabLayout 2021-07-07 21:01:43 +02:00
jens 21d9351b2b Translations 2021-07-07 12:52:26 +02:00
jens a8bfc6f7ec Vibrate pattern 2021-07-04 15:53:24 +02:00
jens 71d9791603 Vibrate pattern 2021-07-04 02:27:07 +02:00
jens d71177f3da Vibrate pattern 2021-07-04 02:14:26 +02:00
jens eef6c3234a Speed calculation 2021-07-03 02:42:24 +02:00
jens 192142c76b Translation 2021-07-02 10:46:25 +02:00
jens 9a2a0aa6a4 Encryption 2021-06-29 23:10:51 +02:00
jens c18a880ad7 Logging 2021-06-28 23:28:46 +02:00
jens a845ea7c63 v1.6.35 2021-06-24 22:38:12 +02:00
jens 2d9695344b Permission 2021-06-23 22:01:40 +02:00
jens 24d05e6d87 Location 2021-06-23 20:20:38 +02:00
jens 07b0513eae Permission 2021-06-20 23:45:02 +02:00
jens e445b787a9 Fixed cache problem after rule clone 2021-06-20 22:24:17 +02:00
jens 82156059fa Translations 2021-06-16 23:12:00 +02:00
jens b976ff95b6 Translations 2021-06-16 21:45:29 +02:00
jens a4b2745b7b Layout changes 2021-06-13 13:53:14 +02:00
jens 844be6a4a7 Manage POI 2021-06-12 18:56:03 +02:00
jens 49a48fc371 Manage POI 2021-06-12 14:02:10 +02:00
jens 722750b724 Translations. 2021-06-12 02:27:51 +02:00
jens ab51eb3655 POI management changes 2021-06-10 23:22:38 +02:00
jens 7b88e7a612 Automatic update check for APK version. 2021-06-09 22:41:47 +02:00
jens bb2f5c9842 Translations. 2021-06-09 19:59:31 +02:00
jens 883a7e8341 Translations. 2021-06-09 17:02:27 +02:00
jens bfc0e3ac4f Automatic update check for APK version. 2021-06-08 23:14:09 +02:00
jens 23ded3a851 Minor corrections. 2021-06-08 20:04:02 +02:00
jens 6d363fd02d Translations 2021-06-07 22:52:38 +02:00
jens 3c0f889db7 Minor corrections. 2021-06-07 20:02:42 +02:00
jens d018c27f0e Minor corrections. 2021-06-05 12:11:05 +02:00
jens 7e36f0f32e New release 2021-06-02 22:36:39 +02:00
jens 666129de16 New release 2021-06-02 22:29:07 +02:00
jens becdbd6546 Hunting crash in Fdroid version 2021-06-02 17:12:33 +02:00
jens d292988737 Hunting crash in Fdroid version 2021-06-01 20:07:15 +02:00
jens 21ee06e9b1 Wifi tethering without root above Oreo works again. 2021-05-30 20:03:30 +02:00
jens f22e4854ee Merge branch 'WifiRouter' into development
# Conflicts:
#	app/src/main/res/values-es/strings.xml
2021-05-30 12:28:59 +02:00
jens 7182698b8a Wifi tethering without root above Oreo works again. 2021-05-30 12:27:27 +02:00
jens 7fd8d1cfd0 Translation 2021-05-26 19:55:21 +02:00
jens 943928089b Translation 2021-05-22 23:12:40 +02:00
jens f70e45701f Wifirouter 2021-05-22 02:51:31 +02:00
jens 9b33f13f66 Italian translation updated 2021-05-21 19:52:36 +02:00
jens 2f3a33b1b8 Translation 2021-05-20 23:11:16 +02:00
jens 6c8ca59e3f Spanish translation 2021-05-19 21:06:15 +02:00
jens 5ffb36a87f Added read_phone_state for action setDataConnection 2021-05-18 22:30:01 +02:00
jens 1560fd3343 SuperSu related changes. 2021-05-18 20:02:45 +02:00
jens a0ff8c80f0 Spanish translation 2021-05-16 22:51:03 +02:00
jens 1ea3bdaea3 Permissions constants used. 2021-05-16 19:57:05 +02:00
jens f325b30917 Permissions constants used. 2021-05-16 19:51:22 +02:00
jens 8ce2a09b3b Wifi trigger mgmt change 2021-05-16 14:27:54 +02:00
jens 4a18a6ed19 Wifi trigger mgmt change 2021-05-16 02:32:31 +02:00
jens 9a8519d3e3 Phone Listener changed. 2021-05-15 19:55:48 +02:00
jens 0a0399c2b0 Phone Listener changed. 2021-05-15 14:22:43 +02:00
jens 3844079781 Phone Listener changed. 2021-05-15 02:27:59 +02:00
jens 191ad904a3 Phone Listener changed. 2021-05-14 20:07:46 +02:00
jens e988cedf7c Phone Listener changed. 2021-05-14 13:00:25 +02:00
jens 9a7f66fa22 PhoneCallTrigger 2021-05-13 23:50:14 +02:00
jens c926c85dd0 Phone Listener changed. 2021-05-13 18:37:34 +02:00
jens cddd8cfac5 Build 2021-05-13 14:44:29 +02:00
189 changed files with 14051 additions and 6894 deletions
+2
View File
@@ -148,3 +148,5 @@ fabric.properties
/app/app-release.apk
Automation_settings.xml
/app/googlePlayFlavor/
/.idea/deploymentTargetDropDown.xml
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>
+31 -30
View File
@@ -11,8 +11,8 @@ android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 104
versionName "1.6.33"
versionCode 116
versionName "1.7.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -36,41 +36,42 @@ android {
flavorDimensions "version"
productFlavors
{
googlePlayFlavor
{
dimension "version"
// applicationIdSuffix ".googlePlay"
versionNameSuffix "-googlePlay"
targetSdkVersion 29
}
{
googlePlayFlavor
{
dimension "version"
versionNameSuffix "-googlePlay"
targetSdkVersion 30
}
fdroidFlavor
{
dimension "version"
// applicationIdSuffix ".fdroid"
// versionNameSuffix "-fdroid"
targetSdkVersion 28
}
fdroidFlavor
{
dimension "version"
targetSdkVersion 28
}
apkFlavor
{
dimension "version"
// applicationIdSuffix ".apk"
versionNameSuffix "-apk"
targetSdkVersion 28
}
}
apkFlavor
{
dimension "version"
versionNameSuffix "-apk"
targetSdkVersion 28
}
}
}
dependencies {
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
implementation 'org.apache.commons:commons-lang3:3.0'
//implementation "androidx.security:security-crypto:1.0.0"
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
@@ -1,18 +1,20 @@
{
"version": 2,
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.jens.automation2",
"variantName": "processGooglePlayFlavorReleaseResources",
"variantName": "googlePlayFlavorRelease",
"elements": [
{
"type": "SINGLE",
"filters": [],
"versionCode": 102,
"versionName": "1.6.30-googlePlay",
"attributes": [],
"versionCode": 116,
"versionName": "1.7.2-googlePlay",
"outputFile": "app-googlePlayFlavor-release.apk"
}
]
],
"elementType": "File"
}
+28 -18
View File
@@ -51,6 +51,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@@ -64,6 +65,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-feature
android:name="android.hardware.telephony"
@@ -120,31 +122,39 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">
@@ -188,9 +198,10 @@
<activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityManageTriggerNotification"></activity>
<activity android:name=".ActivityManageTriggerNotification" />
<service
android:name=".receivers.NotificationListener"
@@ -202,6 +213,12 @@
</service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<service
android:name=".receivers.ActivityDetectionReceiver"
android:exported="false"
@@ -210,13 +227,6 @@
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name=".ActivityPermissions"></activity>
<!-- 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"/>
<service android:name=".location.GeofenceIntentService"/>
File diff suppressed because it is too large Load Diff
@@ -291,10 +291,10 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
if(allRulesWithActivityDetection.get(i).getsGreenLight(Miscellaneous.getAnyContext()))
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
}
}
+27 -18
View File
@@ -51,6 +51,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@@ -62,6 +63,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-feature
android:name="android.hardware.telephony"
@@ -118,31 +120,39 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">
@@ -169,6 +179,7 @@
</intent-filter>
-->
<!--
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
@@ -185,16 +196,9 @@
<activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<!-- 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"/>
<service android:name=".location.GeofenceIntentService"/>
<activity android:name=".ActivityManageTriggerNotification" />
<service
@@ -207,6 +211,11 @@
</service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<provider
android:name=".FileShareProvider"
android:authorities="com.jens.automation2"
File diff suppressed because it is too large Load Diff
+28 -18
View File
@@ -50,6 +50,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@@ -63,6 +64,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application
android:allowBackup="true"
@@ -112,31 +114,39 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">
@@ -180,9 +190,10 @@
<activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" />
<activity android:name=".ActivityManageTriggerWifi" />
<activity android:name=".ActivityVolumeTest" />
<activity android:name=".ActivityPermissions"></activity>
<activity android:name=".ActivityManageTriggerNotification"></activity>
<activity android:name=".ActivityManageTriggerNotification" />
<service
android:name=".receivers.NotificationListener"
@@ -194,6 +205,12 @@
</service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
<service
android:name=".receivers.ActivityDetectionReceiver"
android:exported="false"
@@ -202,13 +219,6 @@
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name=".ActivityPermissions"></activity>
<!-- 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"/>
<service android:name=".location.GeofenceIntentService"/>
File diff suppressed because it is too large Load Diff
@@ -301,7 +301,7 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
+156 -159
View File
@@ -2,10 +2,10 @@ package com.jens.automation2;
import android.content.Context;
import android.os.AsyncTask;
import android.text.style.TabStopSpan;
import android.util.Log;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import java.util.ArrayList;
@@ -14,14 +14,18 @@ import java.util.Locale;
public class Action
{
Rule parentRule = null;
public static final String actionParameter2Split = "ap2split";
public static final String intentPairSeperator = "intPairSplit";
public static final String vibrateSeparator = ",";
public enum Action_Enum {
setWifi,
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
@@ -29,16 +33,17 @@ public class Action
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation, disableScreenRotation,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
wakeupDevice,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
playMusic,
setScreenBrightness,
playSound,
vibrate,
sendTextMessage;
public String getFullName(Context context)
@@ -51,6 +56,8 @@ public class Action
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
@@ -83,8 +90,10 @@ public class Action
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case wakeupDevice:
return context.getResources().getString(R.string.wakeupDevice);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
return context.getResources().getString(R.string.airplaneMode);
case setDataConnection:
@@ -144,86 +153,93 @@ public class Action
public String toString()
{
StringBuilder returnString = new StringBuilder();
if(this.getAction().equals(Action_Enum.setWifi))
switch(getAction())
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
case setWifi:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
break;
case setBluetooth:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOff));
break;
case setUsbTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOff));
break;
case setWifiTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
break;
case setBluetoothTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOff));
break;
case setDisplayRotation:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionEnableScreenRotation));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionDisableScreenRotation));
break;
case setAirplaneMode:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOff));
break;
case setDataConnection:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOff));
break;
case startOtherActivity:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
break;
case triggerUrl:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
break;
case speakText:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
break;
case playMusic:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
break;
case sendTextMessage:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
break;
case turnScreenOnOrOff:
if (getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOff));
break;
case playSound:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playSound));
break;
case changeSoundProfile:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionChangeSoundProfile));
break;
case waitBeforeNextAction:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.waitBeforeNextAction));
break;
case setScreenBrightness:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setScreenBrightness));
break;
default:
returnString.append(action.toString());
}
else if(this.getAction().equals(Action_Enum.setBluetooth))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOff));
}
else if(this.getAction().equals(Action_Enum.setUsbTethering))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOff));
}
else if(this.getAction().equals(Action_Enum.setWifiTethering))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
}
else if(this.getAction().equals(Action_Enum.setDisplayRotation))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionEnableScreenRotation));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionDisableScreenRotation));
}
else if(this.getAction().equals(Action_Enum.setAirplaneMode))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOff));
}
else if(this.getAction().equals(Action_Enum.setDataConnection))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOff));
}
else if(this.getAction().equals(Action_Enum.startOtherActivity))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
}
else if(this.getAction().equals(Action_Enum.triggerUrl))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
}
else if(this.getAction().equals(Action_Enum.speakText))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
}
else if(this.getAction().equals(Action_Enum.playMusic))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
}
else if(this.getAction().equals(Action_Enum.sendTextMessage))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
}
else if(this.getAction().equals(Action_Enum.wakeupDevice))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wakeupDevice));
}
else if(this.getAction().equals(Action_Enum.playSound))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playSound));
}
else
returnString.append(action.toString());
if(this.getAction().equals(Action_Enum.triggerUrl))
{
@@ -233,7 +249,7 @@ public class Action
returnString.append(": " + components[2]);
if(parameter1)
returnString.append(" using authentication.");
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingAuthentication) + ".");
}
else
returnString.append(": " + components[0]);
@@ -247,14 +263,14 @@ public class Action
String[] components = parameter2.split(Actions.smsSeparator);
if(components.length >= 2)
{
returnString.append(" to number " + components[0]);
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.toNumber) + " " + components[0]);
returnString.append(". Message: " + components[1]);
returnString.append(". " + Miscellaneous.getAnyContext().getResources().getString(R.string.message) + ": " + components[1]);
}
}
else if(this.getAction().equals(Action_Enum.setScreenBrightness))
{
returnString.append(" to ");
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.to) + " ");
if(parameter1)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
@@ -270,6 +286,16 @@ public class Action
return returnString.toString();
}
public Rule getParentRule()
{
return parentRule;
}
public void setParentRule(Rule parentRule)
{
this.parentRule = parentRule;
}
public static CharSequence[] getActionTypesAsArray()
{
ArrayList<String> actionTypesList = new ArrayList<String>();
@@ -346,18 +372,11 @@ public class Action
* Old version. Those checks should not be necessary anymore. Also they didn't work
* because profiles were created with names like silent, vibrate and normal.
*/
// if(this.getParameter2().equals("silent"))
// Actions.setSound(context, AudioManager.RINGER_MODE_SILENT);
// else if(this.getParameter2().equals("vibrate"))
// Actions.setSound(context, AudioManager.RINGER_MODE_VIBRATE);
// else if(this.getParameter2().equals("normal"))
// Actions.setSound(context, AudioManager.RINGER_MODE_NORMAL);
// else
// {
Profile p = Profile.getByName(this.getParameter2());
if (p != null)
p.activate(context);
// }
break;
case triggerUrl:
triggerUrl(context);
@@ -369,11 +388,14 @@ public class Action
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setWifi:
Actions.setWifi(context, getParameter1(), toggleActionIfPossible);
Actions.WifiStuff.setWifi(context, getParameter1(), toggleActionIfPossible);
break;
case setWifiTethering:
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setBluetoothTethering:
Actions.BluetoothTetheringClass.setBluetoothTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setDisplayRotation:
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
break;
@@ -383,16 +405,26 @@ public class Action
case waitBeforeNextAction:
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
break;
case wakeupDevice:
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
// wakeupDevice() will create a seperate thread. That'll take some time, we wait 100ms.
try
case turnScreenOnOrOff:
if(getParameter1())
{
Thread.sleep(100);
if(StringUtils.isNumeric(this.getParameter2()))
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
else
Actions.wakeupDevice((long)1000);
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
else
{
e.printStackTrace();
Actions.turnOffScreen();
}
break;
case setAirplaneMode:
@@ -413,6 +445,9 @@ public class Action
case setScreenBrightness:
Actions.setScreenBrightness(getParameter1(), Integer.parseInt(getParameter2()));
break;
case vibrate:
Actions.vibrate(getParameter1(), getParameter2());
break;
case playSound:
Actions.playSound(getParameter1(), getParameter2());
break;
@@ -460,7 +495,7 @@ public class Action
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.errorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.logErrorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
}
}
@@ -491,62 +526,24 @@ public class Action
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
{
Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
// try
// {
// Either thorough checking or no encryption
if(!Settings.httpAcceptAllCertificates | !urlString.toLowerCase(Locale.getDefault()).contains("https"))
// {
// URL url = new URL(urlString);
// URLConnection urlConnection = url.openConnection();
// urlConnection.setReadTimeout(Settings.httpAttemptsTimeout * 1000);
// InputStream in = urlConnection.getInputStream();
// response = Miscellaneous.convertStreamToString(in);
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
// }
else
// {
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
// post = new HttpGet(new URI(urlString));
// final HttpParams httpParams = new BasicHttpParams();
// HttpConnectionParams.setConnectionTimeout(httpParams, Settings.httpAttemptsTimeout * 1000);
// HttpClient client = new DefaultHttpClient(httpParams);
//
// client = sslClient(client);
//
// // Execute HTTP Post Request
// HttpResponse result = client.execute(post);
// response = EntityUtils.toString(result.getEntity());
// }
// }
// catch (URISyntaxException e)
// {
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
// }
// catch (ClientProtocolException e)
// {
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
// }
// catch (IOException e)
// {
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
// e.printStackTrace();
// }
// finally
// {
try
{
Thread.sleep(Settings.httpAttemptGap * 1000);
}
catch (InterruptedException e1)
{
Miscellaneous.logEvent("w", "HTTP RESULT", "Failed to pause between HTTP requests.", 5);
}
// }
// Either thorough checking or no encryption
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
else
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
try
{
Thread.sleep(Settings.httpAttemptGap * 1000);
}
catch (InterruptedException e1)
{
Miscellaneous.logEvent("w", "HTTP RESULT", "Failed to pause between HTTP requests.", 5);
}
}
// Miscellaneous.logEvent("i", "HTTPS RESULT", response, 3);
Miscellaneous.logEvent("i", "HTTPS RESULT", response, 5);
return response;
}
File diff suppressed because it is too large Load Diff
@@ -9,7 +9,6 @@ import com.jens.automation2.R.layout;
public class ActivityHelp extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -19,5 +18,4 @@ public class ActivityHelp extends Activity
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -60,11 +61,11 @@ public class ActivityMainPoi extends ActivityGeneric
}
else
{
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
if (!ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, ActivityMainPoi.this) || !ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityMainPoi.this))
{
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine});
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION});
startActivityForResult(permissionIntent, requestCodeForPermission);
}
@@ -184,8 +184,16 @@ public class ActivityMainProfiles extends ActivityGeneric
startActivityForResult(manageSpecificProfileIntent, 2000);
break;
case 2:
if(profile.delete(myAutomationService))
updateListView();
Rule user = profile.isInUseByRules();
if(user == null)
{
if (profile.delete(ActivityMainProfiles.this))
updateListView();
else
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.profileCouldNotBeDeleted), Toast.LENGTH_LONG).show();
}
else
Toast.makeText(ActivityMainProfiles.this, String.format(getResources().getString(R.string.ruleXIsUsingProfileY), user.getName(), profile.getName()), Toast.LENGTH_LONG).show();
break;
}
}
@@ -19,17 +19,21 @@ import android.widget.TextView;
import android.widget.Toast;
import com.jens.automation2.AutomationService.serviceCommands;
import com.jens.automation2.receivers.AlarmListener;
import com.jens.automation2.receivers.DateTimeListener;
import java.util.ArrayList;
public class ActivityMainRules extends ActivityGeneric
{
private ListView ruleListView;
ArrayList<Rule> ruleList = new ArrayList<>();
private ArrayAdapter<Rule> ruleListViewAdapter;
public static Rule ruleToEdit;
protected static ActivityMainRules instance = null;
public static final int requestCodeCreateRule = 3000;
public static final int requestCodeChangeRule = 4000;
public static ActivityMainRules getInstance()
{
if(instance == null)
@@ -52,21 +56,14 @@ public class ActivityMainRules extends ActivityGeneric
@Override
public void onClick(View v)
{
// if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainRules.this))
// {
// Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
// return;
// }
ruleToEdit = null;
Intent startAddRuleIntent = new Intent(ActivityMainRules.this, ActivityManageRule.class);
startActivityForResult(startAddRuleIntent, 3000);
startActivityForResult(startAddRuleIntent, requestCodeCreateRule);
}
});
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, ruleList);
ruleListView = (ListView)findViewById(R.id.lvRuleList);
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, Rule.getRuleCollection());
ruleListView.setClickable(true);
ruleListView.setOnItemLongClickListener(new OnItemLongClickListener()
@@ -112,7 +109,6 @@ public class ActivityMainRules extends ActivityGeneric
private static class RuleArrayAdapter extends ArrayAdapter<Rule>
{
public RuleArrayAdapter(Context context, int resource, ArrayList<Rule> objects)
{
super(context, resource, objects);
@@ -163,13 +159,13 @@ public class ActivityMainRules extends ActivityGeneric
if(AutomationService.isMyServiceRunning(this))
bindToService();
if(requestCode == 3000) //add Rule
if(requestCode == requestCodeCreateRule) //add Rule
{
ruleToEdit = null; //clear cache
updateListView();
}
if(requestCode == 4000) //editRule
if(requestCode == requestCodeChangeRule) //editRule
{
ruleToEdit = null; //clear cache
updateListView();
@@ -190,7 +186,7 @@ public class ActivityMainRules extends ActivityGeneric
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithRule));
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital) }, new DialogInterface.OnClickListener()
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()
{
@Override
public void onClick(DialogInterface dialog, int which)
@@ -212,11 +208,22 @@ public class ActivityMainRules extends ActivityGeneric
case 1:
ruleToEdit = ruleThisIsAbout;
Intent manageSpecificRuleIntent = new Intent (ActivityMainRules.this, ActivityManageRule.class);
startActivityForResult(manageSpecificRuleIntent, 4000);
startActivityForResult(manageSpecificRuleIntent, requestCodeChangeRule);
break;
case 2:
if(ruleThisIsAbout.delete())
{
ruleToEdit = null; //clear cache
updateListView();
}
break;
case 3:
ruleToEdit = ruleThisIsAbout;
if(ruleToEdit.cloneRule(ActivityMainRules.this))
{
ruleToEdit = null; //clear cache
updateListView();
}
break;
}
}
@@ -229,6 +236,11 @@ public class ActivityMainRules extends ActivityGeneric
public void updateListView()
{
Miscellaneous.logEvent("i", "ListView", "Attempting to update RuleListView", 4);
ruleList.clear();
for(Rule r : Rule.getRuleCollection())
ruleList.add(r);
try
{
if(ruleListView.getAdapter() == null)
@@ -242,11 +254,11 @@ public class ActivityMainRules extends ActivityGeneric
try
{
if(AutomationService.isMyServiceRunning(this))
AlarmListener.reloadAlarms();
DateTimeListener.reloadAlarms();
}
catch(NullPointerException e)
{
// AlarmManager instance not prepared, yet.
}
}
}
}
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.PendingIntent;
@@ -28,6 +29,7 @@ import androidx.core.text.HtmlCompat;
import com.jens.automation2.AutomationService.serviceCommands;
import com.jens.automation2.Trigger.Trigger_Enum;
import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.LocationProvider;
import java.io.File;
@@ -42,8 +44,9 @@ public class ActivityMainScreen extends ActivityGeneric
private static ActivityMainScreen activityMainScreenInstance = null;
private ToggleButton toggleService, tbLockSound;
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme;
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme, bDonate;
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration;
private static boolean updateNoteDisplayed = false;
private ListView lvRuleHistory;
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
@@ -79,6 +82,12 @@ public class ActivityMainScreen extends ActivityGeneric
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
if(!BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
bDonate.setVisibility(View.VISIBLE);
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@@ -108,6 +117,18 @@ public class ActivityMainScreen extends ActivityGeneric
}
});
bDonate.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
String privacyPolicyUrl = "https://server47.de/donate";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
startActivity(browserIntent);
}
});
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
@@ -323,9 +344,9 @@ public class ActivityMainScreen extends ActivityGeneric
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, Miscellaneous.getAnyContext())
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, Miscellaneous.getAnyContext())
&&
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, Miscellaneous.getAnyContext())
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, Miscellaneous.getAnyContext())
)
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
else
@@ -406,6 +427,15 @@ public class ActivityMainScreen extends ActivityGeneric
else
activityMainScreenInstance.checkForNews();
if(BuildConfig.FLAVOR.equals("apkFlavor") && Settings.automaticUpdateCheck)
{
Calendar now = Calendar.getInstance();
if (Settings.lastUpdateCheck == Settings.default_lastUpdateCheck || now.getTimeInMillis() >= Settings.lastUpdateCheck + (long)(Settings.updateCheckFrequencyDays * 24 * 60 * 60 * 1000))
{
activityMainScreenInstance.checkForUpdate();
}
}
Settings.considerDone(Settings.constNewsOptInDone);
Settings.writeSettings(Miscellaneous.getAnyContext());
}
@@ -587,6 +617,15 @@ public class ActivityMainScreen extends ActivityGeneric
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
}
synchronized void checkForUpdate()
{
if(Settings.automaticUpdateCheck)
{
AsyncTasks.AsyncTaskUpdateCheck updateCheckTask = new AsyncTasks.AsyncTaskUpdateCheck();
updateCheckTask.execute(ActivityMainScreen.this);
}
}
synchronized void checkForNews()
{
if(Settings.displayNewsOnMainScreen)
@@ -616,4 +655,38 @@ public class ActivityMainScreen extends ActivityGeneric
Miscellaneous.logEvent("e", "Error displaying news", Log.getStackTraceString(e), 3);
}
}
public void processUpdateCheckResult(Boolean result)
{
if(result && !updateNoteDisplayed)
{
updateNoteDisplayed = true;
AlertDialog.Builder updateNoteBuilder = new AlertDialog.Builder(ActivityMainScreen.this);
updateNoteBuilder.setMessage(getResources().getString(R.string.updateAvailable));
updateNoteBuilder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
String url = "https://server47.de/automation/";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
updateNoteDisplayed = false;
}
});
updateNoteBuilder.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
updateNoteDisplayed = false;
}
});
updateNoteBuilder.show();
}
AsyncTasks.AsyncTaskUpdateCheck.checkRunning = false;
}
}
@@ -13,12 +13,17 @@ import com.jens.automation2.receivers.NfcReceiver;
@SuppressLint("NewApi")
public class ActivityMainTabLayout extends TabActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_tab_layout);
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
if(Settings.tabsPlacement == 1)
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
else
setContentView(R.layout.main_tab_layout_tabs_at_top);
TabHost tabHost = getTabHost();
@@ -67,4 +72,4 @@ public class ActivityMainTabLayout extends TabActivity
// setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent);
}
}
}
@@ -16,6 +16,8 @@ import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.documentfile.provider.DocumentFile;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
@@ -27,7 +29,7 @@ public class ActivityMaintenance extends Activity
final static String prefsFileName = "com.jens.automation2_preferences.xml";
TextView tvFileStoreLocation;
TextView tvFileStoreLocation, tvAppVersion;
Button bVolumeTest, bMoreSettings, bSettingsSetToDefault, bShareConfigAndLog, bImportConfiguration, bExportConfiguration;
@Override
@@ -101,6 +103,13 @@ public class ActivityMaintenance extends Activity
});
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
tvAppVersion = (TextView)findViewById(R.id.tvAppVersion);
tvAppVersion.setText(
"Version: " + BuildConfig.VERSION_NAME + Miscellaneous.lineSeparator +
"Version code: " + String.valueOf(BuildConfig.VERSION_CODE) + Miscellaneous.lineSeparator +
"Flavor: " + BuildConfig.FLAVOR
);
}
@Override
@@ -192,6 +201,9 @@ public class ActivityMaintenance extends Activity
try
{
XmlFileInterface.readFile();
ActivityMainPoi.getInstance().updateListView();
ActivityMainRules.getInstance().updateListView();
ActivityMainProfiles.getInstance().updateListView();
}
catch (Exception e)
{
@@ -221,10 +233,17 @@ public class ActivityMaintenance extends Activity
// Clean up
for(DocumentFile file : directory.listFiles())
{
if(file.getName().equals(XmlFileInterface.settingsFileName) && file.canWrite())
file.delete();
else if(file.getName().equals(prefsFileName) && file.canWrite())
file.delete();
/*
On some few users' devices it seems this caused a crash because file.getName() was null.
The reason for that remains unknown, but we don't want the export to crash because of it.
*/
if(!StringUtils.isEmpty(file.getName()))
{
if (file.getName().equals(XmlFileInterface.settingsFileName) && file.canWrite())
file.delete();
else if (file.getName().equals(prefsFileName) && file.canWrite())
file.delete();
}
}
DocumentFile dstRules = directory.createFile("text/xml", XmlFileInterface.settingsFileName);
@@ -298,17 +317,9 @@ public class ActivityMaintenance extends Activity
String subject = "Automation logs";
StringBuilder emailBody = new StringBuilder();
emailBody.append("Device details" + Miscellaneous.lineSeparator);
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
emailBody.append("Product: " + android.os.Build.PRODUCT);
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), uri);
}
});
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
@@ -317,6 +328,19 @@ public class ActivityMaintenance extends Activity
return alertDialog;
}
public static String getSystemInfo()
{
StringBuilder systemInfoText = new StringBuilder();
systemInfoText.append("Device details" + Miscellaneous.lineSeparator);
systemInfoText.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
systemInfoText.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
systemInfoText.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
systemInfoText.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
systemInfoText.append("Product: " + android.os.Build.PRODUCT + Miscellaneous.lineSeparator);
systemInfoText.append("Flavor: " + BuildConfig.FLAVOR);
return systemInfoText.toString();
}
@Override
protected void onResume()
{
@@ -8,7 +8,6 @@ import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
@@ -27,7 +26,7 @@ public class ActivityManageActionPlaySound extends Activity
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_play_sound);
setContentView(R.layout.activity_manage_action_play_sound);
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
etSelectedSoundFile = (EditText)findViewById(R.id.etSelectedSoundFile);
@@ -25,6 +25,7 @@ public class ActivityManageActionSendTextMessage extends Activity
EditText etPhoneNumber, etSendTextMessage;
protected final static int requestCodeForContactsPermissions = 9876;
protected final static int requestCodeGetContact = 3235;
// private String existingUrl = "";
@@ -35,7 +36,7 @@ public class ActivityManageActionSendTextMessage extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.send_textmessage_editor);
this.setContentView(R.layout.activity_manage_action_send_textmessage);
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
etPhoneNumber = (EditText)findViewById(R.id.etPhoneNumber);
@@ -58,7 +59,7 @@ public class ActivityManageActionSendTextMessage extends Activity
backToRuleManager();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
}
});
@@ -83,20 +84,10 @@ public class ActivityManageActionSendTextMessage extends Activity
etPhoneNumber.setText(parameters[0]);
etSendTextMessage.setText(parameters[1]);
}
// String url = getIntent().getStringExtra("urlToTrigger");
// if(url != null)
// existingUrl = url;
}
private void backToRuleManager()
{
// Intent returnIntent = new Intent();
// returnIntent.putExtra("urlToTrigger", existingUrl);
// setResult(RESULT_OK, returnIntent);
if(edit && resultingAction != null)
{
ActivityManageActionSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
@@ -145,16 +136,14 @@ public class ActivityManageActionSendTextMessage extends Activity
private void openContactsDialogue()
{
// Toast.makeText(ActivityEditSendTextMessage.this, "Opening contacts dialogue", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, 1000);
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, requestCodeGetContact);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == 1000)
if(requestCode == requestCodeGetContact)
{
if(resultCode == Activity.RESULT_OK)
{
@@ -24,7 +24,7 @@ public class ActivityManageActionSpeakText extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.speak_text_editor);
this.setContentView(R.layout.activity_manage_action_speak_text);
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl);
@@ -44,7 +44,7 @@ public class ActivityManageActionSpeakText extends Activity
backToRuleManager();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
}
});
@@ -230,44 +230,89 @@ public class ActivityManageActionStartActivity extends Activity
return null;
}
private AlertDialog getActionStartActivityDialog1()
private AlertDialog getActionStartActivityDialog1Application()
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
final String[] applicationArray = ActivityManageActionStartActivity.getApplicationNameListString(this);
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
{
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
getActionStartActivityDialog2(applicationArray[which]).show();
getActionStartActivityDialog2(applicationArray[which]);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
private AlertDialog getActionStartActivityDialog2(String applicationName)
private void getActionStartActivityDialog2(String applicationName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
final String[] packageArray = ActivityManageActionStartActivity.getPackageListString(this, applicationName);
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
{
if(packageArray.length > 1)
{
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog4ActivityPickMethod(packageArray[which]).show();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
else
{
getActionStartActivityDialog4ActivityPickMethod(packageArray[0]).show();
}
}
private AlertDialog getActionStartActivityDialog4ActivityPickMethod(final String packageName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage(getResources().getString(R.string.launcherOrManualExplanation));
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.takeLauncherActivity), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog3(packageArray[which]).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
// Pick the launcher automatically
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (launchIntent != null)
{
ActivityInfo ai = ActivityManageActionStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, launchIntent.getComponent().getClassName());
etPackageName.setText(ai.packageName);
etActivityOrActionPath.setText(ai.name);
}
else
{
getActionStartActivityDialog5Activity(packageName).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.launcherNotFound) + Miscellaneous.lineSeparator + getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
}
}
});
alertDialogBuilder.setNegativeButton(getResources().getString(R.string.pickActivityManually), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog5Activity(packageName).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
}
});
final String activityArray[] = ActivityManageActionStartActivity.getActivityListForPackageName(packageName);
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
private AlertDialog getActionStartActivityDialog3(final String packageName)
private AlertDialog getActionStartActivityDialog5Activity(final String packageName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
@@ -283,7 +328,6 @@ public class ActivityManageActionStartActivity extends Activity
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
@@ -598,7 +642,6 @@ public class ActivityManageActionStartActivity extends Activity
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
@@ -615,9 +658,7 @@ public class ActivityManageActionStartActivity extends Activity
protected void onPostExecute(Void result)
{
progressDialog.dismiss();
getActionStartActivityDialog1().show();
getActionStartActivityDialog1Application().show();
}
}
}
}
@@ -39,7 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.trigger_url_editor);
this.setContentView(R.layout.activity_manage_action_trigger_url);
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
etTriggerUrlUsername = (EditText)findViewById(R.id.etTriggerUrlUsername);
@@ -0,0 +1,85 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageActionVibrate extends Activity
{
TextView etVibratePattern;
Button bTestVibratePattern, bSaveVibratePattern;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_vibrate);
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
bTestVibratePattern = (Button)findViewById(R.id.bTestVibratePattern);
bSaveVibratePattern = (Button)findViewById(R.id.bSaveVibratePattern);
bSaveVibratePattern.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if(checkInput())
{
Intent answer = new Intent();
answer.putExtra("vibratePattern", etVibratePattern.getText().toString());
setResult(RESULT_OK, answer);
finish();
}
}
});
bTestVibratePattern.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(checkInput())
{
if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this))
{
String pattern = etVibratePattern.getText().toString();
Actions.vibrate(false, pattern);
}
}
}
});
Intent input = getIntent();
if(input.hasExtra("vibratePattern"))
etVibratePattern.setText(input.getStringExtra("vibratePattern"));
}
boolean checkInput()
{
String vibratePattern = etVibratePattern.getText().toString();
String regex = "^[0-9,]+$";
if(StringUtils.isEmpty(vibratePattern) || !vibratePattern.matches(regex) || vibratePattern.substring(0, 1).equals(",") || vibratePattern.substring(vibratePattern.length()-1).equals(","))
{
Toast.makeText(ActivityManageActionVibrate.this, getResources().getString(R.string.pleaseEnterValidVibrationPattern), Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
}
@@ -13,6 +13,7 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
@@ -21,6 +22,12 @@ import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.jens.automation2.receivers.ConnectivityReceiver;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class ActivityManagePoi extends Activity
{
public LocationManager myLocationManager;
@@ -31,6 +38,11 @@ public class ActivityManagePoi extends Activity
Button bGetPosition, bSavePoi;
ImageButton ibShowOnMap;
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
Calendar locationSearchStart = null;
Timer timer = null;
final static int defaultRadius = 250;
final static int searchTimeout = 120;
private static ProgressDialog progressDialog;
@@ -47,7 +59,7 @@ public class ActivityManagePoi extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.manage_specific_poi);
this.setContentView(R.layout.activity_manage_specific_poi);
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
bGetPosition = (Button)findViewById(R.id.bGetPosition);
@@ -104,7 +116,7 @@ public class ActivityManagePoi extends Activity
myLocationManager.removeUpdates(myLocationListenerGps);
ActivityMainPoi.poiToEdit = new PointOfInterest();
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
if(loadFormValuesToVariable())
if(loadFormValuesToVariable(false))
if(ActivityMainPoi.poiToEdit.create(this))
{
this.setResult(RESULT_OK);
@@ -114,7 +126,7 @@ public class ActivityManagePoi extends Activity
private void changePoi()
{
myLocationManager.removeUpdates(myLocationListenerGps);
if(loadFormValuesToVariable())
if(loadFormValuesToVariable(false))
if(ActivityMainPoi.poiToEdit.change(this))
{
this.setResult(RESULT_OK);
@@ -150,47 +162,142 @@ public class ActivityManagePoi extends Activity
}
else
{
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider1, 3);
myLocationManager.requestLocationUpdates(provider1, 500, Settings.satisfactoryAccuracyNetwork, myLocationListenerNetwork);
locationSearchStart = Calendar.getInstance();
startTimeout();
if(!Settings.privacyLocationing || !ConnectivityReceiver.isDataConnectionAvailable(AutomationService.getInstance()))
{
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider1, 3);
myLocationManager.requestLocationUpdates(provider1, 500, Settings.satisfactoryAccuracyNetwork, myLocationListenerNetwork);
}
else
Miscellaneous.logEvent("i", "POI Manager", "Skipping network location query because private locationing is active.", 4);
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider2, 3);
myLocationManager.requestLocationUpdates(provider2, 500, Settings.satisfactoryAccuracyGps, myLocationListenerGps);
}
}
private void compareLocations()
private void startTimeout()
{
if(timer != null)
stopTimeout();
timer = new Timer();
class TimeoutTask extends TimerTask
{
public void run()
{
evaluateLocationResults();
}
}
Miscellaneous.logEvent("i", "POI Manager", "Starting timeout for location search: " + String.valueOf(searchTimeout) + " seconds", 5);
TimerTask timeoutTask = new TimeoutTask();
timer.schedule(timeoutTask, searchTimeout * 1000);
}
private void stopTimeout()
{
Miscellaneous.logEvent("i", "POI Manager", "Stopping timeout for location search.", 5);
if(timer != null)
{
timer.purge();
timer.cancel();
}
}
private void evaluateLocationResults()
{
/*
Procedure:
If we get a GPS result we take it and suggest a default minimum radius.
If private locationing is active that's the only possible outcome other than a timeout.
If private locationing is not active
If we get a network
*/
// We have GPS
if(locationGps != null)
{
myLocationManager.removeUpdates(myLocationListenerNetwork);
guiPoiLatitude.setText(String.valueOf(locationGps.getLatitude()));
guiPoiLongitude.setText(String.valueOf(locationGps.getLongitude()));
String text;
if(locationNetwork != null)
{
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.comparing), 4);
double variance = locationGps.distanceTo(locationNetwork);
String text = getResources().getString(R.string.distanceBetween) + " " + String.valueOf(Math.round(variance)) + " " + getResources().getString(R.string.radiusSuggestion);
// Toast.makeText(getBaseContext(), text, Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "POI Manager", text, 4);
// if(variance > 50 && guiPoiRadius.getText().toString().length()>0 && Integer.parseInt(guiPoiRadius.getText().toString())<variance)
// {
// String text = "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.";
getDialog(text, Math.round(variance) + 1).show();
// Toast.makeText(getBaseContext(), "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.", Toast.LENGTH_LONG).show();
// }
text = String.format(getResources().getString(R.string.distanceBetween), Math.round(variance));
getRadiusConfirmationDialog(text, Math.round(variance) + 1).show();
}
else
{
progressDialog.dismiss();
myLocationManager.removeUpdates(myLocationListenerNetwork);
guiPoiRadius.setText("250");
text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
getRadiusConfirmationDialog(text, defaultRadius).show();
}
Miscellaneous.logEvent("i", "POI Manager", text, 4);
} // we have a great network signal:
else if(locationNetwork != null && locationNetwork.getAccuracy() <= Settings.satisfactoryAccuracyGps && locationNetwork.getAccuracy() <= defaultRadius)
{
/*
We do not yet have a GPS result. But we have a network result that is good enough
to accept it a sole result. In that case we suggest a default radius, no variance.
*/
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
String text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
Miscellaneous.logEvent("i", "POI Manager", text, 4);
getRadiusConfirmationDialog(text, defaultRadius).show();
}
else if( // we have a bad network signal and nothing else, GPS result may still come in
locationNetwork != null
&&
Calendar.getInstance().getTimeInMillis()
<
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
)
{
// Only a network location was found and it is also not very accurate.
}
else if( // we have a bad network signal and nothing else, timeout has expired, nothing else can possibly come in
locationNetwork != null
&&
Calendar.getInstance().getTimeInMillis()
>
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
)
{
// Only a network location was found and it is also not very accurate.
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
String text = String.format(getResources().getString(R.string.locationFoundInaccurate), defaultRadius);
getRadiusConfirmationDialog(text, defaultRadius).show();
Miscellaneous.logEvent("i", "POI Manager", text, 4);
}
else
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logNotAllMeasurings), 4);
{
String text = String.format(getResources().getString(R.string.noLocationCouldBeFound), String.valueOf(searchTimeout));
Miscellaneous.logEvent("i", "POI Manager", text, 2);
if(myLocationListenerNetwork != null)
myLocationManager.removeUpdates(myLocationListenerNetwork);
myLocationManager.removeUpdates(myLocationListenerGps);
progressDialog.dismiss();
getErrorDialog(text).show();
}
}
private AlertDialog getNotificationDialog(String text)
@@ -202,15 +309,6 @@ public class ActivityManagePoi extends Activity
@Override
public void onClick(DialogInterface dialog, int which)
{
// switch(which)
// {
// case DialogInterface.BUTTON_POSITIVE:
// guiPoiRadius.setText(String.valueOf(value));
// break;
// case DialogInterface.BUTTON_NEGATIVE:
// break;
// }
progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
getLocation();
}
@@ -221,8 +319,11 @@ public class ActivityManagePoi extends Activity
return alertDialog;
}
private AlertDialog getDialog(String text, final double value)
private AlertDialog getRadiusConfirmationDialog(String text, final double value)
{
stopTimeout();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
@@ -247,10 +348,31 @@ public class ActivityManagePoi extends Activity
return alertDialog;
}
private AlertDialog getErrorDialog(String text)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
progressDialog.dismiss();
}
};
alertDialogBuilder.setMessage(text);
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.ok), null);
if (Looper.myLooper() == null)
Looper.prepare();
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
public class MyLocationListenerGps implements LocationListener
{
@Override
public void onLocationChanged(Location location)
{
@@ -260,10 +382,11 @@ public class ActivityManagePoi extends Activity
// {
// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from GPS location updates.", 5);
myLocationManager.removeUpdates(this);
locationGps = location;
compareLocations();
evaluateLocationResults();
// }
}
@@ -287,66 +410,27 @@ public class ActivityManagePoi extends Activity
// TODO Auto-generated method stub
}
}
// public class MyLocationListenerWifi implements LocationListener
// {
//
// @Override
// public void onLocationChanged(Location location)
// {
// Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.gotGpsUpdate) + " " + String.valueOf(location.getAccuracy()));
// // Deactivate when accuracy reached
//// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
//// {
//// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
//
// myLocationManager.removeUpdates(this);
// locationGps = location;
//
// compareLocations();
//// }
// }
//
// @Override
// public void onProviderDisabled(String provider)
// {
// // TODO Auto-generated method stub
//
// }
//
// @Override
// public void onProviderEnabled(String provider)
// {
// // TODO Auto-generated method stub
//
// }
//
// @Override
// public void onStatusChanged(String provider, int status, Bundle extras)
// {
// // TODO Auto-generated method stub
//
// }
//
// }
public class MyLocationListenerNetwork implements LocationListener
{
@Override
public void onLocationChanged(Location location)
{
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGotNetworkUpdate) + " " + String.valueOf(location.getAccuracy()), 3);
myLocationManager.removeUpdates(this);
locationNetwork = location;
// Deactivate when accuracy reached
// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
// {
// String text = "Network position found. satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_NETWORK) + "m reached. Removing location updates...";
// Miscellaneous.logEvent("i", "POI Manager", text);
myLocationManager.removeUpdates(this);
locationNetwork = location;
compareLocations();
// }
if(location.getAccuracy() <= Settings.satisfactoryAccuracyGps)
{
// Accuracy is so good that we don't need to wait for GPS result
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from network location updates.", 5);
myLocationManager.removeUpdates(myLocationListenerGps);
}
evaluateLocationResults();
}
@Override
@@ -369,7 +453,6 @@ public class ActivityManagePoi extends Activity
// TODO Auto-generated method stub
}
}
public void editPoi(PointOfInterest poi)
@@ -380,19 +463,22 @@ public class ActivityManagePoi extends Activity
guiPoiRadius.setText(String.valueOf(poi.getRadius()));
}
public boolean loadFormValuesToVariable()
public boolean loadFormValuesToVariable(boolean checkOnlyCoordinates)
{
if(ActivityMainPoi.poiToEdit == null)
ActivityMainPoi.poiToEdit = new PointOfInterest();
if(guiPoiName.getText().length() == 0)
if(!checkOnlyCoordinates)
{
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
return false;
if (guiPoiName.getText().length() == 0)
{
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
return false;
}
else
ActivityMainPoi.poiToEdit.setName(guiPoiName.getText().toString());
}
else
ActivityMainPoi.poiToEdit.setName(guiPoiName.getText().toString());
if(ActivityMainPoi.poiToEdit.getLocation() == null)
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
@@ -415,28 +501,31 @@ public class ActivityManagePoi extends Activity
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidLongitude), Toast.LENGTH_LONG).show();
return false;
}
try
if(!checkOnlyCoordinates)
{
ActivityMainPoi.poiToEdit.setRadius(Double.parseDouble(guiPoiRadius.getText().toString()), this);
try
{
ActivityMainPoi.poiToEdit.setRadius(Double.parseDouble(guiPoiRadius.getText().toString()), this);
}
catch (NumberFormatException e)
{
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidRadius), Toast.LENGTH_LONG).show();
return false;
}
catch (Exception e)
{
Toast.makeText(this, getResources().getString(R.string.unknownError), Toast.LENGTH_LONG).show();
return false;
}
}
catch(NumberFormatException e)
{
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidRadius), Toast.LENGTH_LONG).show();
return false;
}
catch (Exception e)
{
Toast.makeText(this, getResources().getString(R.string.unknownError), Toast.LENGTH_LONG).show();
return false;
}
return true;
}
private void showOnMap()
{
if(loadFormValuesToVariable())
if(loadFormValuesToVariable(true))
{
try
{
@@ -1,6 +1,7 @@
package com.jens.automation2;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -37,8 +38,8 @@ public class ActivityManageProfile extends Activity
final static int intentCodeRingtonePickerNotificationsFile = 9020;
final static int intentCodeRingtonePickerNotificationsRingtone = 9021;
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback;
Spinner spinnerSoundMode;
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback, checkBoxChangeDnd;
Spinner spinnerSoundMode, spinnerDndMode;
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms;
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
TextView tvIncomingCallsRingtone, tvNotificationsRingtone;
@@ -47,6 +48,7 @@ public class ActivityManageProfile extends Activity
File incomingCallsRingtone = null, notificationsRingtone = null;
ArrayAdapter<String> soundModeAdapter;
ArrayAdapter<String> dndModeAdapter;
public void setIncomingCallsRingtone(File incomingCallsRingtone)
{
@@ -82,9 +84,10 @@ public class ActivityManageProfile extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.manage_specific_profile);
this.setContentView(R.layout.activity_manage_specific_profile);
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
checkBoxChangeDnd = (CheckBox)findViewById(R.id.checkBoxChangeDnd);
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications);
checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms);
@@ -99,6 +102,7 @@ public class ActivityManageProfile extends Activity
checkBoxHapticFeedback = (CheckBox)findViewById(R.id.checkBoxHapticFeedback);
checkBoxVibrateWhenRinging = (CheckBox)findViewById(R.id.checkBoxVibrateWhenRinging);
spinnerSoundMode = (Spinner)findViewById(R.id.spinnerSoundMode);
spinnerDndMode = (Spinner)findViewById(R.id.spinnerDndMode);
seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic);
seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications);
seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms);
@@ -114,6 +118,7 @@ public class ActivityManageProfile extends Activity
checkBoxScreenLockUnlockSound.setEnabled(false);
checkBoxHapticFeedback.setEnabled(false);
spinnerSoundMode.setEnabled(false);
spinnerDndMode.setEnabled(false);
seekBarVolumeMusic.setEnabled(false);
seekBarVolumeNotifications.setEnabled(false);
seekBarVolumeAlarms.setEnabled(false);
@@ -121,6 +126,14 @@ public class ActivityManageProfile extends Activity
bChangeSoundNotifications.setEnabled(false);
spinnerSoundMode.setSelection(0);
spinnerDndMode.setSelection(0);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
{
// Disable DND controls
checkBoxChangeDnd.setEnabled(false);
spinnerDndMode.setEnabled(false);
}
// Scale SeekBars to the system's maximum volume values
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
@@ -128,8 +141,30 @@ public class ActivityManageProfile extends Activity
seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM));
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[] { getResources().getString(R.string.soundModeSilent), getResources().getString(R.string.soundModeVibrate), getResources().getString(R.string.soundModeNormal) });
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[]
{
getResources().getString(R.string.soundModeSilent),
getResources().getString(R.string.soundModeVibrate),
getResources().getString(R.string.soundModeNormal)
});
spinnerSoundMode.setAdapter(soundModeAdapter);
dndModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[]
{
getResources().getString(R.string.dndOff),
getResources().getString(R.string.dndPriority),
getResources().getString(R.string.dndNothing),
getResources().getString(R.string.dndAlarms)
});
spinnerDndMode.setAdapter(dndModeAdapter);
/*
Order in spinner: 1, 2, 4, 3
NotificationManager.INTERRUPTION_FILTER_UNKNOWN -> Returned when the value is unavailable for any reason.
NotificationManager.INTERRUPTION_FILTER_ALL -> 1 -> Normal interruption filter - no notifications are suppressed. -> essentially turn off DND
NotificationManager.INTERRUPTION_FILTER_PRIORITY -> 2 -> Priority interruption filter - all notifications are suppressed except those that match the priority criteria.
NotificationManager.INTERRUPTION_FILTER_ALARMS -> 4 -> Alarms only interruption filter - all notifications except those of category
NotificationManager.INTERRUPTION_FILTER_NONE -> 3 -> No interruptions filter - all notifications are suppressed and all audio streams (except those used for phone calls) and vibrations are muted.
*/
checkBoxChangeSoundMode.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@@ -139,6 +174,14 @@ public class ActivityManageProfile extends Activity
spinnerSoundMode.setEnabled(isChecked);
}
});
checkBoxChangeDnd.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
spinnerDndMode.setEnabled(isChecked);
}
});
checkBoxChangeVolumeMusicVideoGameMedia.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
@@ -327,6 +370,7 @@ public class ActivityManageProfile extends Activity
{
etName.setText(ActivityMainProfiles.profileToEdit.getName());
checkBoxChangeSoundMode.setChecked(ActivityMainProfiles.profileToEdit.getChangeSoundMode());
checkBoxChangeDnd.setChecked(ActivityMainProfiles.profileToEdit.getChangeDndMode());
checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia());
checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications());
checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms());
@@ -338,6 +382,7 @@ public class ActivityManageProfile extends Activity
checkBoxChangeVibrateWhenRinging.setChecked(ActivityMainProfiles.profileToEdit.getChangeVibrateWhenRinging());
spinnerSoundMode.setSelection(ActivityMainProfiles.profileToEdit.getSoundMode());
spinnerDndMode.setSelection(ActivityMainProfiles.profileToEdit.getDndMode()-1);
seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic());
seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications());
seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms());
@@ -359,6 +404,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setName(etName.getText().toString());
ActivityMainProfiles.profileToEdit.setChangeSoundMode(checkBoxChangeSoundMode.isChecked());
ActivityMainProfiles.profileToEdit.setChangeDndMode(checkBoxChangeDnd.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked());
ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked());
@@ -374,6 +420,7 @@ public class ActivityManageProfile extends Activity
ActivityMainProfiles.profileToEdit.setHapticFeedback(checkBoxHapticFeedback.isChecked());
ActivityMainProfiles.profileToEdit.setVibrateWhenRinging(checkBoxVibrateWhenRinging.isChecked());
ActivityMainProfiles.profileToEdit.setSoundMode(spinnerSoundMode.getSelectedItemPosition());
ActivityMainProfiles.profileToEdit.setDndMode(spinnerDndMode.getSelectedItemPosition()+1);
ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress());
ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress());
@@ -401,21 +448,23 @@ public class ActivityManageProfile extends Activity
}
if(!checkBoxChangeSoundMode.isChecked()
&
&&
!checkBoxChangeDnd.isChecked()
&&
!checkBoxChangeVolumeMusicVideoGameMedia.isChecked()
&
&&
!checkBoxChangeVolumeNotifications.isChecked()
&
&&
!checkBoxChangeVolumeAlarms.isChecked()
&
&&
!checkBoxChangeIncomingCallsRingtone.isChecked()
&
&&
!checkBoxChangeNotificationRingtone.isChecked()
&
&&
!checkBoxChangeAudibleSelection.isChecked()
&
&&
!checkBoxChangeScreenLockUnlockSound.isChecked()
&
&&
!checkBoxChangeHapticFeedback.isChecked()
)
{
File diff suppressed because it is too large Load Diff
@@ -29,7 +29,7 @@ public class ActivityManageTriggerBluetooth extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_trigger);
setContentView(R.layout.activity_manage_trigger_bluetooth);
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
radioNoDevice = (RadioButton)findViewById(R.id.radioNoDevice);
@@ -0,0 +1,297 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.jens.automation2.receivers.DeviceOrientationListener;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerDeviceOrientation extends Activity
{
TextView currentAzimuth, currentPitch, currentRoll, tvAppliesAzimuth, tvAppliesPitch, tvAppliesRoll;
Button bApplyPositionValues, bSavePositionValues;
EditText etDesiredAzimuth, etDesiredAzimuthTolerance, etDesiredPitch, etDesiredPitchTolerance, etDesiredRoll, etDesiredRollTolerance;
CheckBox chkDevicePositionApplies;
public static String vectorFieldName = "deviceVector";
boolean editMode = false;
float desiredAzimuth, desiredPitch, desiredRoll, desiredAzimuthTolerance, desiredPitchTolerance, desiredRollTolerance;
public void updateFields(float azimuth, float pitch, float roll)
{
currentAzimuth.setText(Float.toString(azimuth));
currentPitch.setText(Float.toString(pitch));
currentRoll.setText(Float.toString(roll));
try
{
desiredAzimuth = Float.parseFloat(etDesiredAzimuth.getText().toString());
desiredAzimuthTolerance = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
if (desiredAzimuthTolerance == 180 || (desiredAzimuth - desiredAzimuthTolerance <= azimuth && azimuth <= desiredAzimuth + desiredAzimuthTolerance))
{
tvAppliesAzimuth.setText(getResources().getString(R.string.yes));
tvAppliesAzimuth.setTextColor(Color.GREEN);
}
else
{
tvAppliesAzimuth.setText(getResources().getString(R.string.no));
tvAppliesAzimuth.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesAzimuth.setText("");
}
try
{
desiredPitch = Float.parseFloat(etDesiredPitch.getText().toString());
desiredPitchTolerance = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
if (desiredPitchTolerance == 180 || (desiredPitch - desiredPitchTolerance <= pitch && pitch <= desiredPitch + desiredPitchTolerance))
{
tvAppliesPitch.setText(getResources().getString(R.string.yes));
tvAppliesPitch.setTextColor(Color.GREEN);
}
else
{
tvAppliesPitch.setText(getResources().getString(R.string.no));
tvAppliesPitch.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesPitch.setText("");
}
try
{
desiredRoll = Float.parseFloat(etDesiredRoll.getText().toString());
desiredRollTolerance = Float.parseFloat(etDesiredRollTolerance.getText().toString());
if (desiredRollTolerance == 180 || (desiredRoll - desiredRollTolerance <= roll && roll <= desiredRoll + desiredRollTolerance))
{
tvAppliesRoll.setText(getResources().getString(R.string.yes));
tvAppliesRoll.setTextColor(Color.GREEN);
}
else
{
tvAppliesRoll.setText(getResources().getString(R.string.no));
tvAppliesRoll.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesRoll.setText("");
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_device_orientation);
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
currentPitch = (TextView) findViewById(R.id.tvCurrentOrientationPitch);
currentRoll = (TextView) findViewById(R.id.tvCurrentRoll);
tvAppliesAzimuth = (TextView) findViewById(R.id.tvAppliesAzimuth);
tvAppliesPitch = (TextView) findViewById(R.id.tvAppliesPitch);
tvAppliesRoll = (TextView) findViewById(R.id.tvAppliesRoll);
bApplyPositionValues = (Button) findViewById(R.id.bApplyPositionValues);
bSavePositionValues = (Button) findViewById(R.id.bSavePositionValues);
etDesiredAzimuth = (EditText) findViewById(R.id.etDesiredAzimuth);
etDesiredAzimuthTolerance = (EditText) findViewById(R.id.etDesiredAzimuthTolerance);
etDesiredPitch = (EditText) findViewById(R.id.etDesiredPitch);
etDesiredPitchTolerance = (EditText) findViewById(R.id.etDesiredPitchTolerance);
etDesiredRoll = (EditText) findViewById(R.id.etDesiredRoll);
etDesiredRollTolerance = (EditText) findViewById(R.id.etDesiredRollTolerance);
chkDevicePositionApplies = (CheckBox)findViewById(R.id.chkDevicePositionApplies);
// etDesiredAzimuth.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredPitch.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredRoll.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
etDesiredAzimuthTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredPitchTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredRollTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
if(getIntent().hasExtra(vectorFieldName))
{
editMode = true;
try
{
boolean chkValue = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true);
chkDevicePositionApplies.setChecked(chkValue);
String values[] = getIntent().getStringExtra(vectorFieldName).split(Trigger.triggerParameter2Split);
etDesiredAzimuth.setText(values[0]);
etDesiredAzimuthTolerance.setText(values[1]);
etDesiredPitch.setText(values[2]);
etDesiredPitchTolerance.setText(values[3]);
etDesiredRoll.setText(values[4]);
etDesiredRollTolerance.setText(values[5]);
}
catch(Exception e)
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show();
Miscellaneous.logEvent("e", "DevicePositionTrigger", "There\'s something wrong with a device position trigger. Content: " + getIntent().getStringExtra(vectorFieldName) + ", " + Log.getStackTraceString(e), 1);
}
}
bApplyPositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// Round the values. Too long decimals will destroy the layout
if(!StringUtils.isEmpty(currentAzimuth.getText()))
etDesiredAzimuth.setText(String.valueOf(Math.round(Float.parseFloat(currentAzimuth.getText().toString()))));
if(!StringUtils.isEmpty(currentPitch.getText()))
etDesiredPitch.setText(String.valueOf(Math.round(Float.parseFloat(currentPitch.getText().toString()))));
if(!StringUtils.isEmpty(currentRoll.getText()))
etDesiredRoll.setText(String.valueOf(Math.round(Float.parseFloat(currentRoll.getText().toString()))));
}
});
bSavePositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(!checkInputs(true))
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.enterValidNumbersIntoAllFields), Toast.LENGTH_LONG).show();
}
else
{
// Save
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkDevicePositionApplies.isChecked());
returnData.putExtra(vectorFieldName,
etDesiredAzimuth.getText().toString() + Trigger.triggerParameter2Split +
etDesiredAzimuthTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitch.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitchTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRoll.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRollTolerance.getText().toString());
setResult(RESULT_OK, returnData);
finish();
}
}
});
}
boolean checkInputs(boolean showMessages)
{
if(
!StringUtils.isEmpty(etDesiredAzimuth.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuth.getText().toString())
&&
!StringUtils.isEmpty(etDesiredAzimuthTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuthTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitch.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitch.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitchTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitchTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRoll.getText().toString()) && Miscellaneous.isNumeric(etDesiredRoll.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRollTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredRollTolerance.getText().toString())
)
{
float da = Float.parseFloat(etDesiredAzimuth.getText().toString());
float dp = Float.parseFloat(etDesiredPitch.getText().toString());
float dr = Float.parseFloat(etDesiredRoll.getText().toString());
if(Math.abs(da) > 180 || Math.abs(dp) > 180 || Math.abs(dr) > 180)
{
return false;
}
if(showMessages)
{
float dat = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
float dpt = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
float drt = Float.parseFloat(etDesiredRollTolerance.getText().toString());
/*
The user may enter a tolerance of 180° for two directions, but not all three.
Otherwise this trigger would always apply.
*/
if (Math.abs(dat) >= 180 && Math.abs(dpt) >= 180 && Math.abs(drt) >= 180)
{
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.toleranceOf180OnlyAllowedIn2Fields), ActivityManageTriggerDeviceOrientation.this).show();
return false;
}
}
return true;
}
return false;
}
@Override
protected void onResume()
{
super.onResume();
DeviceOrientationListener.getInstance().startSensorFromConfigActivity(ActivityManageTriggerDeviceOrientation.this, this);
}
@Override
protected void onPause()
{
super.onPause();
DeviceOrientationListener.getInstance().stopSensorFromConfigActivity();
}
public class InputFilterMinMax implements InputFilter
{
private float minimumValue;
private float maximumValue;
public InputFilterMinMax(float minimumValue, float maximumValue)
{
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
}
private boolean isInRange(float a, float b, float c)
{
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
try
{
int input = Integer.parseInt(dest.subSequence(0, dstart).toString() + source + dest.subSequence(dend, dest.length()));
if (isInRange(minimumValue, maximumValue, input))
return null;
}
catch (NumberFormatException nfe)
{
}
return "";
}
}
}
@@ -31,14 +31,22 @@ import static com.jens.automation2.Trigger.triggerParameter2Split;
public class ActivityManageTriggerNotification extends Activity
{
public static final String intentNameNotificationApp = "app";
public static final String intentNameNotificationTitleDir = "titleDir";
public static final String intentNameNotificationTitle = "title";
public static final String intentNameNotificationTextDir = "textDir";
public static final String intentNameNotificationText = "text";
public static final String intentNameNotificationDirection = "direction";
public static Trigger editedNotificationTrigger;
boolean edit = false;
ProgressDialog progressDialog = null;
EditText etNotificationTitle, etNotificationText;
Button bSelectApp, bSaveTriggerNotification;
Spinner spinnerTitleDirection, spinnerTextDirection;
TextView tvSelectedApplication;
CheckBox chkNotificationDirection;
boolean edit = false;
ProgressDialog progressDialog = null;
private static List<PackageInfo> pInfos = null;
public static Trigger resultingTrigger;
@@ -250,7 +258,7 @@ public class ActivityManageTriggerNotification extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.manage_trigger_notification);
setContentView(R.layout.activity_manage_trigger_notification);
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
@@ -322,12 +330,12 @@ public class ActivityManageTriggerNotification extends Activity
else
{
Intent data = new Intent();
data.putExtra("direction", chkNotificationDirection.isChecked());
data.putExtra("app", app);
data.putExtra("titleDir", titleDir);
data.putExtra("title", title);
data.putExtra("textDir", textDir);
data.putExtra("text", text);
data.putExtra(intentNameNotificationDirection, chkNotificationDirection.isChecked());
data.putExtra(intentNameNotificationApp, app);
data.putExtra(intentNameNotificationTitleDir, titleDir);
data.putExtra(intentNameNotificationTitle, title);
data.putExtra(intentNameNotificationTextDir, textDir);
data.putExtra(intentNameNotificationText, text);
ActivityManageTriggerNotification.this.setResult(RESULT_OK, data);
}
@@ -393,7 +401,5 @@ public class ActivityManageTriggerNotification extends Activity
progressDialog.dismiss();
getActionStartActivityDialog1().show();
}
}
}
}
@@ -0,0 +1,212 @@
package com.jens.automation2;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import androidx.annotation.NonNull;
import static com.jens.automation2.Trigger.triggerParameter2Split;
public class ActivityManageTriggerPhoneCall extends Activity
{
public static Trigger editedPhoneCallTrigger;
boolean edit = false;
public static Trigger resultingTrigger;
ProgressDialog progressDialog = null;
protected final static int requestCodeForContactsPermissions = 2345;
protected final static int requestCodeGetContact = 3235;
EditText etTriggerPhoneCallPhoneNumber;
RadioButton rbTriggerPhoneCallStateRinging, rbTriggerPhoneCallStateStarted, rbTriggerPhoneCallStateStopped, rbTriggerPhoneCallDirectionAny, rbTriggerPhoneCallDirectionIncoming, rbTriggerPhoneCallDirectionOutgoing;
Button bSaveTriggerPhoneCall, bTriggerPhoneCallImportFromContacts;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_phone_call);
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
rbTriggerPhoneCallStateRinging = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateRinging);
rbTriggerPhoneCallStateStarted = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStarted);
rbTriggerPhoneCallStateStopped = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStopped);
rbTriggerPhoneCallDirectionAny = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionAny);
rbTriggerPhoneCallDirectionIncoming = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionIncoming);
rbTriggerPhoneCallDirectionOutgoing = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionOutgoing);
bTriggerPhoneCallImportFromContacts = (Button) findViewById(R.id.bTriggerPhoneCallImportFromContacts);
bSaveTriggerPhoneCall = (Button) findViewById(R.id.bSaveTriggerPhoneCall);
bSaveTriggerPhoneCall.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
String tp2Result = "";
if(rbTriggerPhoneCallStateRinging.isChecked())
tp2Result += Trigger.triggerPhoneCallStateRinging;
else if(rbTriggerPhoneCallStateStarted.isChecked())
tp2Result += Trigger.triggerPhoneCallStateStarted;
else if(rbTriggerPhoneCallStateStopped.isChecked())
tp2Result += Trigger.triggerPhoneCallStateStopped;
tp2Result += triggerParameter2Split;
if(rbTriggerPhoneCallDirectionAny.isChecked())
tp2Result += Trigger.triggerPhoneCallDirectionAny;
else if(rbTriggerPhoneCallDirectionIncoming.isChecked())
tp2Result += Trigger.triggerPhoneCallDirectionIncoming;
else if(rbTriggerPhoneCallDirectionOutgoing.isChecked())
tp2Result += Trigger.triggerPhoneCallDirectionOutgoing;
tp2Result += triggerParameter2Split;
if(etTriggerPhoneCallPhoneNumber.getText() != null && etTriggerPhoneCallPhoneNumber.getText().toString().length() > 0)
tp2Result += etTriggerPhoneCallPhoneNumber.getText().toString();
else
tp2Result += Trigger.triggerPhoneCallNumberAny;
if(edit)
{
editedPhoneCallTrigger.setTriggerParameter(false);
editedPhoneCallTrigger.setTriggerParameter2(tp2Result);
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK);
}
else
{
Intent data = new Intent();
data.putExtra("triggerParameter", false);
data.putExtra("triggerParameter2", tp2Result);
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK, data);
}
finish();
}
});
bTriggerPhoneCallImportFromContacts.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageTriggerPhoneCall.this))
{
requestPermissions("android.permission.READ_CONTACTS");
}
else
openContactsDialogue();
}
});
Intent i = getIntent();
if(i.getBooleanExtra("edit", false) == true)
{
edit = true;
loadValuesIntoGui();
}
}
protected void requestPermissions(String... requiredPermissions)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(requiredPermissions.length > 0)
{
StringBuilder permissions = new StringBuilder();
for (String perm : requiredPermissions)
permissions.append(perm + "; ");
if (permissions.length() > 0)
permissions.delete(permissions.length() - 2, permissions.length());
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
requestPermissions(requiredPermissions, requestCodeForContactsPermissions);
}
}
}
private void openContactsDialogue()
{
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, requestCodeGetContact);
}
private void loadValuesIntoGui()
{
String[] parts = editedPhoneCallTrigger.getTriggerParameter2().split(triggerParameter2Split);
if(parts[0].equals(Trigger.triggerPhoneCallStateRinging))
rbTriggerPhoneCallStateRinging.setChecked(true);
else if(parts[0].equals(Trigger.triggerPhoneCallStateStarted))
rbTriggerPhoneCallStateStarted.setChecked(true);
else if(parts[0].equals(Trigger.triggerPhoneCallStateStopped))
rbTriggerPhoneCallStateStopped.setChecked(true);
if(parts[1].equals(Trigger.triggerPhoneCallDirectionAny))
rbTriggerPhoneCallDirectionAny.setChecked(true);
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionIncoming))
rbTriggerPhoneCallDirectionIncoming.setChecked(true);
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionOutgoing))
rbTriggerPhoneCallDirectionOutgoing.setChecked(true);
if(!parts[2].equals(Trigger.triggerPhoneCallNumberAny))
etTriggerPhoneCallPhoneNumber.setText(parts[2]);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == requestCodeGetContact)
{
if(resultCode == Activity.RESULT_OK)
{
String phoneNo = null;
String name = null;
Uri uri = data.getData();
Cursor cursor = ActivityManageTriggerPhoneCall.this.getContentResolver().query(uri, null, null, null, null);
if (cursor.moveToFirst())
{
int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
phoneNo = cursor.getString(phoneIndex);
name = cursor.getString(nameIndex);
etTriggerPhoneCallPhoneNumber.setText(phoneNo);
}
}
}
//super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if(requestCode == requestCodeForContactsPermissions)
{
for(int i=0; i<permissions.length; i++)
{
if(permissions[i].equals("android.permission.READ_CONTACTS"))
{
if(grantResults[i] == PackageManager.PERMISSION_GRANTED)
{
openContactsDialogue();
}
}
}
}
}
}
@@ -0,0 +1,117 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.List;
public class ActivityManageTriggerProfile extends Activity
{
public static final String profileFieldName = "profileName";
boolean editMode = false;
Button bSaveTriggerProfile;
Spinner spinnerProfiles;
CheckBox chkProfileActive, chkProfileCheckSettings;
ArrayAdapter<Profile> profileSpinnerAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_profile);
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile);
spinnerProfiles = (Spinner)findViewById(R.id.spinnerProfiles);
chkProfileActive = (CheckBox)findViewById(R.id.chkProfileActive);
chkProfileCheckSettings = (CheckBox)findViewById(R.id.chkProfileCheckSettings);
try
{
profileSpinnerAdapter = new ArrayAdapter<Profile>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Profile.getProfileCollection());
loadProfileItems();
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "ActivityManageTriggerProfile", Log.getStackTraceString(e), 1);
}
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{
editMode = true;
boolean active = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true);
chkProfileActive.setChecked(active);
try
{
String values[] = getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
if(values.length >= 2)
{
boolean checkSettings = Boolean.parseBoolean(values[0]);
chkProfileCheckSettings.setChecked(checkSettings);
String profileName = values[0];
List<Profile> profileList = Profile.getProfileCollection();
for(int i = 0; i < profileList.size(); i++)
{
if(profileList.get(i).getName().equals(profileName))
{
spinnerProfiles.setSelection(i);
break;
}
}
}
}
catch(Exception e)
{
Toast.makeText(ActivityManageTriggerProfile.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show();
Miscellaneous.logEvent("e", "ActivityManageTriggerProfile", "There\'s something wrong with parameters. Content: " + getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2) + ", " + Log.getStackTraceString(e), 1);
}
}
bSaveTriggerProfile.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkProfileActive.isChecked());
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter2,
spinnerProfiles.getSelectedItem().toString() + Trigger.triggerParameter2Split +
chkProfileCheckSettings.isChecked());
setResult(RESULT_OK, returnData);
finish();
}
});
}
private void loadProfileItems()
{
try
{
if(spinnerProfiles.getAdapter() == null)
spinnerProfiles.setAdapter(profileSpinnerAdapter);
profileSpinnerAdapter.notifyDataSetChanged();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
}
}
@@ -6,11 +6,16 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TimePicker;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -18,8 +23,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
{
Button bSaveTimeFrame;
TimePicker startPicker, stopPicker;
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday;
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday, chkRepeat;
RadioButton radioTimeFrameEntering, radioTimeFrameLeaving;
EditText etRepeatEvery;
public static Trigger editedTimeFrameTrigger = null;
@@ -27,7 +33,7 @@ public class ActivityManageTriggerTimeFrame extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.manage_trigger_timeframe);
setContentView(R.layout.activity_manage_trigger_timeframe);
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
@@ -44,7 +50,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
checkSunday = (CheckBox)findViewById(R.id.checkSunday);
radioTimeFrameEntering = (RadioButton)findViewById(R.id.radioTimeFrameEntering);
radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving);
chkRepeat = (CheckBox)findViewById(R.id.chkRepeat);
etRepeatEvery = (EditText)findViewById(R.id.etRepeatEvery);
bSaveTimeFrame.setOnClickListener(new OnClickListener()
{
@Override
@@ -92,11 +100,43 @@ public class ActivityManageTriggerTimeFrame extends Activity
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.selectOneDay), Toast.LENGTH_LONG).show();
return;
}
}
boolean goOn = false;
if(chkRepeat.isChecked())
{
if(!StringUtils.isEmpty(etRepeatEvery.getText().toString()))
{
try
{
long value = Long.parseLong(etRepeatEvery.getText().toString());
if(value > 0)
{
goOn = true;
}
}
catch(Exception e)
{
}
}
}
else
goOn = true;
if(!goOn)
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterRepetitionTime), Toast.LENGTH_LONG).show();
return;
}
if(editedTimeFrameTrigger.getTimeFrame() == null)
{
// add new one
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList));
if(chkRepeat.isChecked())
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, Long.parseLong(etRepeatEvery.getText().toString())));
else
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, 0));
}
else
{
// edit one
@@ -104,6 +144,11 @@ public class ActivityManageTriggerTimeFrame extends Activity
editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStop(stopTime);
editedTimeFrameTrigger.getTimeFrame().getDayList().clear();
editedTimeFrameTrigger.getTimeFrame().setDayList(dayList);
if(chkRepeat.isChecked())
editedTimeFrameTrigger.getTimeFrame().setRepetition(Long.parseLong(etRepeatEvery.getText().toString()));
else
editedTimeFrameTrigger.getTimeFrame().setRepetition(0);
}
editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked());
@@ -112,6 +157,15 @@ public class ActivityManageTriggerTimeFrame extends Activity
finish();
}
});
chkRepeat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
etRepeatEvery.setEnabled(isChecked);
}
});
if(editedTimeFrameTrigger.getTimeFrame() != null)
loadVariableIntoGui();
@@ -158,6 +212,12 @@ public class ActivityManageTriggerTimeFrame extends Activity
break;
}
}
if(editedTimeFrameTrigger.getTimeFrame().getRepetition() > 0)
{
chkRepeat.setChecked(true);
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
}
}
}
@@ -0,0 +1,196 @@
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.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import com.jens.automation2.receivers.BluetoothReceiver;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ActivityManageTriggerWifi extends Activity
{
public final static String intentNameWifiState = "wifiState";
public final static String intentNameWifiName = "wifiName";
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
EditText etTriggerWifiName;
Spinner spinnerWifiList;
Button btriggerWifiSave, bLoadWifiList;
List<String> wifiList = new ArrayList<>();
ArrayAdapter<String> wifiSpinnerAdapter;
private final static int requestCodeLocationPermission = 124;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_wifi);
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
rbTriggerWifiDisconnected = (RadioButton) findViewById(R.id.rbTriggerWifiDisconnected);
etTriggerWifiName = (EditText) findViewById(R.id.etTriggerWifiName);
spinnerWifiList = (Spinner) findViewById(R.id.spinnerWifiList);
btriggerWifiSave = (Button) findViewById(R.id.btriggerWifiSave);
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
spinnerWifiList.setEnabled(false); // bug in Android; this only works when done in code, not in xml
if (getIntent().hasExtra("edit"))
{
boolean connected = getIntent().getBooleanExtra("wifiState", false);
String wifiName = getIntent().getStringExtra("wifiName");
rbTriggerWifiConnected.setChecked(connected);
rbTriggerWifiDisconnected.setChecked(!connected);
etTriggerWifiName.setText(wifiName);
}
btriggerWifiSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Intent response = new Intent();
response.putExtra("wifiState", rbTriggerWifiConnected.isChecked());
response.putExtra("wifiName", etTriggerWifiName.getText().toString());
setResult(RESULT_OK, response);
finish();
}
});
spinnerWifiList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
etTriggerWifiName.setText(wifiList.get(position));
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
}
});
bLoadWifiList.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
loadWifis();
}
});
}
public void loadWifis()
{
if(!ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityManageTriggerWifi.this))
{
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.permissionsTitle), getResources().getString(R.string.needLocationPermForWifiList), ActivityManageTriggerWifi.this);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialog)
{
ActivityCompat.requestPermissions(ActivityManageTriggerWifi.this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, requestCodeLocationPermission);
}
});
dialog.show();
}
else
{
reallyLoadWifiList();
}
}
void reallyLoadWifiList()
{
if(Build.VERSION.SDK_INT >= 30)
{
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.wifiApi30), ActivityManageTriggerWifi.this).show();
loadListOfVisibleWifis();
}
else
{
WifiManager myWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
for (WifiConfiguration wifi : myWifiManager.getConfiguredNetworks())
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
}
if (wifiList.size() > 0)
{
spinnerWifiList.setEnabled(true);
Collections.sort(wifiList);
}
else
{
spinnerWifiList.setEnabled(false);
Toast.makeText(ActivityManageTriggerWifi.this, getResources().getString(R.string.noKnownWifis), Toast.LENGTH_SHORT).show();
}
wifiSpinnerAdapter.notifyDataSetChanged();
}
void loadListOfVisibleWifis()
{
List<ScanResult> results = null;
try
{
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
results = wifiManager.getScanResults();
for (ScanResult wifi : results)
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "loadListOfVisibleWifis()", Log.getStackTraceString(e), 1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case requestCodeLocationPermission:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
reallyLoadWifiList();
break;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,7 @@
package com.jens.automation2;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.PreferenceActivity;
@@ -9,11 +10,18 @@ import com.jens.automation2.R.layout;
public class ActivitySettings extends PreferenceActivity
{
ListPreference lpStartScreenOptionsValues;
CheckBoxPreference chkPrefUpdateCheck;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(layout.settings);
addPreferencesFromResource(layout.activity_settings);
if(BuildConfig.FLAVOR.equals("apkFlavor"))
{
chkPrefUpdateCheck = (CheckBoxPreference) findPreference("automaticUpdateCheck");
chkPrefUpdateCheck.setEnabled(true);
}
}
}
@@ -1,16 +0,0 @@
package com.jens.automation2;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
public class ActivityTriggerPhoneCall extends Activity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.trigger_phone_call);
}
}
@@ -30,14 +30,14 @@ public class ActivityVolumeTest extends Activity
instance = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_volume_test);
setContentView(R.layout.activity_volume_calibration);
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
etReferenceValue = (EditText)findViewById(R.id.etReferenceValue);
sbReferenceValue = (SeekBar)findViewById(R.id.sbReferenceValue);
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeTestExplanation);
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeCalibrationExplanation);
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeTesterExplanation), String.valueOf(volumeRefreshInterval)));
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeCalibrationExplanation), String.valueOf(volumeRefreshInterval)));
etReferenceValue.setText(String.valueOf(Settings.referenceValueForNoiseLevelMeasurements));
@@ -0,0 +1,65 @@
package com.jens.automation2;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.util.ArrayList;
import java.util.Calendar;
public class AsyncTasks
{
public static class AsyncTaskUpdateCheck extends AsyncTask<Context, Void, Boolean>
{
public static boolean checkRunning = false;
@Override
protected Boolean doInBackground(Context... contexts)
{
if(checkRunning)
return false;
else
checkRunning = true;
try
{
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null).trim();
int latestVersion = Integer.parseInt(result);
// At this point the update check itself has already been successful.
Settings.lastUpdateCheck = Calendar.getInstance().getTimeInMillis();
Settings.writeSettings(contexts[0]);
if (latestVersion > BuildConfig.VERSION_CODE)
{
// There's a new update
return true;
}
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Error checking for update", Log.getStackTraceString(e), 3);
}
return false;
}
@Override
protected void onPostExecute(Boolean result)
{
try
{
ActivityMainScreen.getActivityMainScreenInstance().processUpdateCheckResult(result);
}
catch (NullPointerException e)
{
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result, probably ActivityMainScreen isn't currently shown: " + Log.getStackTraceString(e), 2);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result: " + Log.getStackTraceString(e), 2);
}
}
}
}
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
@@ -23,6 +24,7 @@ import android.util.Log;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import com.jens.automation2.Trigger.Trigger_Enum;
import com.jens.automation2.location.LocationProvider;
@@ -121,14 +123,14 @@ public class AutomationService extends Service implements OnInitListener
if(Build.VERSION.SDK_INT >= 28)
{
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameStartService, AutomationService.this))
if (!ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE, AutomationService.this))
{
/*
Don't have permission to start service. This is a show stopper.
*/
Miscellaneous.logEvent("e", "Permission", "Don't have permission to start foreground service. Will request it now.", 4);
// Toast.makeText(AutomationService.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
ActivityPermissions.requestSpecificPermission(ActivityPermissions.permissionNameStartService);
ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE);
return false;
}
}
@@ -196,7 +198,8 @@ public class AutomationService extends Service implements OnInitListener
if (checkStartupRequirements(this, startAtBoot))
{
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting), 1);
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Miscellaneous.logEvent("i", "Service", ActivityMaintenance.getSystemInfo(), 1);
startUpRoutine();
@@ -210,7 +213,7 @@ public class AutomationService extends Service implements OnInitListener
ActivityMainScreen.updateMainScreen();
this.isRunning = true;
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " " + String.format(this.getResources().getString(R.string.version), BuildConfig.VERSION_NAME + "(Build " + BuildConfig.VERSION_CODE + ")"), 1);
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
// ********** Test area **********
// Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3);
@@ -257,7 +260,8 @@ public class AutomationService extends Service implements OnInitListener
case reloadSettings:
Settings.readFromPersistentStorage(this);
applySettingsAndRules();
myLocationProvider.applySettingsAndRules();
if(myLocationProvider != null)
myLocationProvider.applySettingsAndRules();
break;
case updateNotification:
this.updateNotification();
@@ -270,16 +274,7 @@ public class AutomationService extends Service implements OnInitListener
public void applySettingsAndRules()
{
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate)
{
if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this);
}
else
{
if (ttsEngine != null)
ttsEngine.shutdown();
}
checkForTtsEngine();
startLocationProvider();
ReceiverCoordinator.startAllReceivers();
@@ -302,7 +297,7 @@ public class AutomationService extends Service implements OnInitListener
public void checkForTtsEngine()
{
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate | Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
if (Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate || Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
{
if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this);
@@ -331,7 +326,7 @@ public class AutomationService extends Service implements OnInitListener
protected void startLocationProvider()
{
if(ActivityPermissions.havePermission("android.permission.ACCESS_COARSE_LOCATION", AutomationService.this))
if(ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.this))
myLocationProvider = new LocationProvider(this); //autostart with this (only) constructor
}
@@ -341,19 +336,22 @@ public class AutomationService extends Service implements OnInitListener
{
boolean displayNotification = false;
String rule = "";
outerLoop:
for(Rule r : Rule.getRuleCollection())
{
if(r.isRuleActive())
{
if(!r.haveEnoughPermissions())
// for (String permission : ActivityPermissions.getPermissionsForRule(r))
{
// if (!ActivityPermissions.havePermission(permission, AutomationService.this))
{
// r.setRuleActive(false);
// r.change(AutomationService.this);
if(!displayNotification)
{
displayNotification = true;
rule = r.getName();
break outerLoop;
}
}
}
}
@@ -361,18 +359,16 @@ public class AutomationService extends Service implements OnInitListener
if(displayNotification)
{
// Toast.makeText(Miscellaneous.getAnyContext(), "Require more permissions.", Toast.LENGTH_LONG).show();
// Update notification or show new one that notifiies of the lack or permissions.
Intent intent = new Intent(AutomationService.this, ActivityPermissions.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
Miscellaneous.createDismissableNotificationWithDelay(1010, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
else
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
}
// else
// Toast.makeText(Miscellaneous.getAnyContext(), "Have all required permissions.", Toast.LENGTH_LONG).show();
}
}
@@ -389,6 +385,9 @@ public class AutomationService extends Service implements OnInitListener
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.settingsReferringToRestrictedFeatures), ActivityPermissions.notificationIdPermissions, pi);
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
Miscellaneous.createDismissableNotificationWithDelay(3300, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
else
@@ -397,6 +396,11 @@ public class AutomationService extends Service implements OnInitListener
}
}
public void cancelNotification()
{
NotificationManagerCompat.from(AutomationService.this).cancelAll();
}
protected void checkForMissingBackgroundLocationPermission()
{
if(Miscellaneous.googleToBlameForLocation(true))
@@ -404,28 +408,13 @@ public class AutomationService extends Service implements OnInitListener
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
else
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
}
/*
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
{
if (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
{
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
else
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
}
}
}*/
}
public static void startAutomationService(Context context, boolean startAtBoot)
@@ -445,7 +434,7 @@ public class AutomationService extends Service implements OnInitListener
private void stopRoutine()
{
Log.i("STOP", "Stopping");
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
try
{
myLocationProvider.stopLocationService();
@@ -474,7 +463,6 @@ public class AutomationService extends Service implements OnInitListener
builder.setWhen(System.currentTimeMillis());
builder.setContentIntent(myPendingIntent);
// Notification defaultNotification = new Notification();
Notification defaultNotification = builder.build();
defaultNotification.icon = R.drawable.ic_launcher;
@@ -492,31 +480,6 @@ public class AutomationService extends Service implements OnInitListener
// defaultNotification.ledOffMS = 1500;
return builder;
/*NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(AutomationService.getInstance());
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(Notification.CATEGORY_EVENT);
builder.setWhen(System.currentTimeMillis());
builder.setContentTitle("Automation");
builder.setSmallIcon(R.drawable.ic_launcher);
// builder.setContentText(textToDisplay);
// builder.setSmallIcon(icon);
// builder.setContentIntent(pendingIntent);
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel("notify_001", "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
return builder;*/
}
protected static NotificationCompat.Builder createDefaultNotificationBuilder()
@@ -566,76 +529,68 @@ public class AutomationService extends Service implements OnInitListener
if(instance != null)
{
// if(Settings.showIconWhenServiceIsRunning)
// {
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
String bodyText="";
String lastRuleString = "";
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
try
{
PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
}
catch(NullPointerException e)
{
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
}
}
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
String bodyText="";
String lastRuleString = "";
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
try
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
}
catch(Exception e)
catch(NullPointerException e)
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
}
}
String textToDisplay = bodyText + " " + lastRuleString;
// if(Build.VERSION.SDK_INT < 11)
// {
// myNotification.setLatestEventInfo(instance, "Automation", textToDisplay, myPendingIntent);
// }
// else
// {
notificationBuilder.setContentText(textToDisplay);
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
try
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
}
catch(Exception e)
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
}
myNotification = notificationBuilder.build();
myNotification.defaults = 0;
// }
String textToDisplay = bodyText + " " + lastRuleString;
if(notificationBuilder == null)
notificationBuilder = createDefaultNotificationBuilder();
notificationBuilder.setContentText(textToDisplay);
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
myNotification = notificationBuilder.build();
myNotification.defaults = 0;
// NotificationManager notificationManager = (NotificationManager) instance.getSystemService(NOTIFICATION_SERVICE);
// hide the notification after its selected
// hide the notification after its selected
// myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
myNotification.flags |= Notification.FLAG_NO_CLEAR;
myNotification.flags |= Notification.FLAG_NO_CLEAR;
// notificationManager.notify(notificationId, myNotification);
instance.startForeground(notificationId, myNotification);
// }
// else
// instance.startForeground(notificationId, null); // do not show icon in task bar
instance.startForeground(notificationId, myNotification);
}
}
@@ -659,18 +614,18 @@ public class AutomationService extends Service implements OnInitListener
**/
public void speak(String text, boolean force)
{
if(text.length() > 0 && (force | Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate))
if(text.length() > 0 && (force || Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate))
{
AudioManager myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int mode = myAudioManager.getRingerMode();
if(
(mode == AudioManager.RINGER_MODE_NORMAL && Settings.useTextToSpeechOnNormal)
|
||
(mode == AudioManager.RINGER_MODE_VIBRATE && Settings.useTextToSpeechOnVibrate)
|
||
(mode == AudioManager.RINGER_MODE_SILENT && Settings.useTextToSpeechOnSilent)
|
||
force
)
{
@@ -700,12 +655,12 @@ public class AutomationService extends Service implements OnInitListener
{}
}
}
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking " + text + " in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3);
e.printStackTrace();
}
}
}
@@ -718,31 +673,6 @@ public class AutomationService extends Service implements OnInitListener
return false;
else
return true;
// boolean isActivityFound = false;
// ActivityManager activityManager = (ActivityManager)context.getSystemService (Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
// isActivityFound = false;
// for (int i = 0; i < activitys.size(); i++)
// {
// if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.jens.automation/com.jens.automation.ActivityMainScreen}"))
// {
// isActivityFound = true;
// }
// }
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity running status: " + String.valueOf(isActivityFound), 5);
// return isActivityFound;
// ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
//
// for (RunningTaskInfo task : tasks)
// {
// if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
// return true;
// }
//
// return false;
}
public static boolean isMyServiceRunning(Context context)
@@ -754,7 +684,6 @@ public class AutomationService extends Service implements OnInitListener
{
if(AutomationService.class.getName().equals(service.service.getClassName()))
{
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
return true;
}
}
@@ -763,9 +692,8 @@ public class AutomationService extends Service implements OnInitListener
{
if(Log.getStackTraceString(e).contains("activate")) // Means that a poi has been activated/deactivated. Service is running.
return true;
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
}
return false;
}
}
}
@@ -0,0 +1,22 @@
package com.jens.automation2;
import android.app.admin.DeviceAdminReceiver;
import android.content.Context;
import android.content.Intent;
public class DeviceAdmin extends DeviceAdminReceiver
{
@Override
public void onEnabled (Context context , Intent intent)
{
super.onEnabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Got permission BIND_DEVICE_ADMIN.", 3);
}
@Override
public void onDisabled (Context context , Intent intent)
{
super.onDisabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Permission BIND_DEVICE_ADMIN taken.", 3);
}
}
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
@@ -13,7 +14,10 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -21,6 +25,8 @@ import android.os.Environment;
import android.os.IBinder;
import android.provider.MediaStore;
import android.provider.Settings.Secure;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;
@@ -72,6 +78,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@@ -118,15 +126,6 @@ public class Miscellaneous extends Service
if(url.toLowerCase().contains("https"))
{
connection = (HttpsURLConnection) urlObject.openConnection();
// if(Settings.httpAcceptAllCertificates)
// {
// SSLContext sc = SSLContext.getInstance("TLS");
// sc.init(null, getInsecureTrustManager(), new java.security.SecureRandom());
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Miscellaneous.disableSSLCertificateChecking();
// HttpsURLConnection.setDefaultHostnameVerifier(getInsecureHostnameVerifier());
// }
}
else
connection = (HttpURLConnection) urlObject.openConnection();
@@ -217,7 +216,15 @@ public class Miscellaneous extends Service
return null;
}
@Override
public static int boolToInt(boolean input)
{
if(input)
return 1;
else
return 0;
}
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
@@ -334,7 +341,7 @@ public class Miscellaneous extends Service
migration:
if (!newConfigFile.exists())
{
if (ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, Miscellaneous.getAnyContext()))
if (ActivityPermissions.havePermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Miscellaneous.getAnyContext()))
{
// We have the storage permission, probably because it's an old installation. Files should be migrated to app-specific folder.
@@ -453,6 +460,14 @@ public class Miscellaneous extends Service
public static boolean compare(String direction, String needle, String haystack)
{
// If only one of needle or haystack is null
if(
(needle == null && haystack != null)
||
(needle != null && haystack == null)
)
return false;
switch(direction)
{
case Trigger.directionEquals:
@@ -537,6 +552,22 @@ public class Miscellaneous extends Service
return null;
}
public static boolean isDarkModeEnabled(Context context)
{
int mode = context.getResources().getConfiguration().uiMode;
switch(mode)
{
case 33:
case Configuration.UI_MODE_NIGHT_YES:
return true;
case 17:
case Configuration.UI_MODE_NIGHT_NO:
case Configuration.UI_MODE_NIGHT_UNDEFINED:
default:
return false;
}
}
@SuppressLint("NewApi")
public static String replaceVariablesInText(String source, Context context) throws Exception
@@ -605,7 +636,10 @@ public class Miscellaneous extends Service
if(notificationTitle != null && notificationTitle.length() > 0)
source = source.replace("[notificationTitle]", notificationTitle);
else
{
source = source.replace("notificationTitle unknown", notificationTitle);
Miscellaneous.logEvent("w", "Variable replacement", "notificationTitle was empty.", 3);
}
}
if(source.contains("[notificationText]"))
@@ -615,7 +649,10 @@ public class Miscellaneous extends Service
if(notificationText != null && notificationText.length() > 0)
source = source.replace("[notificationText]", notificationText);
else
{
source = source.replace("notificationText unknown", notificationText);
Miscellaneous.logEvent("w", "Variable replacement", "notificationText was empty.", 3);
}
}
// Miscellaneous.logEvent("i", "URL after replace", source);
@@ -662,6 +699,24 @@ public class Miscellaneous extends Service
return alertDialog.create();
}
private boolean haveNetworkConnection()
{
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
/**
* Checks if the device is rooted.
@@ -670,9 +725,13 @@ public class Miscellaneous extends Service
*/
public static boolean isPhoneRooted()
{
// if(true)
// return true;
// get from build info
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
if (buildTags != null && buildTags.contains("test-keys"))
{
return true;
}
@@ -879,6 +938,7 @@ public class Miscellaneous extends Service
dismissableNotificationBuilder.setContentText(textToDisplay);
dismissableNotificationBuilder.setContentIntent(pendingIntent);
dismissableNotificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
dismissableNotificationBuilder.setAutoCancel(true);
Notification dismissableNotification = dismissableNotificationBuilder.build();
@@ -980,6 +1040,7 @@ public class Miscellaneous extends Service
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(Notification.CATEGORY_SERVICE);
builder.setAutoCancel(true);
builder.setWhen(System.currentTimeMillis());
builder.setContentIntent(myPendingIntent);
@@ -1012,6 +1073,23 @@ public class Miscellaneous extends Service
return "";
}
public static String explode(String glue, String[] inputArray)
{
if(inputArray != null)
{
StringBuilder builder = new StringBuilder();
for (String s : inputArray)
builder.append(s + glue);
if (builder.length() > 0)
builder.delete(builder.length() - glue.length(), builder.length());
return builder.toString();
}
else
return "";
}
public static boolean isGooglePlayInstalled(Context context)
{
// return false;
@@ -1099,11 +1177,11 @@ public class Miscellaneous extends Service
}
catch (IllegalAccessException e)
{
e.printStackTrace();
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
}
catch (InvocationTargetException e)
{
e.printStackTrace();
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
}
return result;
@@ -1471,4 +1549,48 @@ public class Miscellaneous extends Service
{
return intent.resolveActivityInfo(context.getPackageManager(), 0) != null;
}
public static boolean isRegularExpression(String regex)
{
try
{
"compareString".matches(regex); //will cause expection if no valid regex
return true;
}
catch(java.util.regex.PatternSyntaxException e)
{
}
return false;
}
public static boolean comparePhoneNumbers(String number1, String number2)
{
/* To be activated when Android S SDK comes out
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
{
TelephonyManager tm = (TelephonyManager)Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
}
else*/
return PhoneNumberUtils.compare(number1, number2);
}
public static String formatDate(Date input)
{
DateFormat sdf = null;
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
if(sdf == null && Settings.dateFormat != null)
sdf = new SimpleDateFormat(Settings.dateFormat);
String formattedDate;
if(sdf != null)
formattedDate = sdf.format(input);
else
formattedDate = fallBackFormatter.format(input);
return formattedDate;
}
}
@@ -23,7 +23,7 @@ import java.util.Map;
public class News
{
Calendar publishDate;
String applicablePlattform;
String applicablePlatform;
Map<String,NewsTranslation> translations = new HashMap<>();
public static class NewsTranslation
@@ -76,7 +76,7 @@ public class News
if(oldFilePath.exists())
oldFilePath.delete();
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == -1 || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
{
String newsUrl = "https://server47.de/automation/appNews.php";
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
@@ -151,9 +151,9 @@ public class News
String publishDateString = neEl.getElementsByTagName("publishDate").item(0).getTextContent();
newsEntry.setPublishDate(Miscellaneous.calendarFromLong(Long.parseLong(publishDateString) * 1000));
newsEntry.setApplicablePlattform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent());
newsEntry.setApplicablePlatform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent());
if(newsEntry.getApplicablePlattform().equalsIgnoreCase("all") || newsEntry.getApplicablePlattform().equalsIgnoreCase(BuildConfig.FLAVOR))
if(newsEntry.getApplicablePlatform().equalsIgnoreCase("all") || newsEntry.getApplicablePlatform().equalsIgnoreCase(BuildConfig.FLAVOR))
returnList.add(newsEntry);
}
}
@@ -199,14 +199,14 @@ public class News
this.publishDate = publishDate;
}
public String getApplicablePlattform()
public String getApplicablePlatform()
{
return applicablePlattform;
return applicablePlatform;
}
public void setApplicablePlattform(String applicablePlattform)
public void setApplicablePlatform(String applicablePlatform)
{
this.applicablePlattform = applicablePlattform;
this.applicablePlatform = applicablePlatform;
}
@NonNull
@@ -252,8 +252,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, true);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0)
{
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@@ -264,18 +265,22 @@ public class PointOfInterest implements Comparable<PointOfInterest>
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions())
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false);
}
}
}
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Done checking POI rules.", 2);
parentService.updateNotification();
ActivityMainScreen.updateMainScreen();
}
}
public void deactivate(AutomationService parentService)
{
if(this.isActivated())
@@ -285,8 +290,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Left POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, false);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0)
{
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@@ -296,7 +302,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(parentService))
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false);
@@ -491,9 +497,17 @@ public class PointOfInterest implements Comparable<PointOfInterest>
AutomationService service = AutomationService.getInstance();
if (service != null)
{
service.applySettingsAndRules();
//Easiest way to check for changes in location, reset the last known location.
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
try
{
service.applySettingsAndRules();
//Easiest way to check for changes in location, reset the last known location.
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
}
catch(Exception e)
{
// Just log the event. This should not cause an interruption in the program flow.
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
}
}
return true;
@@ -530,14 +544,18 @@ public class PointOfInterest implements Comparable<PointOfInterest>
PointOfInterest.writePoisToFile();
AutomationService service = AutomationService.getInstance();
if(service != null)
try
{
service.applySettingsAndRules();
//Easiest way to check for changes in location, reset the last known location.
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
}
catch(Exception e)
{
// Just log the event. This should not cause an interruption in the program flow.
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
}
return true;
}
@@ -793,6 +811,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
{
String text = String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.overlapBetweenPois), otherPoi.getName(), String.valueOf(overlap));
Miscellaneous.logEvent("w", "POI", text, 2);
// Miscellaneous.messageBox("POI", text, Miscellaneous.getAnyContext()).show();
Toast.makeText(Miscellaneous.getAnyContext(), text, Toast.LENGTH_LONG).show();
return false;
}
@@ -1,10 +1,12 @@
package com.jens.automation2;
import android.app.NotificationManager;
import android.content.ContentValues;
import android.content.Context;
import android.media.AudioManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
@@ -13,10 +15,12 @@ import com.jens.automation2.Action.Action_Enum;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Profile implements Comparable<Profile>
{
protected static ArrayList<Profile> profileCollection = new ArrayList<Profile>();
protected static List<Profile> profileCollection = new ArrayList<Profile>();
protected static List<Profile> profileActivationHistory = new ArrayList<>();
protected String name;
protected String oldName;
@@ -24,6 +28,9 @@ public class Profile implements Comparable<Profile>
protected boolean changeSoundMode;
protected int soundMode;
protected boolean changeDndMode;
protected int dndMode;
boolean changeVolumeMusicVideoGameMedia;
protected int volumeMusic;
@@ -81,6 +88,26 @@ public class Profile implements Comparable<Profile>
return soundMode;
}
public boolean getChangeDndMode()
{
return changeDndMode;
}
public void setChangeDndMode(boolean changeDndMode)
{
this.changeDndMode = changeDndMode;
}
public int getDndMode()
{
return dndMode;
}
public void setDndMode(int dndMode)
{
this.dndMode = dndMode;
}
public void setChangeVolumeMusicVideoGameMedia(boolean changeVolumeMusicVideoGameMedia)
{
this.changeVolumeMusicVideoGameMedia = changeVolumeMusicVideoGameMedia;
@@ -243,7 +270,7 @@ public class Profile implements Comparable<Profile>
return hapticFeedback;
}
public static ArrayList<Profile> getProfileCollection()
public static List<Profile> getProfileCollection()
{
return profileCollection;
}
@@ -264,18 +291,12 @@ public class Profile implements Comparable<Profile>
return null;
}
public boolean delete(AutomationService myAutomationService)
{
// TODO Auto-generated method stub
return false;
}
private boolean applyRingTone(File ringtoneFile, int ringtoneType, Context context)
{
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile.getAbsolutePath(), 3);
if(!ringtoneFile.exists() | !ringtoneFile.canRead())
if(!ringtoneFile.exists() || !ringtoneFile.canRead())
{
String message = "Ringtone file does not exist or cannot read it: " + ringtoneFile.getAbsolutePath();
Miscellaneous.logEvent("i", "Profile", message, 3);
@@ -366,11 +387,23 @@ public class Profile implements Comparable<Profile>
}
// Check if rules reference this profile
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByProfile(this);
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByActionProfile(this);
if(rulesThatReferenceMe.size() > 0)
{
for(Rule oneRule : rulesThatReferenceMe)
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.profileActive)
{
String[] parts = oneTrigger.getTriggerParameter2().split(Trigger.triggerParameter2Split);
parts[0] = this.name;
oneTrigger.setTriggerParameter2(Miscellaneous.explode(Trigger.triggerParameter2Split, parts));
// We don't need to save the file. This will happen anyway in PointOfInterest.writePoisToFile() below.
}
}
for(Action oneAction : oneRule.getActionSet())
{
if(oneAction.getAction() == Action_Enum.changeSoundProfile)
@@ -399,19 +432,50 @@ public class Profile implements Comparable<Profile>
return false;
}
public boolean delete()
{
for(int i = 0; i< Profile.getProfileCollection().size(); i++)
public Rule isInUseByRules()
{
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.profileActive))
{
if(Profile.getProfileCollection().get(i).getName().equals(this.getName()))
for (Rule rule : Rule.findRuleCandidatesByTriggerProfile(this))
{
Profile.getProfileCollection().remove(0);
// write to file
return XmlFileInterface.writeFile();
return rule;
}
}
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
{
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
{
return rule;
}
}
return null;
}
public boolean delete(Context context)
{
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.profileActive))
{
for (Rule rule : Rule.findRuleCandidatesByTriggerProfile(this))
{
Toast.makeText(context, String.format(context.getResources().getString(R.string.ruleXIsUsingProfileY), rule.getName(), this.getName()), Toast.LENGTH_LONG).show();
return false;
}
}
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
{
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
{
Toast.makeText(context, String.format(context.getResources().getString(R.string.ruleXIsUsingProfileY), rule.getName(), this.getName()), Toast.LENGTH_LONG).show();
return false;
}
}
else
{
profileCollection.remove(this);
return XmlFileInterface.writeFile();
}
return false;
}
@@ -439,6 +503,8 @@ public class Profile implements Comparable<Profile>
{
Miscellaneous.logEvent("i", "Profile " + this.getName(), String.format(context.getResources().getString(R.string.profileActivate), this.getName()), 3);
profileActivationHistory.add(this);
AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
if(AutomationService.getInstance().getLockSoundChangesEnd() == null)
@@ -449,6 +515,9 @@ public class Profile implements Comparable<Profile>
if(changeSoundMode)
Actions.setSound(context, soundMode);
if(changeDndMode)
Actions.setDND(context, dndMode);
if(changeVolumeMusicVideoGameMedia)
am.setStreamVolume(AudioManager.STREAM_MUSIC, volumeMusic, AudioManager.FLAG_PLAY_SOUND);
@@ -464,10 +533,19 @@ public class Profile implements Comparable<Profile>
applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
if(changeVibrateWhenRinging)
if(vibrateWhenRinging)
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
else
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
android.provider.Settings.System.putInt(context.getContentResolver(), "vibrate_when_ringing", vibrateWhenRinging?1:0);
}
else
{
if (vibrateWhenRinging)
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
else
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
}
}
if(changeNotificationRingtone)
if(notificationRingtone != null)
@@ -498,6 +576,20 @@ public class Profile implements Comparable<Profile>
{
Miscellaneous.logEvent("e", "Profile " + this.getName(), context.getResources().getString(R.string.errorActivatingProfile) + " " + Log.getStackTraceString(e), 1);
}
finally
{
Miscellaneous.logEvent("i", "POI", "Checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.profileActive);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies after " + this.getName() + " has been activated.", 2);
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
Miscellaneous.logEvent("i", "POI", "Done checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
}
}
else
{
@@ -505,6 +597,104 @@ public class Profile implements Comparable<Profile>
}
}
public boolean areMySettingsCurrentlyActive(Context context)
{
Miscellaneous.logEvent("i", "Profile " + this.getName(), "Checking if profile's settings are currently active.", 3);
try
{
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
if(changeSoundMode)
{
if(am.getRingerMode() != soundMode)
return false;
}
if(changeDndMode && Build.VERSION.SDK_INT >= 23)
{
if(mNotificationManager.getCurrentInterruptionFilter() != dndMode)
return false;
}
if(changeVolumeMusicVideoGameMedia)
{
if(am.getStreamVolume(AudioManager.STREAM_MUSIC) != volumeMusic)
return false;
}
if(changeVolumeNotifications)
{
if(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != volumeNotifications)
return false;
}
if(changeVolumeAlarms)
{
if(am.getStreamVolume(AudioManager.STREAM_ALARM) != volumeAlarms)
return false;
}
// if(changeIncomingCallsRingtone)
// {
// if (incomingCallsRingtone != null)
// {
// applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
// }
// }
if(changeVibrateWhenRinging)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), "vibrate_when_ringing");
if(currentSetting != Miscellaneous.boolToInt(vibrateWhenRinging))
return false;
}
else
{
int currentSetting = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
if(currentSetting != Miscellaneous.boolToInt(vibrateWhenRinging))
return false;
}
}
// if(changeNotificationRingtone)
// if(notificationRingtone != null)
// applyRingTone(notificationRingtone, RingtoneManager.TYPE_NOTIFICATION, context);
if(changeScreenLockUnlockSound)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), "lockscreen_sounds_enabled");
if(currentSetting != Miscellaneous.boolToInt(screenLockUnlockSound))
return false;
}
if(changeAudibleSelection)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED);
if(currentSetting != Miscellaneous.boolToInt(audibleSelection))
return false;
}
if(changeHapticFeedback)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED);
if(currentSetting != Miscellaneous.boolToInt(hapticFeedback))
return false;
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "Profile " + this.getName(), "Error while checking if profile settings are currently active. " + Log.getStackTraceString(e), 1);
}
Miscellaneous.logEvent("i", "Profile " + this.getName(), "This profile's settings are currently active.", 4);
return true;
}
@Override
public String toString()
{
@@ -5,11 +5,12 @@ import android.util.Log;
import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.AlarmListener;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.AutomationListenerInterface;
import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener;
import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener;
@@ -42,10 +43,11 @@ public class ReceiverCoordinator
Class adClass = Class.forName("ActivityDetectionReceiver");
allImplementers = new Class[] {
adClass,
AlarmListener.class,
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
//NfcReceiver.class,
NoiseListener.class,
@@ -56,13 +58,12 @@ public class ReceiverCoordinator
}
catch (ClassNotFoundException e)
{
// e.printStackTrace();
allImplementers = new Class[] {
AlarmListener.class,
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
//NfcReceiver.class,
NoiseListener.class,
@@ -144,18 +145,18 @@ public class ReceiverCoordinator
ConnectivityReceiver.startConnectivityReceiver(AutomationService.getInstance());
// startCellLocationChangedReceiver
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.speed)))
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.speed)))
{
if(!Miscellaneous.googleToBlameForLocation(true))
CellLocationChangedReceiver.startCellLocationChangedReceiver();
}
// startBatteryReceiver
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.charging) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.usb_host_connection) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.batteryLevel))
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.charging) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.usb_host_connection) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.batteryLevel))
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
// startAlarmListener
AlarmListener.startAlarmListener(AutomationService.getInstance());
DateTimeListener.startAlarmListener(AutomationService.getInstance());
TimeZoneListener.startTimeZoneListener(AutomationService.getInstance());
// startNoiseListener
@@ -166,15 +167,15 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
ProcessListener.startProcessListener(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
//startActivityDetectionReceiver
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
// ActivityDetectionReceiver.startActivityDetectionReceiver();
}
}
catch(ClassNotFoundException e)
{
@@ -199,15 +200,15 @@ public class ReceiverCoordinator
WifiBroadcastReceiver.stopWifiReceiver();
BatteryReceiver.stopBatteryReceiver();
TimeZoneListener.stopTimeZoneListener();
AlarmListener.stopAlarmListener(AutomationService.getInstance());
DateTimeListener.stopAlarmListener(AutomationService.getInstance());
NoiseListener.stopNoiseListener();
ProcessListener.stopProcessListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
}
catch(ClassNotFoundException e)
{
@@ -216,6 +217,7 @@ public class ReceiverCoordinator
BluetoothReceiver.stopBluetoothReceiver();
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
}
catch(Exception e)
{
@@ -271,41 +273,45 @@ public class ReceiverCoordinator
ProcessListener.stopProcessListener(AutomationService.getInstance());
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
{
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);;
if(runResult instanceof Boolean)
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
boolean isRunning = (Boolean) runResult;
if (isRunning)
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
if (runResult instanceof Boolean)
{
Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4);
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
if (haveAllPerms)
Miscellaneous.runMethodReflective(activityDetectionClassPath, "restartActivityDetectionReceiver", null);
boolean isRunning = (Boolean) runResult;
if (isRunning)
{
Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4);
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
if (haveAllPerms)
Miscellaneous.runMethodReflective(activityDetectionClassPath, "restartActivityDetectionReceiver", null);
// ActivityDetectionReceiver.restartActivityDetectionReceiver();
}
else
{
Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4);
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
if (haveAllPerms)
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
}
else
{
Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4);
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
if (haveAllPerms)
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
// ActivityDetectionReceiver.startActivityDetectionReceiver();
}
}
}
}
else
{
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
if(runResult instanceof Boolean)
else
{
boolean isRunning = (Boolean) runResult;
if (isRunning)
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
if (runResult instanceof Boolean)
{
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4);
Miscellaneous.runMethodReflective(activityDetectionClassPath, "stopActivityDetectionReceiver", null);
boolean isRunning = (Boolean) runResult;
if (isRunning)
{
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4);
Miscellaneous.runMethodReflective(activityDetectionClassPath, "stopActivityDetectionReceiver", null);
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
}
}
}
}
@@ -346,6 +352,24 @@ public class ReceiverCoordinator
}
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
{
if(!DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Starting DevicePositionListener because used in a new/changed rule.", 4);
// if(DevicePositionListener.getInstance().haveAllPermission())
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
}
}
else
{
if(DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Shutting down DevicePositionListener because not used in any rule.", 4);
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
}
}
AutomationService.updateNotification();
}
}
@@ -15,6 +15,7 @@ public class Settings implements SharedPreferences
public final static int lockSoundChangesInterval = 15;
public static final int newsPollEveryXDays = 3;
public static final int newsDisplayForXDays = 3;
public static final int updateCheckFrequencyDays = 7;
public static final String folderName = "Automation";
public static final String zipFileName = "automation.zip";
@@ -55,16 +56,21 @@ public class Settings implements SharedPreferences
public static boolean rememberLastActivePoi;
public static int locationRingBufferSize;
public static long timeBetweenProcessMonitorings;
public static long acceptDeviceOrientationSignalEveryX_MilliSeconds;
public static int activityDetectionFrequency;
public static int activityDetectionRequiredProbability;
public static boolean privacyLocationing;
public static int startScreen;
public static int tabsPlacement;
public static boolean executeRulesAndProfilesWithSingleClick;
public static boolean displayNewsOnMainScreen;
public static boolean automaticUpdateCheck;
public static boolean lockSoundChanges;
public static boolean noticeAndroid9MicrophoneShown;
public static boolean noticeAndroid10WifiShown;
public static long lastNewsPolltime;
public static long lastUpdateCheck;
public static ArrayList<String> whatHasBeenDone;
@@ -108,14 +114,18 @@ public class Settings implements SharedPreferences
protected static final boolean default_rememberLastActivePoi = true;
protected static final int default_locationRingBufferSize=3;
protected static final long default_timeBetweenProcessMonitorings = 60;
protected static final long default_acceptDevicePositionSignalEveryX_MilliSeconds = 1000;
protected static final int default_activityDetectionFrequency = 60;
protected static final int default_activityDetectionRequiredProbability = 75;
protected static final boolean default_privacyLocationing = false;
protected static final int default_startScreen = 0;
protected static final int default_tabsPlacement = 0;
protected static final boolean default_executeRulesAndProfilesWithSingleClick = false;
protected static final boolean default_displayNewsOnMainScreen = false;
protected static final boolean default_automaticUpdateCheck = false;
protected static final boolean default_lockSoundChanges = false;
protected static final long default_lastNewsPolltime = -1;
protected static final long default_lastUpdateCheck = -1;
@Override
public boolean contains(String arg0)
@@ -228,6 +238,7 @@ public class Settings implements SharedPreferences
lengthOfNoiseLevelMeasurements = Long.parseLong(prefs.getString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements)));
referenceValueForNoiseLevelMeasurements = Long.parseLong(prefs.getString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements)));
timeBetweenProcessMonitorings = Long.parseLong(prefs.getString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings)));
acceptDeviceOrientationSignalEveryX_MilliSeconds = Long.parseLong(prefs.getString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds)));
httpAcceptAllCertificates = prefs.getBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates);
httpAttempts = Integer.parseInt(prefs.getString("httpAttempts", String.valueOf(default_httpAttempts)));
@@ -247,8 +258,10 @@ public class Settings implements SharedPreferences
privacyLocationing = prefs.getBoolean("privacyLocationing", default_privacyLocationing);
startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
executeRulesAndProfilesWithSingleClick = prefs.getBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
automaticUpdateCheck = prefs.getBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
displayNewsOnMainScreen = prefs.getBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
lockSoundChanges = prefs.getBoolean("lockSoundChanges", default_lockSoundChanges);
@@ -256,6 +269,7 @@ public class Settings implements SharedPreferences
noticeAndroid10WifiShown = prefs.getBoolean("noticeAndroid10WifiShown", false);
lastNewsPolltime = prefs.getLong("lastNewsPolltime", default_lastNewsPolltime);
lastUpdateCheck = prefs.getLong("lastUpdateCheck", default_lastUpdateCheck);
String whbdString = prefs.getString("whatHasBeenDone", "");
if(whbdString != null && whbdString.length() > 0)
@@ -420,6 +434,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("timeBetweenProcessMonitorings") | force)
editor.putString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings));
if(!prefs.contains("acceptDevicePositionSignalEveryX_MilliSeconds") | force)
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds));
if(!prefs.contains("activityDetectionFrequency") | force)
editor.putString("activityDetectionFrequency", String.valueOf(default_activityDetectionFrequency));
@@ -432,9 +449,15 @@ public class Settings implements SharedPreferences
if(!prefs.contains("startScreen") | force)
editor.putString("startScreen", String.valueOf(default_startScreen));
if(!prefs.contains("tabsPlacement") | force)
editor.putString("tabsPlacement", String.valueOf(default_tabsPlacement));
if(!prefs.contains("executeRulesAndProfilesWithSingleClick") | force)
editor.putBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
if(!prefs.contains("automaticUpdateCheck") | force)
editor.putBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
if(!prefs.contains("displayNewsOnMainScreen") | force)
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
@@ -447,6 +470,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("lastNewsPolltime") | force)
editor.putLong("lastNewsPolltime", default_lastNewsPolltime);
if(!prefs.contains("lastUpdateCheck") | force)
editor.putLong("lastUpdateCheck", default_lastUpdateCheck);
if(!prefs.contains("whatHasBeenDone") | force)
editor.putString("whatHasBeenDone", "");
@@ -506,11 +532,14 @@ public class Settings implements SharedPreferences
editor.putString("httpAttemptGap", String.valueOf(httpAttemptGap));
editor.putString("locationRingBufferSize", String.valueOf(locationRingBufferSize));
editor.putString("timeBetweenProcessMonitorings", String.valueOf(timeBetweenProcessMonitorings));
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(acceptDeviceOrientationSignalEveryX_MilliSeconds));
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
editor.putBoolean("privacyLocationing", privacyLocationing);
editor.putString("startScreen", String.valueOf(startScreen));
editor.putString("tabsPlacement", String.valueOf(tabsPlacement));
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
editor.putBoolean("automaticUpdateCheck", automaticUpdateCheck);
editor.putBoolean("displayNewsOnMainScreen", displayNewsOnMainScreen);
editor.putBoolean("lockSoundChanges", lockSoundChanges);
@@ -518,6 +547,7 @@ public class Settings implements SharedPreferences
editor.putBoolean("noticeAndroid10WifiShown", noticeAndroid10WifiShown);
editor.putLong("lastNewsPolltime", lastNewsPolltime);
editor.putLong("lastUpdateCheck", lastUpdateCheck);
editor.putString("whatHasBeenDone", Miscellaneous.explode(";", whatHasBeenDone));
@@ -559,4 +589,4 @@ public class Settings implements SharedPreferences
return null;
}
}
}
@@ -6,70 +6,90 @@ import java.util.ArrayList;
public class TimeFrame
{
// Defines a timeframe
private Time triggerTimeStart;
private Time triggerTimeStop;
protected Time triggerTimeStart;
protected Time triggerTimeStop;
protected long repetition;
private ArrayList<Integer> dayList = new ArrayList<Integer>();
public ArrayList<Integer> getDayList()
protected final static String separator = "/";
private ArrayList<Integer> dayList = new ArrayList<Integer>();
public ArrayList<Integer> getDayList()
{
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
// Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item)));
}
dayList.add(Integer.parseInt(String.valueOf(item)));
}
}
public Time getTriggerTimeStart()
{
return triggerTimeStart;
}
public void setTriggerTimeStart(Time triggerTimeStart)
{
this.triggerTimeStart = triggerTimeStart;
}
public Time getTriggerTimeStop()
{
return triggerTimeStop;
}
public void setTriggerTimeStop(Time triggerTimeStop)
{
this.triggerTimeStop = triggerTimeStop;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
this.setDayList(dayList2);
}
TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split("/"); // example: timestart/timestop/days[int]
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.setDayListFromString(dateArray[2]);
}
@Override
public String toString()
{
String returnString = this.getTriggerTimeStart().toString() + "/" + this.getTriggerTimeStop().toString() + "/";
for(Integer oneDay : this.getDayList())
returnString += String.valueOf(oneDay);
return returnString;
}
}
public Time getTriggerTimeStart()
{
return triggerTimeStart;
}
public void setTriggerTimeStart(Time triggerTimeStart)
{
this.triggerTimeStart = triggerTimeStart;
}
public Time getTriggerTimeStop()
{
return triggerTimeStop;
}
public void setTriggerTimeStop(Time triggerTimeStop)
{
this.triggerTimeStop = triggerTimeStop;
}
public long getRepetition()
{
return repetition;
}
public void setRepetition(long repetition)
{
this.repetition = repetition;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2, long repetition)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
this.setDayList(dayList2);
this.setRepetition(repetition);
}
public TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split(separator); // example: timestart/timestop/days[int]/repetition
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.setDayListFromString(dateArray[2]);
if(dateArray.length > 3) // may not exist in old config files
this.setRepetition(Long.parseLong(dateArray[3]));
}
@Override
public String toString()
{
String returnString = this.getTriggerTimeStart().toString() + separator + this.getTriggerTimeStop().toString() + separator;