Compare commits
181 Commits
v1.6.43
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
92e58149a7 | |||
efaf0ed270 | |||
a9673e65b9 | |||
592abe5b0d | |||
dd7c3cb1d6 | |||
38665ccd92 | |||
c60347b990 | |||
1e7ccf5200 | |||
9b84b8dad7 | |||
a19c84ea51 | |||
3a14a56fd0 | |||
2dfc538343 | |||
67a58077cc | |||
df68f7ca5c | |||
ad18313284 | |||
29a93e0e43 | |||
a5d54c18d8 | |||
62f5ad0005 | |||
4eb7133d9d | |||
343cbba8f8 | |||
51caae0794 | |||
e39a2411ba | |||
98b49036a7 | |||
a7c4cc0965 | |||
5d67452486 | |||
7e12a0f3e5 | |||
5786c1bfd4 | |||
cf500c740e | |||
41efa7c11b | |||
7046cccabe | |||
bdbed3dbef | |||
3f36c4c6b3 | |||
52a10fe626 | |||
9fce7d987e | |||
d5ce04f80b | |||
62c97832a9 | |||
391edc59bf | |||
0d3a13e753 | |||
152b0c3c49 | |||
7ed04c7ae2 | |||
c688a4c460 | |||
5a09962cc9 | |||
0368b2a8c8 | |||
965bf55811 | |||
217f459833 | |||
13fd4c2aae | |||
195a60cfe0 | |||
76563eb89b | |||
4c9e61618b | |||
e719114166 | |||
7733d57435 | |||
481e4d1896 | |||
0bd64e4a53 | |||
5af59e1754 | |||
c569ab798c | |||
4e46878009 | |||
619f348a28 | |||
72ccdd99f9 | |||
c9d7399068 | |||
9bf353ea3a | |||
af90b566c8 | |||
0e51c577d5 | |||
275091f9d7 | |||
bc31c9a4c8 | |||
b02220609b | |||
da244d1bbe | |||
d402986dc3 | |||
85eee6c4da | |||
34883519e4 | |||
92e405d396 | |||
1a8ce579a7 | |||
5899dd86f5 | |||
9387e8bdb2 | |||
5ed024774e | |||
e76f9f69db | |||
0f1a12d28f | |||
abaa961d3a | |||
5f0eab5b30 | |||
92cb71ff2d | |||
71adc83b39 | |||
88f4d65b19 | |||
0c5b4d3874 | |||
d64ea8454e | |||
94f6418076 | |||
83ee19b4fa | |||
5ed6097ed6 | |||
7e9d03104c | |||
2e3e829abb | |||
06080bb456 | |||
a5fd23949d | |||
59c7a2d313 | |||
ec61a3ffa5 | |||
a0c4cb7b6f | |||
22899347a1 | |||
4b84a0c2f5 | |||
724192e80b | |||
e6a7e2c5b5 | |||
e010e3392f | |||
f3c4a0fd91 | |||
f0853b3a30 | |||
98185a79df | |||
246a02371a | |||
9b8ae2271b | |||
b2cd3cf17c | |||
cf4ec286ae | |||
2a067507ae | |||
12f44aca8b | |||
1c8eec735d | |||
87edd595ba | |||
53f46c10da | |||
c5f04afe85 | |||
4d7fa711f9 | |||
4bea2113fa | |||
890260b8eb | |||
230521149f | |||
9a50da550a | |||
941bb3e1af | |||
5653a9c70e | |||
8c6331237d | |||
1bbf04d548 | |||
a2d93d27cb | |||
0463e0aa19 | |||
41cf907be3 | |||
acae282a0d | |||
ebfceee69f | |||
69283c5fea | |||
fff0bde9d8 | |||
f9c76ba951 | |||
d1263b46b6 | |||
64801d8ff2 | |||
3d8257aeec | |||
67b2a81647 | |||
3e9590d7d2 | |||
21b8c6c7ec | |||
dc8cc14d20 | |||
4fc1f8a2a9 | |||
d7e1cd44e8 | |||
c1139e1cb8 | |||
03c8a1ff60 | |||
20acd563e7 | |||
5ae193847e | |||
391479b164 | |||
fa578b175d | |||
0008642044 | |||
359dd545c7 | |||
89ac69fd4b | |||
b88801500f | |||
128116025f | |||
5d3e89595f | |||
8e5ad15c34 | |||
8b29dd0985 | |||
c34ec83425 | |||
cdf1a8baa8 | |||
d28ee8d00d | |||
2bb6f81596 | |||
6f0dbc9555 | |||
a9bd7b9561 | |||
81d6ab7b5f | |||
034c76fe30 | |||
15637e914d | |||
cd6ed7543c | |||
f991325566 | |||
b744e76b07 | |||
06d63826e6 | |||
fb87d5e42d | |||
17109b12d4 | |||
92ca6d6cb4 | |||
5fdc68e396 | |||
ab0f2d88b4 | |||
06a6651fae | |||
473c464bf7 | |||
a5b9ced9ba | |||
9cea3f4285 | |||
0438a58f3e | |||
97f32bd012 | |||
6588443459 | |||
604ab0eb43 | |||
31c4f6c1d1 | |||
0c646b55fc | |||
88cdc366c5 | |||
2bd94e8a3d |
2
.gitignore
vendored
2
.gitignore
vendored
@ -148,3 +148,5 @@ fabric.properties
|
||||
|
||||
/app/app-release.apk
|
||||
Automation_settings.xml
|
||||
/app/googlePlayFlavor/
|
||||
/.idea/deploymentTargetDropDown.xml
|
||||
|
17
.idea/deploymentTargetDropDown.xml
generated
17
.idea/deploymentTargetDropDown.xml
generated
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="C:\Users\jens\.android\avd\Android_11.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2021-09-24T23:07:53.935197300Z" />
|
||||
</component>
|
||||
</project>
|
@ -8,11 +8,11 @@ android {
|
||||
defaultConfig {
|
||||
applicationId "com.jens.automation2"
|
||||
minSdkVersion 16
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 113
|
||||
versionName "1.6.43"
|
||||
versionCode 120
|
||||
versionName "1.7.6"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -28,11 +28,6 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
flavorDimensions "version"
|
||||
|
||||
productFlavors
|
||||
@ -57,9 +52,15 @@ android {
|
||||
targetSdkVersion 28
|
||||
}
|
||||
}
|
||||
lint {
|
||||
abortOnError false
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
namespace 'com.jens.automation2'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.jetbrains:annotations:15.0'
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
|
||||
|
||||
@ -71,9 +72,9 @@ dependencies {
|
||||
|
||||
//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 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
}
|
@ -11,8 +11,8 @@
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 113,
|
||||
"versionName": "1.6.43-googlePlay",
|
||||
"versionCode": 119,
|
||||
"versionName": "1.7.5-googlePlay",
|
||||
"outputFile": "app-googlePlayFlavor-release.apk"
|
||||
}
|
||||
],
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -65,6 +64,8 @@
|
||||
<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-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -72,6 +73,12 @@
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action
|
||||
android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -121,32 +128,44 @@
|
||||
<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=".ActivityManageActionCloseNotification" />
|
||||
<activity android:name=".ActivityManageTriggerProfile" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityControlCenter" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageTriggerBroadcast" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionCreateNotification" />
|
||||
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity android:name=".ActivityManageActionControlMedia" />
|
||||
<activity android:name=".ActivityManageActionSendBroadcast" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@ -186,6 +205,7 @@
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
@ -204,6 +224,7 @@
|
||||
|
||||
</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"/>
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -51,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" />
|
||||
@ -62,6 +62,8 @@
|
||||
<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-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -69,6 +71,12 @@
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action
|
||||
android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -118,32 +126,44 @@
|
||||
<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=".ActivityManageActionCloseNotification" />
|
||||
<activity android:name=".ActivityManageTriggerProfile" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityControlCenter" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageTriggerBroadcast" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionCreateNotification" />
|
||||
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity android:name=".ActivityManageActionControlMedia" />
|
||||
<activity android:name=".ActivityManageActionSendBroadcast" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@ -170,6 +190,7 @@
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
@ -203,7 +224,6 @@
|
||||
|
||||
<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"/>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -50,6 +49,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 +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"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -112,32 +113,44 @@
|
||||
<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=".ActivityManageActionCloseNotification" />
|
||||
<activity android:name=".ActivityManageTriggerProfile" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityControlCenter" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageTriggerBroadcast" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionCreateNotification" />
|
||||
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity android:name=".ActivityManageActionControlMedia" />
|
||||
<activity android:name=".ActivityManageActionSendBroadcast" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@ -198,7 +211,6 @@
|
||||
|
||||
<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"/>
|
||||
|
||||
|
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()))
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jens.automation2">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
|
||||
|
||||
|
@ -2,9 +2,13 @@ package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -13,100 +17,118 @@ 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 intentPairSeparator = "intPairSplit";
|
||||
public static final String vibrateSeparator = ",";
|
||||
|
||||
public enum Action_Enum {
|
||||
setWifi,
|
||||
setBluetooth,
|
||||
setUsbTethering,
|
||||
setWifiTethering,
|
||||
setDisplayRotation,
|
||||
turnWifiOn,turnWifiOff,
|
||||
turnBluetoothOn,turnBluetoothOff,
|
||||
triggerUrl,
|
||||
changeSoundProfile,
|
||||
turnUsbTetheringOn,turnUsbTetheringOff,
|
||||
turnWifiTetheringOn,turnWifiTetheringOff,
|
||||
enableScreenRotation, disableScreenRotation,
|
||||
startOtherActivity,
|
||||
waitBeforeNextAction,
|
||||
wakeupDevice,
|
||||
setAirplaneMode,
|
||||
setDataConnection,
|
||||
speakText,
|
||||
playMusic,
|
||||
setScreenBrightness,
|
||||
playSound,
|
||||
vibrate,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case setWifi:
|
||||
return context.getResources().getString(R.string.actionSetWifi);
|
||||
case setBluetooth:
|
||||
return context.getResources().getString(R.string.actionSetBluetooth);
|
||||
case setWifiTethering:
|
||||
return context.getResources().getString(R.string.actionSetWifiTethering);
|
||||
case setUsbTethering:
|
||||
return context.getResources().getString(R.string.actionSetUsbTethering);
|
||||
case setDisplayRotation:
|
||||
return context.getResources().getString(R.string.actionSetDisplayRotation);
|
||||
case turnWifiOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOn);
|
||||
case turnWifiOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOff);
|
||||
case turnBluetoothOn:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOn);
|
||||
case turnBluetoothOff:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOff);
|
||||
case triggerUrl:
|
||||
return context.getResources().getString(R.string.actionTriggerUrl);
|
||||
case changeSoundProfile:
|
||||
return context.getResources().getString(R.string.actionChangeSoundProfile);
|
||||
case turnUsbTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
|
||||
case turnUsbTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
|
||||
case turnWifiTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
|
||||
case turnWifiTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
|
||||
case enableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionEnableScreenRotation);
|
||||
case disableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionDisableScreenRotation);
|
||||
case startOtherActivity:
|
||||
return context.getResources().getString(R.string.startOtherActivity);
|
||||
case waitBeforeNextAction:
|
||||
return context.getResources().getString(R.string.waitBeforeNextAction);
|
||||
case wakeupDevice:
|
||||
return context.getResources().getString(R.string.wakeupDevice);
|
||||
case vibrate:
|
||||
return context.getResources().getString(R.string.vibrate);
|
||||
case setAirplaneMode:
|
||||
return context.getResources().getString(R.string.airplaneMode);
|
||||
case setDataConnection:
|
||||
return context.getResources().getString(R.string.actionDataConnection);
|
||||
case speakText:
|
||||
return context.getResources().getString(R.string.actionSpeakText);
|
||||
case playMusic:
|
||||
return context.getResources().getString(R.string.actionPlayMusic);
|
||||
case playSound:
|
||||
return context.getResources().getString(R.string.playSound);
|
||||
case sendTextMessage:
|
||||
return context.getResources().getString(R.string.sendTextMessage);
|
||||
case setScreenBrightness:
|
||||
return context.getResources().getString(R.string.setScreenBrightness);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
public enum Action_Enum
|
||||
{
|
||||
setWifi,
|
||||
setBluetooth,
|
||||
setUsbTethering,
|
||||
setWifiTethering,
|
||||
setBluetoothTethering,
|
||||
setDisplayRotation,
|
||||
turnWifiOn,turnWifiOff,
|
||||
turnBluetoothOn,turnBluetoothOff,
|
||||
triggerUrl,
|
||||
changeSoundProfile,
|
||||
turnUsbTetheringOn,turnUsbTetheringOff,
|
||||
turnWifiTetheringOn,turnWifiTetheringOff,
|
||||
enableScreenRotation,disableScreenRotation,
|
||||
startOtherActivity,
|
||||
waitBeforeNextAction,
|
||||
turnScreenOnOrOff,
|
||||
setAirplaneMode,
|
||||
setDataConnection,
|
||||
speakText,
|
||||
playMusic,
|
||||
controlMediaPlayback,
|
||||
setScreenBrightness,
|
||||
playSound,
|
||||
vibrate,
|
||||
createNotification,
|
||||
closeNotification,
|
||||
sendBroadcast,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case setWifi:
|
||||
return context.getResources().getString(R.string.actionSetWifi);
|
||||
case setBluetooth:
|
||||
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:
|
||||
return context.getResources().getString(R.string.actionSetDisplayRotation);
|
||||
case turnWifiOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOn);
|
||||
case turnWifiOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOff);
|
||||
case turnBluetoothOn:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOn);
|
||||
case turnBluetoothOff:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOff);
|
||||
case triggerUrl:
|
||||
return context.getResources().getString(R.string.actionTriggerUrl);
|
||||
case changeSoundProfile:
|
||||
return context.getResources().getString(R.string.actionChangeSoundProfile);
|
||||
case turnUsbTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
|
||||
case turnUsbTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
|
||||
case turnWifiTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
|
||||
case turnWifiTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
|
||||
case enableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionEnableScreenRotation);
|
||||
case disableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionDisableScreenRotation);
|
||||
case startOtherActivity:
|
||||
return context.getResources().getString(R.string.startOtherActivity);
|
||||
case waitBeforeNextAction:
|
||||
return context.getResources().getString(R.string.waitBeforeNextAction);
|
||||
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:
|
||||
return context.getResources().getString(R.string.actionDataConnection);
|
||||
case speakText:
|
||||
return context.getResources().getString(R.string.actionSpeakText);
|
||||
case playMusic:
|
||||
return context.getResources().getString(R.string.actionPlayMusic);
|
||||
case controlMediaPlayback:
|
||||
return context.getResources().getString(R.string.actionMediaControl);
|
||||
case playSound:
|
||||
return context.getResources().getString(R.string.playSound);
|
||||
case sendTextMessage:
|
||||
return context.getResources().getString(R.string.sendTextMessage);
|
||||
case setScreenBrightness:
|
||||
return context.getResources().getString(R.string.setScreenBrightness);
|
||||
case createNotification:
|
||||
return context.getResources().getString(R.string.createNotification);
|
||||
case closeNotification:
|
||||
return context.getResources().getString(R.string.closeNotifications);
|
||||
case sendBroadcast:
|
||||
return context.getResources().getString(R.string.sendBroadcast);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private Action_Enum action;
|
||||
private boolean parameter1 = false;
|
||||
@ -147,132 +169,212 @@ public class Action
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
if(this.getAction().equals(Action_Enum.setWifi))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
|
||||
}
|
||||
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))
|
||||
try
|
||||
{
|
||||
String[] components = parameter2.split(";");
|
||||
if(components.length >= 3)
|
||||
switch (getAction())
|
||||
{
|
||||
returnString.append(": " + components[2]);
|
||||
|
||||
if(parameter1)
|
||||
returnString.append(" using authentication.");
|
||||
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 controlMediaPlayback:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionMediaControl));
|
||||
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;
|
||||
case createNotification:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.createNotification));
|
||||
break;
|
||||
case closeNotification:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.closeNotifications));
|
||||
break;
|
||||
case sendBroadcast:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendBroadcast));
|
||||
break;
|
||||
default:
|
||||
returnString.append(action.toString());
|
||||
}
|
||||
else
|
||||
returnString.append(": " + components[0]);
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.intentPairSeperator, "/"));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
String[] components = parameter2.split(Actions.smsSeparator);
|
||||
if(components.length >= 2)
|
||||
|
||||
if (this.getAction().equals(Action_Enum.triggerUrl))
|
||||
{
|
||||
returnString.append(" to number " + components[0]);
|
||||
String[] components = parameter2.split(";");
|
||||
if (components.length >= 3)
|
||||
{
|
||||
returnString.append(": " + components[2]);
|
||||
|
||||
returnString.append(". Message: " + components[1]);
|
||||
if (parameter1)
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingAuthentication) + ".");
|
||||
}
|
||||
else
|
||||
returnString.append(": " + components[0]);
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.intentPairSeparator, "/"));
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
String[] components = parameter2.split(Actions.smsSeparator);
|
||||
if (components.length >= 2)
|
||||
{
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.toNumber) + " " + components[0]);
|
||||
|
||||
returnString.append(". " + Miscellaneous.getAnyContext().getResources().getString(R.string.message) + ": " + components[1]);
|
||||
}
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.setScreenBrightness))
|
||||
{
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.to) + " ");
|
||||
|
||||
if (parameter1)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessManual));
|
||||
|
||||
returnString.append(" / " + Integer.parseInt(parameter2) + "%");
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.closeNotification))
|
||||
{
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.from) + " ");
|
||||
|
||||
String parts[] = this.getParameter2().split(Action.actionParameter2Split);
|
||||
if (parts[0].equals(Trigger.anyAppString))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.anyApp));
|
||||
else
|
||||
returnString.append(parts[0]);
|
||||
|
||||
if (!StringUtils.isBlank(parts[2]))
|
||||
returnString.append(", " + Miscellaneous.getAnyContext().getResources().getString(R.string.ifString) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.title) + " " + Trigger.getMatchString(parts[1]) + " " + parts[2]);
|
||||
|
||||
if (parts.length > 4 && !StringUtils.isBlank(parts[4]))
|
||||
returnString.append(", " + Miscellaneous.getAnyContext().getResources().getString(R.string.ifString) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.text) + " " + Trigger.getMatchString(parts[3]) + " " + parts[4]);
|
||||
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.controlMediaPlayback))
|
||||
{
|
||||
returnString.append(": ");
|
||||
|
||||
switch (this.getParameter2())
|
||||
{
|
||||
case "0":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playPause));
|
||||
break;
|
||||
case "1":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.play));
|
||||
break;
|
||||
case "2":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.pause));
|
||||
break;
|
||||
case "3":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.stop));
|
||||
break;
|
||||
case "4":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.previous));
|
||||
break;
|
||||
case "5":
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.next));
|
||||
break;
|
||||
default:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.unknown));
|
||||
}
|
||||
}
|
||||
else if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setScreenBrightness))
|
||||
catch (Exception e)
|
||||
{
|
||||
returnString.append(" to ");
|
||||
|
||||
if(parameter1)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessManual));
|
||||
|
||||
returnString.append(" / " + Integer.parseInt(parameter2) + "%");
|
||||
returnString.append(": " + Miscellaneous.getAnyContext().getResources().getString(R.string.error));
|
||||
}
|
||||
else
|
||||
if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2);
|
||||
|
||||
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>();
|
||||
@ -337,7 +439,7 @@ public class Action
|
||||
|
||||
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
|
||||
}
|
||||
|
||||
|
||||
public void run(Context context, boolean toggleActionIfPossible)
|
||||
{
|
||||
try
|
||||
@ -370,6 +472,9 @@ public class Action
|
||||
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;
|
||||
@ -379,16 +484,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 separate 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:
|
||||
@ -403,6 +518,9 @@ public class Action
|
||||
case playMusic:
|
||||
Actions.playMusic(this.getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case controlMediaPlayback:
|
||||
Actions.controlMediaPlayback(context, Integer.parseInt(getParameter2()));
|
||||
break;
|
||||
case sendTextMessage:
|
||||
Actions.sendTextMessage(context, this.getParameter2().split(Actions.smsSeparator));
|
||||
break;
|
||||
@ -415,6 +533,18 @@ public class Action
|
||||
case playSound:
|
||||
Actions.playSound(getParameter1(), getParameter2());
|
||||
break;
|
||||
case createNotification:
|
||||
Actions.createNotification(this);
|
||||
break;
|
||||
case closeNotification:
|
||||
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M)
|
||||
Actions.closeNotification(this);
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Close notification", "Close notification was requested, but OS version is too low: " + String.valueOf(Build.VERSION.SDK_INT), 2);
|
||||
break;
|
||||
case sendBroadcast:
|
||||
Actions.sendBroadcast(context, this.getParameter2());
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
@ -518,7 +648,7 @@ public class Action
|
||||
//Do something with result
|
||||
//Toast.makeText(context, text, duration) result;
|
||||
Miscellaneous.logEvent("i", "HTTP RESULT", result, 3);
|
||||
Actions myAction=new Actions();
|
||||
Actions myAction = new Actions();
|
||||
myAction.useDownloadedWebpage(result);
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,18 @@ import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
@ -20,11 +26,13 @@ import android.os.PowerManager.WakeLock;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.MediaStore;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
@ -33,7 +41,9 @@ import com.jens.automation2.actions.wifi_router.MyOnStartTetheringCallback;
|
||||
import com.jens.automation2.actions.wifi_router.MyOreoWifiManager;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
@ -43,13 +53,17 @@ import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
@ -57,9 +71,8 @@ import eu.chainfire.libsuperuser.Shell;
|
||||
|
||||
public class Actions
|
||||
{
|
||||
public static AutomationService autoMationServerRef;
|
||||
public static AutomationService automationServerRef;
|
||||
public static Context context;
|
||||
public static Context rootetcontext;
|
||||
private static Intent playMusicIntent;
|
||||
private static boolean suAvailable = false;
|
||||
private static String suVersion = null;
|
||||
@ -72,7 +85,115 @@ public class Actions
|
||||
public static final String wireguard_tunnel_down = "com.wireguard.android.action.SET_TUNNEL_DOWN";
|
||||
public static final String wireguard_tunnel_refresh = "com.wireguard.android.action.REFRESH_TUNNEL_STATES";
|
||||
|
||||
public static class WifiStuff
|
||||
public static void createNotification(Action action)
|
||||
{
|
||||
String[] elements = action.getParameter2().split(Action.actionParameter2Split);
|
||||
|
||||
Miscellaneous.logEvent("w", "createNotification", "Creating notification with title " + elements[0] + " and text " + elements[1], 3);
|
||||
|
||||
int notificationId = Math.round(Calendar.getInstance().getTimeInMillis()/1000);
|
||||
|
||||
try
|
||||
{
|
||||
String title = Miscellaneous.replaceVariablesInText(elements[0], Miscellaneous.getAnyContext());
|
||||
String text = Miscellaneous.replaceVariablesInText(elements[1], Miscellaneous.getAnyContext());
|
||||
Miscellaneous.createDismissibleNotification(title, text, notificationId, false, AutomationService.NOTIFICATION_CHANNEL_ID_RULES, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "createNotification", "Error occurred while replacing vars: " + Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static void closeNotification(Action action)
|
||||
{
|
||||
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
for(StatusBarNotification n : nm.getActiveNotifications())
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = action.getParameter2().split(Action.actionParameter2Split);
|
||||
|
||||
String myApp = params[0];
|
||||
String myTitleDir = params[1];
|
||||
String requiredTitle = params[2];
|
||||
String myTextDir = params[3];
|
||||
String requiredText;
|
||||
if (params.length >= 5)
|
||||
requiredText = params[4];
|
||||
else
|
||||
requiredText = "";
|
||||
|
||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
||||
{
|
||||
NotificationListener.SimpleNotification sn = NotificationListener.convertNotificationToSimpleNotification(true, sbn);
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Checking if this notification should be closed in the context of rule " + action.getParentRule().getName() + ": "+ sn.toString(), 5);
|
||||
|
||||
if (!myApp.equals(Trigger.anyAppString))
|
||||
{
|
||||
if (!myApp.equalsIgnoreCase(sn.getApp()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification app name does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Notifications from Automation are disregarded to avoid infinite loops.
|
||||
*/
|
||||
if(myApp.equals(BuildConfig.APPLICATION_ID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If there are multiple notifications ("stacked") title or text might be null:
|
||||
https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications
|
||||
*/
|
||||
|
||||
// T I T L E
|
||||
if (!StringUtils.isEmpty(requiredTitle))
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, requiredTitle, sn.getTitle()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification title does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// T E X T
|
||||
if (!StringUtils.isEmpty(requiredText))
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, requiredText, sn.getText()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification text does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "All criteria matches. Closing notification: " + sbn.getNotification().toString(), 3);
|
||||
if(NotificationListener.getInstance() != null)
|
||||
NotificationListener.getInstance().dismissNotification(sbn);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "NotificationListener instance is null. Can\'t close notification.", 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendBroadcast(Context context, String action)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "sendBroadcast", "Sending broadcast with action " + action, 5);
|
||||
Intent broadcastIntent = new Intent();
|
||||
broadcastIntent.setAction(action);
|
||||
context.sendBroadcast(broadcastIntent);
|
||||
}
|
||||
|
||||
public static class WifiStuff
|
||||
{
|
||||
public static Boolean setWifi(Context context, Boolean desiredState, boolean toggleActionIfPossible)
|
||||
{
|
||||
@ -113,7 +234,7 @@ public class Actions
|
||||
Miscellaneous.logEvent("i", "Wifi", "Changing wifi to " + String.valueOf(desiredState), 4);
|
||||
|
||||
if (desiredState && Settings.useWifiForPositioning)
|
||||
WifiBroadcastReceiver.startWifiReceiver(autoMationServerRef.getLocationProvider());
|
||||
WifiBroadcastReceiver.startWifiReceiver(automationServerRef.getLocationProvider());
|
||||
|
||||
WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
|
||||
@ -304,6 +425,149 @@ public class Actions
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class BluetoothTetheringClass
|
||||
{
|
||||
static Object instance = null;
|
||||
static Method setTetheringOn = null;
|
||||
static Method isTetheringOn = null;
|
||||
static Object mutex = new Object();
|
||||
|
||||
public static Boolean setBluetoothTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Bluetooth Tethering", "Changing Bluetooth Tethering to " + String.valueOf(desiredState), 4);
|
||||
|
||||
// boolean state = isTetheringOn(context);
|
||||
|
||||
// if (toggleActionIfPossible)
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "Bluetooth Tethering", context.getResources().getString(R.string.toggling), 2);
|
||||
// desiredState = !state;
|
||||
// }
|
||||
|
||||
// if (((state && !desiredState) || (!state && desiredState)))
|
||||
// {
|
||||
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
Class<?> classBluetoothPan = null;
|
||||
Constructor<?> BTPanCtor = null;
|
||||
Object BTSrvInstance = null;
|
||||
Method mBTPanConnect = null;
|
||||
|
||||
String sClassName = "android.bluetooth.BluetoothPan";
|
||||
try
|
||||
{
|
||||
classBluetoothPan = Class.forName(sClassName);
|
||||
Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
|
||||
|
||||
ctor.setAccessible(true);
|
||||
// Set Tethering ON
|
||||
|
||||
Class[] paramSet = new Class[1];
|
||||
paramSet[0] = boolean.class;
|
||||
|
||||
synchronized (mutex)
|
||||
{
|
||||
setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);
|
||||
isTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", null);
|
||||
instance = ctor.newInstance(context, new BTPanServiceListener(context));
|
||||
}
|
||||
|
||||
classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
|
||||
mBTPanConnect = classBluetoothPan.getDeclaredMethod("connect", BluetoothDevice.class);
|
||||
BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
|
||||
BTPanCtor.setAccessible(true);
|
||||
BTSrvInstance = BTPanCtor.newInstance(context, new BTPanServiceListener(context));
|
||||
|
||||
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
|
||||
|
||||
// If there are paired devices
|
||||
if (pairedDevices.size() > 0)
|
||||
{
|
||||
// Loop through paired devices
|
||||
for (BluetoothDevice device : pairedDevices)
|
||||
{
|
||||
try
|
||||
{
|
||||
mBTPanConnect.invoke(BTSrvInstance, device);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch(InvocationTargetException e)
|
||||
{
|
||||
/*
|
||||
Exact error message: "Bluetooth binder is null"
|
||||
This means this device doesn't have bluetooth.
|
||||
*/
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", "Device probably doesn't have bluetooth. " + Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.deviceDoesNotHaveBluetooth), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class BTPanServiceListener implements BluetoothProfile.ServiceListener
|
||||
{
|
||||
private final Context context;
|
||||
|
||||
public BTPanServiceListener(final Context context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(final int profile, final BluetoothProfile proxy)
|
||||
{
|
||||
//Some code must be here or the compiler will optimize away this callback.
|
||||
|
||||
try
|
||||
{
|
||||
synchronized (mutex)
|
||||
{
|
||||
setTetheringOn.invoke(instance, true);
|
||||
if ((Boolean) isTetheringOn.invoke(instance, null))
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is on", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is off", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(final int profile)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean setUsbTethering(Context context2, Boolean desiredState, boolean toggleActionIfPossible)
|
||||
{
|
||||
//TODO:toggle not really implemented, yet
|
||||
@ -537,14 +801,14 @@ public class Actions
|
||||
|
||||
AudioManager myAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && desiredSoundSetting == AudioManager.RINGER_MODE_SILENT)
|
||||
{
|
||||
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, AudioManager.FLAG_PLAY_SOUND);
|
||||
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
|
||||
}
|
||||
else
|
||||
myAudioManager.setRingerMode(desiredSoundSetting);
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && desiredSoundSetting == AudioManager.RINGER_MODE_SILENT)
|
||||
// {
|
||||
// AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
// am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, AudioManager.FLAG_PLAY_SOUND);
|
||||
// am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
|
||||
// }
|
||||
// else
|
||||
myAudioManager.setRingerMode(desiredSoundSetting);
|
||||
}
|
||||
|
||||
private static String getIPAddressUsb(final boolean useIPv4)
|
||||
@ -780,7 +1044,7 @@ public class Actions
|
||||
// Pack intents
|
||||
for (int i = 3; i < params.length; i++)
|
||||
{
|
||||
String[] singleParam = params[i].split(Action.intentPairSeperator);
|
||||
String[] singleParam = params[i].split(Action.intentPairSeparator);
|
||||
|
||||
/*Class c = Class.forName(singleParam[0]);
|
||||
for(Method m : c.getMethods())
|
||||
@ -860,14 +1124,14 @@ public class Actions
|
||||
}
|
||||
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
|
||||
autoMationServerRef.startActivity(externalActivityIntent);
|
||||
automationServerRef.startActivity(externalActivityIntent);
|
||||
else
|
||||
autoMationServerRef.sendBroadcast(externalActivityIntent);
|
||||
automationServerRef.sendBroadcast(externalActivityIntent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "StartOtherApp", autoMationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
|
||||
Toast.makeText(autoMationServerRef, autoMationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("e", "StartOtherApp", automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
|
||||
Toast.makeText(automationServerRef, automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,7 +1188,7 @@ public class Actions
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, Actions.class), 0);
|
||||
SmsManager sms = SmsManager.getDefault();
|
||||
sms.sendTextMessage(phoneNumber, null, message, pi, null);
|
||||
sms.sendTextMessage(phoneNumber, null, textToSend, pi, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -945,23 +1209,96 @@ public class Actions
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
WakeLock wakeLock = pm.newWakeLock((WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
|
||||
wakeLock.acquire();
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(awakeTime);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
|
||||
}
|
||||
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
WakeLock wakeLock = pm.newWakeLock((PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
|
||||
wakeLock.acquire();
|
||||
|
||||
wakeLock.release();
|
||||
try
|
||||
{
|
||||
Thread.sleep(awakeTime);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
|
||||
}
|
||||
|
||||
wakeLock.release();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Wakeup device action", "Error while waking up device: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public static void turnOnScreen()
|
||||
{
|
||||
// turn on screen
|
||||
Miscellaneous.logEvent("i", "Actions", "Turning screen on.", 3);
|
||||
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
|
||||
wakeLock.acquire();
|
||||
}*/
|
||||
|
||||
@TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
|
||||
public static void turnOffScreen()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Actions", "Turning screen off.", 3);
|
||||
|
||||
|
||||
/*params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
params.screenBrightness = 0;
|
||||
getWindow().setAttributes(params);*/
|
||||
|
||||
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
|
||||
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
|
||||
// wakeLock.acquire();
|
||||
|
||||
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
|
||||
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , "tag");
|
||||
// wakeLock.acquire();
|
||||
|
||||
// wakeLock.release();
|
||||
lockScreen();
|
||||
}
|
||||
|
||||
public static void lockScreen()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Actions", "Locking screen.", 3);
|
||||
|
||||
// Works, but requires Manifest.permission.BIND_DEVICE_ADMIN
|
||||
// https://stackoverflow.com/questions/23898406/java-lang-securityexception-no-active-admin-owned-by-uid-10047-for-policy-4-on
|
||||
DevicePolicyManager deviceManager = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
deviceManager.lockNow();
|
||||
}
|
||||
|
||||
// using root
|
||||
/*private void turnOffScreen()
|
||||
{
|
||||
try
|
||||
{
|
||||
Class c = Class.forName("android.os.PowerManager");
|
||||
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
|
||||
for(Method m : c.getDeclaredMethods())
|
||||
{
|
||||
if(m.getName().equals("goToSleep"))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
if(m.getParameterTypes().length == 1)
|
||||
{
|
||||
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}*/
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@SuppressLint("NewApi")
|
||||
public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible)
|
||||
@ -978,7 +1315,7 @@ public class Actions
|
||||
|
||||
try
|
||||
{
|
||||
boolean isEnabled = ConnectivityReceiver.isAirplaneMode(autoMationServerRef);
|
||||
boolean isEnabled = ConnectivityReceiver.isAirplaneMode(automationServerRef);
|
||||
|
||||
if (isEnabled)
|
||||
Miscellaneous.logEvent("i", "Airplane mode", "Current status is enabled.", 4);
|
||||
@ -1092,7 +1429,7 @@ public class Actions
|
||||
try
|
||||
{
|
||||
String textToSpeak = Miscellaneous.replaceVariablesInText(parameter2, context);
|
||||
autoMationServerRef.speak(textToSpeak, true);
|
||||
automationServerRef.speak(textToSpeak, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -1122,23 +1459,7 @@ public class Actions
|
||||
playMusicIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(playMusicIntent);
|
||||
|
||||
// playMusicIntent = new Intent();
|
||||
// playMusicIntent.setAction(android.content.Intent.ACTION_VIEW);
|
||||
// File file = new File(YOUR_SONG_URI);
|
||||
// playMusicIntent.setDataAndType(Uri.fromFile(file), "audio/*");
|
||||
// context.startActivity(playMusicIntent);
|
||||
|
||||
return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(playMusicIntent != null)
|
||||
// {
|
||||
// context.stopService(playMusicIntent);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
}
|
||||
catch (ActivityNotFoundException e)
|
||||
{
|
||||
@ -1154,6 +1475,45 @@ public class Actions
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public static boolean controlMediaPlayback(Context context, int command)
|
||||
{
|
||||
int keyCode = -1;
|
||||
switch(command)
|
||||
{
|
||||
case 0:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
|
||||
break;
|
||||
case 1:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY;
|
||||
break;
|
||||
case 2:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE;
|
||||
break;
|
||||
case 3:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_STOP;
|
||||
break;
|
||||
case 4:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
|
||||
break;
|
||||
case 5:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
return controlMediaByDispatch(keyCode);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
static boolean controlMediaByDispatch(int keyCode)
|
||||
{
|
||||
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
|
||||
mAudioManager.dispatchMediaKeyEvent(event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getTransactionCode()
|
||||
{
|
||||
try
|
||||
@ -1267,7 +1627,7 @@ public class Actions
|
||||
{
|
||||
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1)
|
||||
{
|
||||
if(MobileDataStuff.setMobileNetworkFromAndroid9(desiredState, autoMationServerRef))
|
||||
if(MobileDataStuff.setMobileNetworkFromAndroid9(desiredState, automationServerRef))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
|
||||
return true;
|
||||
@ -1280,7 +1640,7 @@ public class Actions
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
|
||||
{
|
||||
if (MobileDataStuff.setMobileNetworkTillAndroid5(desiredState, autoMationServerRef))
|
||||
if (MobileDataStuff.setMobileNetworkTillAndroid5(desiredState, automationServerRef))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
|
||||
return true;
|
||||
@ -1293,7 +1653,7 @@ public class Actions
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MobileDataStuff.setMobileNetworkAndroid6Till8(desiredState, autoMationServerRef))
|
||||
if (MobileDataStuff.setMobileNetworkAndroid6Till8(desiredState, automationServerRef))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
|
||||
return true;
|
||||
|
@ -10,6 +10,7 @@ import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -20,8 +21,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ActivityMaintenance extends Activity
|
||||
public class ActivityControlCenter extends Activity
|
||||
{
|
||||
final static int requestCodeImport = 1001;
|
||||
final static int requestCodeExport = 1002;
|
||||
@ -30,13 +32,14 @@ public class ActivityMaintenance extends Activity
|
||||
final static String prefsFileName = "com.jens.automation2_preferences.xml";
|
||||
|
||||
TextView tvFileStoreLocation, tvAppVersion;
|
||||
Button bVolumeTest, bMoreSettings, bSettingsSetToDefault, bShareConfigAndLog, bImportConfiguration, bExportConfiguration;
|
||||
Button bVolumeTest, bMoreSettings, bSettingsSetToDefault, bSendEmailToDev, bImportConfiguration, bExportConfiguration;
|
||||
CheckBox chkShareConfigAndLog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_maintenance);
|
||||
setContentView(R.layout.activity_control_center);
|
||||
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new View.OnClickListener()
|
||||
@ -44,18 +47,25 @@ public class ActivityMaintenance extends Activity
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMaintenance.this, ActivityVolumeTest.class);
|
||||
Intent intent = new Intent(ActivityControlCenter.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
bShareConfigAndLog = (Button) findViewById(R.id.bShareConfigAndLog);
|
||||
bShareConfigAndLog.setOnClickListener(new View.OnClickListener()
|
||||
chkShareConfigAndLog = (CheckBox)findViewById(R.id.chkShareConfigAndLog);
|
||||
bSendEmailToDev = (Button) findViewById(R.id.bSendEmailToDev);
|
||||
bSendEmailToDev.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getShareConfigAndLogDialogue(ActivityMaintenance.this).show();
|
||||
if(chkShareConfigAndLog.isChecked())
|
||||
getShareConfigAndLogDialogue(ActivityControlCenter.this).show();
|
||||
else
|
||||
{
|
||||
String subject = "Automation";
|
||||
Miscellaneous.sendEmail(ActivityControlCenter.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -65,17 +75,17 @@ public class ActivityMaintenance extends Activity
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityMaintenance.this).show();
|
||||
getDefaultSettingsDialog(ActivityControlCenter.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
Button bMoreSettings = (Button) findViewById(R.id.bMoreSettings);
|
||||
bMoreSettings = (Button) findViewById(R.id.bMoreSettings);
|
||||
bMoreSettings.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityMaintenance.this, ActivitySettings.class);
|
||||
Intent myIntent = new Intent(ActivityControlCenter.this, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, requestCodeMoreSettings);
|
||||
}
|
||||
});
|
||||
@ -123,7 +133,7 @@ public class ActivityMaintenance extends Activity
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
AutomationService.getInstance().serviceInterface(AutomationService.serviceCommands.reloadSettings);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(ActivityMaintenance.this))
|
||||
if (AutomationService.isMyServiceRunning(ActivityControlCenter.this))
|
||||
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
@ -170,7 +180,7 @@ public class ActivityMaintenance extends Activity
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstRules))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.rulesImportError), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.rulesImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
else if (file.getName().equals(prefsFileName))
|
||||
@ -183,7 +193,7 @@ public class ActivityMaintenance extends Activity
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstPrefs))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.prefsImportError), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.prefsImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,33 +201,40 @@ public class ActivityMaintenance extends Activity
|
||||
if(applicableFilesFound > 0)
|
||||
{
|
||||
if(filesImported == 0)
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if(filesImported < applicableFilesFound)
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.notAllFilesImported), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.notAllFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if (filesImported == applicableFilesFound)
|
||||
{
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.configurationImportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.configurationImportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
|
||||
try
|
||||
{
|
||||
XmlFileInterface.readFile();
|
||||
ActivityMainPoi.getInstance().updateListView();
|
||||
ActivityMainRules.getInstance().updateListView();
|
||||
ActivityMainProfiles.getInstance().updateListView();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Reading import", "Rules re-read failed: " + Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.errorReadingPoisAndRulesFromFile), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.errorReadingPoisAndRulesFromFile), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
Settings.readFromPersistentStorage(ActivityMaintenance.this);
|
||||
Settings.readFromPersistentStorage(ActivityControlCenter.this);
|
||||
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if(service != null && service.isRunning)
|
||||
service.applySettingsAndRules();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
void exportFiles(Uri uriTree)
|
||||
@ -249,12 +266,12 @@ public class ActivityMaintenance extends Activity
|
||||
if(dstRules.canWrite() && dstPrefs.canWrite())
|
||||
{
|
||||
if(Miscellaneous.copyFileToDocumentFile(srcRules, dstRules) && Miscellaneous.copyFileToDocumentFile(srcPrefs, dstPrefs))
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.configurationExportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.configurationExportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||
@ -293,47 +310,76 @@ public class ActivityMaintenance extends Activity
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if((new File(logFilePath)).exists())
|
||||
if ((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if((new File(logFilePathArchive)).exists())
|
||||
if ((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
if(dstZipFile.exists())
|
||||
if (dstZipFile.exists())
|
||||
dstZipFile.delete();
|
||||
|
||||
Miscellaneous.zip(srcFiles, dstZipFile.getAbsolutePath());
|
||||
|
||||
/*
|
||||
Without root the zip file in the cache directory is not directly accessible.
|
||||
But have to route it through this content provider crap.
|
||||
*/
|
||||
/*
|
||||
Without root the zip file in the cache directory is not directly accessible.
|
||||
But have to route it through this content provider crap.
|
||||
*/
|
||||
|
||||
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);
|
||||
emailBody.append("Flavor: " + BuildConfig.FLAVOR);
|
||||
|
||||
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(ActivityControlCenter.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), uri);
|
||||
}
|
||||
});
|
||||
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public static String getSystemInfo()
|
||||
{
|
||||
StringBuilder systemInfoText = new StringBuilder();
|
||||
systemInfoText.append("App details" + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("Version name: " + BuildConfig.VERSION_NAME + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("Version code: " + BuildConfig.VERSION_CODE + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("Flavor: " + BuildConfig.FLAVOR + Miscellaneous.lineSeparator);
|
||||
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("Target SDK: " + Miscellaneous.getAnyContext().getApplicationInfo().targetSdkVersion + 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("Rooted: " + String.valueOf(Miscellaneous.isPhoneRooted()));
|
||||
systemInfoText.append("Country: " + Miscellaneous.getUserCountry(Miscellaneous.getAnyContext()) + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("OS language: " + Locale.getDefault().getDisplayName() + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("Logfile written: " + String.valueOf(Settings.writeLogFile) + Miscellaneous.lineSeparator);
|
||||
systemInfoText.append("Log level: " + String.valueOf(Settings.logLevel));
|
||||
|
||||
/*
|
||||
I've checked the Locale methods on my Android 4.1.2 device, and the results:
|
||||
|
||||
Locale.getDefault().getLanguage() ---> en
|
||||
Locale.getDefault().getISO3Language() ---> eng
|
||||
Locale.getDefault().getCountry() ---> US
|
||||
Locale.getDefault().getISO3Country() ---> USA
|
||||
Locale.getDefault().getDisplayCountry() ---> United States
|
||||
Locale.getDefault().getDisplayName() ---> English (United States)
|
||||
Locale.getDefault().toString() ---> en_US
|
||||
Locale.getDefault().getDisplayLanguage()---> English
|
||||
Locale.getDefault().toLanguageTag() ---> en-US
|
||||
*/
|
||||
|
||||
return systemInfoText.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
@ -360,7 +406,7 @@ public class ActivityMaintenance extends Activity
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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,12 +19,13 @@ 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
|
||||
{
|
||||
public static final String intentNameRuleName = "ruleName";
|
||||
private ListView ruleListView;
|
||||
ArrayList<Rule> ruleList = new ArrayList<>();
|
||||
private ArrayAdapter<Rule> ruleListViewAdapter;
|
||||
@ -135,7 +136,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
else
|
||||
holder = (RuleHolder) v.getTag();
|
||||
|
||||
System.out.println("Position ["+position+"]");
|
||||
// System.out.println("Position ["+position+"]");
|
||||
Rule r = Rule.getRuleCollection().get(position);
|
||||
holder.tvRuleName.setText(r.getName());
|
||||
if(r.isRuleActive())
|
||||
@ -199,6 +200,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ActivityMainRules", "Initiating manual execution of rule " + ruleThisIsAbout.getName(), 3);
|
||||
ruleThisIsAbout.activate(runContext, true);
|
||||
break;
|
||||
}
|
||||
@ -206,8 +208,8 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.serviceHasToRunForThat), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 1:
|
||||
ruleToEdit = ruleThisIsAbout;
|
||||
Intent manageSpecificRuleIntent = new Intent (ActivityMainRules.this, ActivityManageRule.class);
|
||||
manageSpecificRuleIntent.putExtra(intentNameRuleName, ruleThisIsAbout.getName());
|
||||
startActivityForResult(manageSpecificRuleIntent, requestCodeChangeRule);
|
||||
break;
|
||||
case 2:
|
||||
@ -250,15 +252,5 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
AlarmListener.reloadAlarms();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
// AlarmManager instance not prepared, yet.
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ package com.jens.automation2;
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@ -11,7 +10,6 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -29,29 +27,25 @@ 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;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainScreen extends ActivityGeneric
|
||||
{
|
||||
private static boolean guiChangeInProgress = false;
|
||||
static boolean guiChangeInProgress = false;
|
||||
static ActivityMainScreen activityMainScreenInstance = null;
|
||||
static boolean updateNoteDisplayed = false;
|
||||
static boolean uiUpdateRunning = false;
|
||||
|
||||
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||
private ToggleButton toggleService, tbLockSound;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration;
|
||||
private static boolean updateNoteDisplayed = false;
|
||||
ToggleButton toggleService, tbLockSound;
|
||||
Button bShowHelp, bPrivacy, bAddSoundLockTIme, bDonate, bControlCenter;
|
||||
TextView tvActivePoi, tvClosestPoi, tvLastRule, tvLastProfile, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvLockSoundDuration;
|
||||
|
||||
private ListView lvRuleHistory;
|
||||
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||
|
||||
private static boolean uiUpdateRunning = false;
|
||||
ListView lvRuleHistory;
|
||||
ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
@ -74,14 +68,21 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
tvActivePoi = (TextView) findViewById(R.id.tvActivePoi);
|
||||
tvClosestPoi = (TextView) findViewById(R.id.tvClosestPoi);
|
||||
lvRuleHistory = (ListView) findViewById(R.id.lvRuleHistory);
|
||||
tvLastRule = (TextView) findViewById(R.id.tvTimeFrameHelpText);
|
||||
tvLastRule = (TextView) findViewById(R.id.tvLastRule);
|
||||
tvLastProfile = (TextView)findViewById(R.id.tvLastProfile);
|
||||
tvMainScreenNotePermissions = (TextView) findViewById(R.id.tvMainScreenNotePermissions);
|
||||
tvMainScreenNoteFeaturesFromOtherFlavor = (TextView) findViewById(R.id.tvMainScreenNoteFeaturesFromOtherFlavor);
|
||||
tvMainScreenNoteLocationImpossibleBlameGoogle = (TextView) findViewById(R.id.tvMainScreenNoteLocationImpossibleBlameGoogle);
|
||||
tvMainScreenNoteNews = (TextView) findViewById(R.id.tvMainScreenNoteNews);
|
||||
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
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()
|
||||
{
|
||||
@ -93,7 +94,8 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
if (toggleService.isChecked())
|
||||
{
|
||||
startAutomationService(getBaseContext(), false);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
stopAutomationService();
|
||||
}
|
||||
@ -111,6 +113,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
|
||||
@ -129,13 +143,13 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
Button bSettings = (Button) findViewById(R.id.bSettings);
|
||||
bSettings.setOnClickListener(new OnClickListener()
|
||||
bControlCenter = (Button) findViewById(R.id.bControlCenter);
|
||||
bControlCenter.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivityMaintenance.class);
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivityControlCenter.class);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
});
|
||||
@ -352,6 +366,16 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
{
|
||||
activityMainScreenInstance.tvLastRule.setText("n./a.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
activityMainScreenInstance.tvLastProfile.setText(Profile.getLastActivatedProfile().getName());
|
||||
activityMainScreenInstance.updateListView();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
activityMainScreenInstance.tvLastProfile.setText("n./a.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -360,6 +384,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.serviceNotRunning));
|
||||
activityMainScreenInstance.tvClosestPoi.setText("");
|
||||
activityMainScreenInstance.tvLastRule.setText("");
|
||||
activityMainScreenInstance.tvLastProfile.setText("");
|
||||
}
|
||||
|
||||
// uiUpdateRunning = true;
|
||||
@ -377,21 +402,21 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
long millis = end.getTimeInMillis() - now.getTimeInMillis();
|
||||
long minutes = millis/1000/60;
|
||||
if(minutes < 60)
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(minutes + " min..."));
|
||||
activityMainScreenInstance.tvLockSoundDuration.setText(String.valueOf(minutes + " min..."));
|
||||
else
|
||||
{
|
||||
double hours = (double)minutes / 60.0;
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(Math.round(hours * 100.0) / 100.0) + " h...");
|
||||
activityMainScreenInstance.tvLockSoundDuration.setText(String.valueOf(Math.round(hours * 100.0) / 100.0) + " h...");
|
||||
}
|
||||
}
|
||||
else
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(""));
|
||||
activityMainScreenInstance.tvLockSoundDuration.setText(String.valueOf(""));
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tbLockSound.setChecked(false);
|
||||
activityMainScreenInstance.tbLockSound.setEnabled(false);
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText("");
|
||||
activityMainScreenInstance.tvLockSoundDuration.setText("");
|
||||
}
|
||||
Settings.writeSettings(activityMainScreenInstance);
|
||||
// uiUpdateRunning = false;
|
||||
|
@ -72,4 +72,4 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
// setIntent(intent);
|
||||
NfcReceiver.checkIntentForNFC(this, intent);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,10 +10,13 @@ import android.widget.CompoundButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ActivityManageActionBrightnessSetting extends Activity
|
||||
{
|
||||
public static final String intentNameAutoBrightness = "autoBrightness";
|
||||
public static final String intentNameBrightnessValue = "brightnessValue";
|
||||
|
||||
CheckBox chkAutoBrightness;
|
||||
SeekBar sbBrightness;
|
||||
Button bApplyBrightness;
|
||||
@ -22,7 +25,7 @@ public class ActivityManageActionBrightnessSetting extends Activity
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
setContentView(R.layout.activity_manage_brightness_setting);
|
||||
setContentView(R.layout.activity_manage_action_brightness_settings);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
|
||||
@ -32,11 +35,11 @@ public class ActivityManageActionBrightnessSetting extends Activity
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra("autoBrightness"))
|
||||
chkAutoBrightness.setChecked(input.getBooleanExtra("autoBrightness", false));
|
||||
if(input.hasExtra(intentNameAutoBrightness))
|
||||
chkAutoBrightness.setChecked(input.getBooleanExtra(intentNameAutoBrightness, false));
|
||||
|
||||
if(input.hasExtra("brightnessValue"))
|
||||
sbBrightness.setProgress(input.getIntExtra("brightnessValue", 0));
|
||||
if(input.hasExtra(intentNameBrightnessValue))
|
||||
sbBrightness.setProgress(input.getIntExtra(intentNameBrightnessValue, 0));
|
||||
|
||||
bApplyBrightness.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@ -44,8 +47,8 @@ public class ActivityManageActionBrightnessSetting extends Activity
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra("autoBrightness", chkAutoBrightness.isChecked());
|
||||
answer.putExtra("brightnessValue", sbBrightness.getProgress());
|
||||
answer.putExtra(intentNameAutoBrightness, chkAutoBrightness.isChecked());
|
||||
answer.putExtra(intentNameBrightnessValue, sbBrightness.getProgress());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
|
@ -0,0 +1,393 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageActionCloseNotification 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";
|
||||
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
EditText etNotificationTitle, etNotificationText;
|
||||
Button bSelectApp, bSaveActionCloseNotification;
|
||||
Spinner spinnerTitleDirection, spinnerTextDirection;
|
||||
TextView tvSelectedApplication;
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
|
||||
private static String[] directions;
|
||||
|
||||
ArrayAdapter<String> directionSpinnerAdapter;
|
||||
|
||||
public static void getActivityList(final Context context)
|
||||
{
|
||||
if(pInfos == null)
|
||||
{
|
||||
pInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
|
||||
Collections.sort(pInfos, new Comparator<PackageInfo>()
|
||||
{
|
||||
public int compare(PackageInfo obj1, PackageInfo obj2)
|
||||
{
|
||||
String name1 = "";
|
||||
String name2 = "";
|
||||
|
||||
ApplicationInfo aInfo1 = obj1.applicationInfo;
|
||||
if (aInfo1 != null)
|
||||
{
|
||||
name1 = (String) context.getPackageManager().getApplicationLabel(aInfo1);
|
||||
}
|
||||
ApplicationInfo aInfo2 = obj2.applicationInfo;
|
||||
if (aInfo2 != null)
|
||||
{
|
||||
name2 = (String) context.getPackageManager().getApplicationLabel(aInfo2);
|
||||
}
|
||||
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getApplicationNameListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ApplicationInfo aInfo = pInfo.applicationInfo;
|
||||
if (aInfo != null)
|
||||
{
|
||||
String aLabel;
|
||||
|
||||
aLabel = (String) myContext.getPackageManager().getApplicationLabel(aInfo);
|
||||
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0) // Only put Applications into the list that have packages.
|
||||
{
|
||||
if(!returnList.contains(aLabel))
|
||||
returnList.add(aLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext, String applicationLabel)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo).equals(applicationLabel))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Empty Application", "Application " + myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo) + " doesn\'t have packages.", 5);
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getActivityListForPackageName(String packageName)
|
||||
{
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
returnList.add(activityInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static ActivityInfo getActivityInfoForPackageNameAndActivityName(String packageName, String activityName)
|
||||
{
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
if(activityInfo.name.equals(activityName))
|
||||
return activityInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AlertDialog getActionStartActivityDialog1()
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
|
||||
final String[] applicationArray = ActivityManageActionCloseNotification.getApplicationNameListString(this);
|
||||
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
getActionStartActivityDialog2(applicationArray[which]).show();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog2(String applicationName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageActionCloseNotification.getPackageListString(this, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, 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), ActivityManageNotificationTrigger.this).show();
|
||||
tvSelectedApplication.setText(packageArray[which]);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog3(final String packageName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
|
||||
final String activityArray[] = ActivityManageActionCloseNotification.getActivityListForPackageName(packageName);
|
||||
alertDialogBuilder.setItems(activityArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageActionCloseNotification.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
tvSelectedApplication.setText(ai.packageName + ";" + ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_action_close_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bSaveActionCloseNotification = (Button)findViewById(R.id.bSaveActionCloseNotification);
|
||||
spinnerTitleDirection = (Spinner)findViewById(R.id.spinnerTitleDirection);
|
||||
spinnerTextDirection = (Spinner)findViewById(R.id.spinnerTextDirection);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etActivityOrActionPath);
|
||||
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringDoesNotContain),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
};
|
||||
|
||||
directionSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionCloseNotification.directions);
|
||||
spinnerTitleDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerTextDirection.setAdapter(directionSpinnerAdapter);
|
||||
directionSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageActionCloseNotification.this, "", ActivityManageActionCloseNotification.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
});
|
||||
|
||||
bSaveActionCloseNotification.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
String app;
|
||||
if(tvSelectedApplication.getText().toString().equalsIgnoreCase(getResources().getString(R.string.anyApp)))
|
||||
app = Trigger.anyAppString;
|
||||
else
|
||||
app = tvSelectedApplication.getText().toString();
|
||||
|
||||
String titleDir = Trigger.getMatchCode(spinnerTitleDirection.getSelectedItem().toString());
|
||||
String title = etNotificationTitle.getText().toString();
|
||||
String textDir = Trigger.getMatchCode(spinnerTextDirection.getSelectedItem().toString());
|
||||
String text = etNotificationText.getText().toString();
|
||||
|
||||
Intent responseData = new Intent();
|
||||
if(edit)
|
||||
{
|
||||
// editedNotificationAction.setTriggerParameter(chkNotificationDirection.isChecked());
|
||||
responseData.putExtra(ActivityManageRule.intentNameActionParameter2, app + Action.actionParameter2Split + titleDir + Action.actionParameter2Split + title + Action.actionParameter2Split + textDir + Action.actionParameter2Split + text);
|
||||
ActivityManageActionCloseNotification.this.setResult(RESULT_OK, responseData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// data.putExtra(intentNameNotificationDirection, chkNotificationDirection.isChecked());
|
||||
responseData.putExtra(ActivityManageRule.intentNameActionParameter2,
|
||||
app + Action.actionParameter2Split +
|
||||
titleDir + Action.actionParameter2Split +
|
||||
title + Action.actionParameter2Split +
|
||||
textDir + Action.actionParameter2Split +
|
||||
text
|
||||
);
|
||||
// data.putExtra(intentNameNotificationApp, app);
|
||||
// data.putExtra(intentNameNotificationTitleDir, titleDir);
|
||||
// data.putExtra(intentNameNotificationTitle, title);
|
||||
// data.putExtra(intentNameNotificationTextDir, textDir);
|
||||
// data.putExtra(intentNameNotificationText, text);
|
||||
ActivityManageActionCloseNotification.this.setResult(RESULT_OK, responseData);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(!StringUtils.isBlank(i.getStringExtra(ActivityManageRule.intentNameActionParameter2)))
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui(i.getStringExtra(ActivityManageRule.intentNameActionParameter2));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui(String param)
|
||||
{
|
||||
String[] params = param.split(Action.actionParameter2Split);
|
||||
|
||||
String app = params[0];
|
||||
String titleDir = params[1];
|
||||
String title = params[2];
|
||||
String textDir = params[3];
|
||||
String text;
|
||||
if (params.length >= 5)
|
||||
text = params[4];
|
||||
else
|
||||
text = "";
|
||||
|
||||
if(!app.equals(Trigger.anyAppString))
|
||||
tvSelectedApplication.setText(app);
|
||||
|
||||
for(int i = 0; i < directions.length; i++)
|
||||
{
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(titleDir))
|
||||
spinnerTitleDirection.setSelection(i);
|
||||
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(textDir))
|
||||
spinnerTextDirection.setSelection(i);
|
||||
}
|
||||
|
||||
if(title.length() > 0)
|
||||
etNotificationTitle.setText(title);
|
||||
|
||||
if(text.length() > 0)
|
||||
etNotificationText.setText(text);
|
||||
}
|
||||
|
||||
private class GetActivityListTask extends AsyncTask<Void, Void, Void>
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
getActivityList(ActivityManageActionCloseNotification.this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageActionControlMedia extends Activity
|
||||
{
|
||||
RadioButton rbMediaPlayPause, rbMediaPlay, rbMediaPause, rbMediaStop, rbMediaPrevious, rbMediaNext;
|
||||
Button bSaveControlMediaAction;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_action_control_media);
|
||||
|
||||
rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause);
|
||||
rbMediaPlay = (RadioButton)findViewById(R.id.rbMediaPlay);
|
||||
rbMediaPause = (RadioButton)findViewById(R.id.rbMediaPause);
|
||||
rbMediaStop = (RadioButton)findViewById(R.id.rbMediaStop);
|
||||
rbMediaPrevious = (RadioButton)findViewById(R.id.rbMediaPrevious);
|
||||
rbMediaNext = (RadioButton)findViewById(R.id.rbMediaNext);
|
||||
|
||||
bSaveControlMediaAction = (Button)findViewById(R.id.bSaveControlMediaAction);
|
||||
|
||||
bSaveControlMediaAction.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
|
||||
if(rbMediaPlayPause.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "0");
|
||||
else if(rbMediaPlay.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "1");
|
||||
else if(rbMediaPause.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "2");
|
||||
else if(rbMediaStop.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "3");
|
||||
else if(rbMediaPrevious.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "4");
|
||||
else if(rbMediaNext.isChecked())
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, "5");
|
||||
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String existing = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
switch (existing)
|
||||
{
|
||||
case "0":
|
||||
rbMediaPlayPause.setChecked(true);
|
||||
break;
|
||||
case "1":
|
||||
rbMediaPlay.setChecked(true);
|
||||
break;
|
||||
case "2":
|
||||
rbMediaPause.setChecked(true);
|
||||
break;
|
||||
case "3":
|
||||
rbMediaStop.setChecked(true);
|
||||
break;
|
||||
case "4":
|
||||
rbMediaPrevious.setChecked(true);
|
||||
break;
|
||||
case "5":
|
||||
rbMediaNext.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean checkInput()
|
||||
{
|
||||
if(
|
||||
!rbMediaPlayPause.isChecked()
|
||||
&&
|
||||
!rbMediaPlay.isChecked()
|
||||
&&
|
||||
!rbMediaPause.isChecked()
|
||||
&&
|
||||
!rbMediaStop.isChecked()
|
||||
&&
|
||||
!rbMediaPrevious.isChecked()
|
||||
&&
|
||||
!rbMediaNext.isChecked()
|
||||
)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionControlMedia.this, getResources().getString(R.string.pleaseSelectActionValue), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionCreateNotification extends Activity
|
||||
{
|
||||
public static final String intentNameNotificationTitle = "notificationTitle";
|
||||
public static final String intentNameNotificationText = "notificationText";
|
||||
|
||||
EditText etNotificationTitle, etNotificationText;
|
||||
Button bSaveActionNotification;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_action_create_notification);
|
||||
|
||||
etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle);
|
||||
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
|
||||
bSaveActionNotification = (Button)findViewById(R.id.bSaveActionNotification);
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(intentNameNotificationTitle))
|
||||
etNotificationTitle.setText(input.getStringExtra(intentNameNotificationTitle));
|
||||
|
||||
if(input.hasExtra(intentNameNotificationText))
|
||||
etNotificationText.setText(input.getStringExtra(intentNameNotificationText));
|
||||
|
||||
bSaveActionNotification.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(StringUtils.isBlank(etNotificationTitle.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionCreateNotification.this, getResources().getString(R.string.enterTitle), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(StringUtils.isBlank(etNotificationText.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionCreateNotification.this, getResources().getString(R.string.enterText), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra(intentNameNotificationTitle, etNotificationTitle.getText().toString());
|
||||
answer.putExtra(intentNameNotificationText, etNotificationText.getText().toString());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionSendBroadcast extends Activity
|
||||
{
|
||||
EditText etBroadcastToSend;
|
||||
Button bBroadcastSendShowSuggestions, bSaveSendBroadcast;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_action_send_broadcast);
|
||||
|
||||
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
|
||||
bBroadcastSendShowSuggestions = (Button)findViewById(R.id.bBroadcastSendShowSuggestions);
|
||||
bSaveSendBroadcast = (Button)findViewById(R.id.bSaveSendBroadcast);
|
||||
|
||||
bSaveSendBroadcast.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, etBroadcastToSend.getText().toString());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bBroadcastSendShowSuggestions.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageActionSendBroadcast.this);
|
||||
builder.setTitle(getResources().getString(R.string.selectBroadcast));
|
||||
builder.setItems(ActivityManageTriggerBroadcast.broadcastSuggestions, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int which)
|
||||
{
|
||||
etBroadcastToSend.setText(ActivityManageTriggerBroadcast.broadcastSuggestions[which]);
|
||||
}
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
});
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
etBroadcastToSend.setText(input.getStringExtra(ActivityManageRule.intentNameActionParameter2));
|
||||
}
|
||||
|
||||
boolean checkInput()
|
||||
{
|
||||
String broadcastToSend = etBroadcastToSend.getText().toString();
|
||||
if(StringUtils.isEmpty(broadcastToSend))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterBroadcast), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@ -59,7 +60,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();
|
||||
}
|
||||
});
|
||||
|
||||
@ -123,7 +124,7 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
{
|
||||
for(int i=0; i<permissions.length; i++)
|
||||
{
|
||||
if(permissions[i].equals("android.permission.READ_CONTACTS"))
|
||||
if(permissions[i].equals(Manifest.permission.READ_CONTACTS))
|
||||
{
|
||||
if(grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
@ -12,6 +13,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.MotionEvent;
|
||||
@ -30,6 +32,8 @@ import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -54,6 +58,8 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
|
||||
final static String startByActivityString = "0";
|
||||
final static String startByBroadcastString = "1";
|
||||
|
||||
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
|
||||
|
||||
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
|
||||
{
|
||||
@ -230,44 +236,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,10 +334,16 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
void getAppList()
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
@ -320,9 +377,19 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
int targetSdkVersion = getApplicationContext().getApplicationInfo().targetSdkVersion;
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && targetSdkVersion >= 30 && !ActivityPermissions.havePermission(Manifest.permission.QUERY_ALL_PACKAGES, ActivityManageActionStartActivity.this))// && shouldShowRequestPermissionRationale(Manifest.permission.QUERY_ALL_PACKAGES))
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equals("googlePlayFlavor"))
|
||||
{
|
||||
// This ain't possible anymore.
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.featureNotInGooglePlayVersion) + Miscellaneous.lineSeparator + Miscellaneous.lineSeparator + getResources().getString(R.string.startActivityInsertManually), ActivityManageActionStartActivity.this).show();
|
||||
}
|
||||
else
|
||||
requestPermissions(new String[] {Manifest.permission.QUERY_ALL_PACKAGES}, requestCodeForRequestQueryAllPackagesPermission);
|
||||
}
|
||||
else
|
||||
getAppList();
|
||||
}
|
||||
});
|
||||
|
||||
@ -343,9 +410,9 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(Action.intentPairSeperator))
|
||||
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeperator), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(";"))
|
||||
@ -359,9 +426,9 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(Action.intentPairSeperator))
|
||||
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeperator), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(";"))
|
||||
@ -370,7 +437,7 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
return;
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeperator + etParameterName.getText().toString() + Action.intentPairSeperator + etParameterValue.getText().toString();
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
@ -598,7 +665,6 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@ -615,9 +681,25 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
getActionStartActivityDialog1Application().show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
if(requestCode == requestCodeForRequestQueryAllPackagesPermission)
|
||||
{
|
||||
for(int i = 0; i < permissions.length; i++)
|
||||
{
|
||||
if(permissions[i].equals(Manifest.permission.QUERY_ALL_PACKAGES) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
getAppList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
@ -33,7 +34,6 @@ public class ActivityManagePoi extends Activity
|
||||
public LocationManager myLocationManager;
|
||||
MyLocationListenerGps myLocationListenerGps = new MyLocationListenerGps();
|
||||
Location locationGps = null, locationNetwork = null;
|
||||
// Location locationWifi = null;
|
||||
MyLocationListenerNetwork myLocationListenerNetwork = new MyLocationListenerNetwork();
|
||||
Button bGetPosition, bSavePoi;
|
||||
ImageButton ibShowOnMap;
|
||||
@ -83,17 +83,17 @@ public class ActivityManagePoi extends Activity
|
||||
bSavePoi = (Button)findViewById(R.id.bSavePoi);
|
||||
bSavePoi.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
hideKeyboard();
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
hideKeyboard();
|
||||
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
createPoi();
|
||||
else
|
||||
changePoi();
|
||||
}
|
||||
});
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
createPoi();
|
||||
else
|
||||
changePoi();
|
||||
}
|
||||
});
|
||||
|
||||
ibShowOnMap.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@ -136,42 +136,45 @@ public class ActivityManagePoi extends Activity
|
||||
|
||||
private void getLocation()
|
||||
{
|
||||
Criteria critNetwork = new Criteria();
|
||||
critNetwork.setPowerRequirement(Criteria.POWER_LOW);
|
||||
critNetwork.setAltitudeRequired(false);
|
||||
critNetwork.setSpeedRequired(false);
|
||||
critNetwork.setBearingRequired(false);
|
||||
critNetwork.setCostAllowed(false);
|
||||
critNetwork.setAccuracy(Criteria.ACCURACY_COARSE);
|
||||
Criteria criteriaNetwork = new Criteria();
|
||||
criteriaNetwork.setPowerRequirement(Criteria.POWER_LOW);
|
||||
criteriaNetwork.setAltitudeRequired(false);
|
||||
criteriaNetwork.setSpeedRequired(false);
|
||||
criteriaNetwork.setBearingRequired(false);
|
||||
criteriaNetwork.setCostAllowed(false);
|
||||
criteriaNetwork.setAccuracy(Criteria.ACCURACY_COARSE);
|
||||
|
||||
Criteria criteriaGps = new Criteria();
|
||||
criteriaGps.setAltitudeRequired(false);
|
||||
criteriaGps.setSpeedRequired(false);
|
||||
criteriaGps.setBearingRequired(false);
|
||||
criteriaGps.setCostAllowed(true);
|
||||
criteriaGps.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
|
||||
Criteria critGps = new Criteria();
|
||||
critGps.setAltitudeRequired(false);
|
||||
critGps.setSpeedRequired(false);
|
||||
critGps.setBearingRequired(false);
|
||||
critGps.setCostAllowed(true);
|
||||
critGps.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
|
||||
String provider1 = myLocationManager.getBestProvider(critNetwork, true);
|
||||
String provider2 = myLocationManager.getBestProvider(critGps, true);
|
||||
String provider1 = myLocationManager.getBestProvider(criteriaNetwork, true);
|
||||
String provider2 = myLocationManager.getBestProvider(criteriaGps, true);
|
||||
// String provider3 = myLocationManager.getProvider("wifi");
|
||||
|
||||
if(provider1 == null | provider2 == null)
|
||||
if(provider1 == null || provider2 == null)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.logNoSuitableProvider), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(provider1.equals(provider2))
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Both location providers are equal. Only one will be used.", 4);
|
||||
|
||||
locationSearchStart = Calendar.getInstance();
|
||||
startTimeout();
|
||||
|
||||
if(!Settings.privacyLocationing || !ConnectivityReceiver.isDataConnectionAvailable(AutomationService.getInstance()))
|
||||
if(!Settings.privacyLocationing && !ConnectivityReceiver.isDataConnectionAvailable(Miscellaneous.getAnyContext()) && !provider1.equals(provider2))
|
||||
{
|
||||
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", "Skipping network location.", 4);
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider2, 3);
|
||||
myLocationManager.requestLocationUpdates(provider2, 500, Settings.satisfactoryAccuracyGps, myLocationListenerGps);
|
||||
@ -310,7 +313,21 @@ public class ActivityManagePoi extends Activity
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
|
||||
getLocation();
|
||||
if(Build.VERSION.SDK_INT >= 31)
|
||||
{
|
||||
AlertDialog dia = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.locationNotWorkingOn12), ActivityManagePoi.this);
|
||||
dia.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
getLocation();
|
||||
}
|
||||
});
|
||||
dia.show();
|
||||
}
|
||||
else
|
||||
getLocation();
|
||||
}
|
||||
};
|
||||
alertDialogBuilder.setMessage(text).setPositiveButton("Ok", dialogClickListener);
|
||||
|
@ -44,6 +44,8 @@ public class ActivityManageProfile extends Activity
|
||||
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
|
||||
TextView tvIncomingCallsRingtone, tvNotificationsRingtone;
|
||||
EditText etName;
|
||||
|
||||
boolean guiUpdate = false;
|
||||
|
||||
File incomingCallsRingtone = null, notificationsRingtone = null;
|
||||
|
||||
@ -368,6 +370,8 @@ public class ActivityManageProfile extends Activity
|
||||
|
||||
public void editProfile(Profile profileToEdit)
|
||||
{
|
||||
guiUpdate = true;
|
||||
|
||||
etName.setText(ActivityMainProfiles.profileToEdit.getName());
|
||||
checkBoxChangeSoundMode.setChecked(ActivityMainProfiles.profileToEdit.getChangeSoundMode());
|
||||
checkBoxChangeDnd.setChecked(ActivityMainProfiles.profileToEdit.getChangeDndMode());
|
||||
@ -393,6 +397,8 @@ public class ActivityManageProfile extends Activity
|
||||
|
||||
setIncomingCallsRingtone(ActivityMainProfiles.profileToEdit.getIncomingCallsRingtone());
|
||||
setNotificationsRingtone(ActivityMainProfiles.profileToEdit.getNotificationRingtone());
|
||||
|
||||
guiUpdate = false;
|
||||
}
|
||||
|
||||
private boolean loadFormValuesToVariable()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,421 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageTriggerBroadcast extends Activity
|
||||
{
|
||||
RadioButton rbBroadcastReceived, rbBroadcastNotReceived;
|
||||
EditText etBroadcastTriggerAction;
|
||||
Button bBroadcastShowSuggestions, bSaveTriggerBroadcast;
|
||||
TextView tvBroadcastUrl;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_trigger_broadcasts);
|
||||
|
||||
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
|
||||
bSaveTriggerBroadcast = findViewById(R.id.bSaveTriggerBroadcast);
|
||||
etBroadcastTriggerAction = findViewById(R.id.etBroadcastTriggerAction);
|
||||
rbBroadcastReceived = findViewById(R.id.rbBroadcastReceived);
|
||||
rbBroadcastNotReceived = findViewById(R.id.rbBroadcastNotReceived);
|
||||
tvBroadcastUrl = findViewById(R.id.tvBroadcastUrl);
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter1) && getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
if(getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true))
|
||||
rbBroadcastReceived.setChecked(true);
|
||||
else
|
||||
rbBroadcastNotReceived.setChecked(true);
|
||||
|
||||
etBroadcastTriggerAction.setText(getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
|
||||
}
|
||||
|
||||
tvBroadcastUrl.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getResources().getString(R.string.broadcastListUrl)));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
bBroadcastShowSuggestions.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerBroadcast.this);
|
||||
builder.setTitle(getResources().getString(R.string.selectBroadcast));
|
||||
builder.setItems(broadcastSuggestions, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int which)
|
||||
{
|
||||
etBroadcastTriggerAction.setText(broadcastSuggestions[which]);
|
||||
}
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
});
|
||||
|
||||
bSaveTriggerBroadcast.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(etBroadcastTriggerAction.getText() != null && !StringUtils.isEmpty(etBroadcastTriggerAction.getText().toString()))
|
||||
{
|
||||
Intent data = new Intent();
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbBroadcastReceived.isChecked());
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, etBroadcastTriggerAction.getText().toString());
|
||||
ActivityManageTriggerBroadcast.this.setResult(RESULT_OK, data);
|
||||
|
||||
finish();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityManageTriggerBroadcast.this, getResources().getString(R.string.enterText), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String[] broadcastSuggestions = {
|
||||
"android.accounts.LOGIN_ACCOUNTS_CHANGED",
|
||||
"android.accounts.action.ACCOUNT_REMOVED",
|
||||
"android.app.action.ACTION_PASSWORD_CHANGED",
|
||||
"android.app.action.ACTION_PASSWORD_EXPIRING",
|
||||
"android.app.action.ACTION_PASSWORD_FAILED",
|
||||
"android.app.action.ACTION_PASSWORD_SUCCEEDED",
|
||||
"android.app.action.AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE",
|
||||
"android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED",
|
||||
"android.app.action.APP_BLOCK_STATE_CHANGED",
|
||||
"android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED",
|
||||
"android.app.action.BUGREPORT_FAILED",
|
||||
"android.app.action.BUGREPORT_SHARE",
|
||||
"android.app.action.BUGREPORT_SHARING_DECLINED",
|
||||
"android.app.action.DATA_SHARING_RESTRICTION_APPLIED",
|
||||
"android.app.action.DATA_SHARING_RESTRICTION_CHANGED",
|
||||
"android.app.action.DEVICE_ADMIN_DISABLED",
|
||||
"android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED",
|
||||
"android.app.action.DEVICE_ADMIN_ENABLED",
|
||||
"android.app.action.DEVICE_OWNER_CHANGED",
|
||||
"android.app.action.INTERRUPTION_FILTER_CHANGED",
|
||||
"android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL",
|
||||
"android.app.action.LOCK_TASK_ENTERING",
|
||||
"android.app.action.LOCK_TASK_EXITING",
|
||||
"android.app.action.MANAGED_USER_CREATED",
|
||||
"android.app.action.NETWORK_LOGS_AVAILABLE",
|
||||
"android.app.action.NEXT_ALARM_CLOCK_CHANGED",
|
||||
"android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED",
|
||||
"android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED",
|
||||
"android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED",
|
||||
"android.app.action.NOTIFICATION_POLICY_CHANGED",
|
||||
"android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE",
|
||||
"android.app.action.PROFILE_OWNER_CHANGED",
|
||||
"android.app.action.PROFILE_PROVISIONING_COMPLETE",
|
||||
"android.app.action.SECURITY_LOGS_AVAILABLE",
|
||||
"android.app.action.SYSTEM_UPDATE_POLICY_CHANGED",
|
||||
"android.app.action.TRANSFER_OWNERSHIP_COMPLETE",
|
||||
"android.app.action.USER_ADDED",
|
||||
"android.app.action.USER_REMOVED",
|
||||
"android.app.action.USER_STARTED",
|
||||
"android.app.action.USER_STOPPED",
|
||||
"android.app.action.USER_SWITCHED",
|
||||
"android.appwidget.action.APPWIDGET_DELETED",
|
||||
"android.appwidget.action.APPWIDGET_DISABLED",
|
||||
"android.appwidget.action.APPWIDGET_ENABLED",
|
||||
"android.appwidget.action.APPWIDGET_HOST_RESTORED",
|
||||
"android.appwidget.action.APPWIDGET_RESTORED",
|
||||
"android.appwidget.action.APPWIDGET_UPDATE",
|
||||
"android.appwidget.action.APPWIDGET_UPDATE_OPTIONS",
|
||||
"android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED",
|
||||
"android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED",
|
||||
"android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED",
|
||||
"android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.adapter.action.DISCOVERY_FINISHED",
|
||||
"android.bluetooth.adapter.action.DISCOVERY_STARTED",
|
||||
"android.bluetooth.adapter.action.LOCAL_NAME_CHANGED",
|
||||
"android.bluetooth.adapter.action.SCAN_MODE_CHANGED",
|
||||
"android.bluetooth.adapter.action.STATE_CHANGED",
|
||||
"android.bluetooth.device.action.ACL_CONNECTED",
|
||||
"android.bluetooth.device.action.ACL_DISCONNECTED",
|
||||
"android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED",
|
||||
"android.bluetooth.device.action.ALIAS_CHANGED",
|
||||
"android.bluetooth.device.action.BATTERY_LEVEL_CHANGED",
|
||||
"android.bluetooth.device.action.BOND_STATE_CHANGED",
|
||||
"android.bluetooth.device.action.CLASS_CHANGED",
|
||||
"android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL",
|
||||
"android.bluetooth.device.action.CONNECTION_ACCESS_REPLY",
|
||||
"android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST",
|
||||
"android.bluetooth.device.action.FOUND",
|
||||
"android.bluetooth.device.action.MAS_INSTANCE",
|
||||
"android.bluetooth.device.action.NAME_CHANGED",
|
||||
"android.bluetooth.device.action.NAME_FAILED",
|
||||
"android.bluetooth.device.action.PAIRING_CANCEL",
|
||||
"android.bluetooth.device.action.PAIRING_REQUEST",
|
||||
"android.bluetooth.device.action.SDP_RECORD",
|
||||
"android.bluetooth.device.action.SILENCE_MODE_CHANGED",
|
||||
"android.bluetooth.device.action.UUID",
|
||||
"android.bluetooth.devicepicker.action.DEVICE_SELECTED",
|
||||
"android.bluetooth.devicepicker.action.LAUNCH",
|
||||
"android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT",
|
||||
"android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED",
|
||||
"android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED",
|
||||
"android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED",
|
||||
"android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.input.profile.action.HANDSHAKE",
|
||||
"android.bluetooth.input.profile.action.IDLE_TIME_CHANGED",
|
||||
"android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED",
|
||||
"android.bluetooth.input.profile.action.REPORT",
|
||||
"android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS",
|
||||
"android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED",
|
||||
"android.content.pm.action.SESSION_COMMITTED",
|
||||
"android.content.pm.action.SESSION_UPDATED",
|
||||
"android.hardware.action.NEW_PICTURE",
|
||||
"android.hardware.action.NEW_VIDEO",
|
||||
"android.hardware.hdmi.action.OSD_MESSAGE",
|
||||
"android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS",
|
||||
"android.hardware.usb.action.USB_ACCESSORY_ATTACHED",
|
||||
"android.hardware.usb.action.USB_ACCESSORY_DETACHED",
|
||||
"android.hardware.usb.action.USB_DEVICE_ATTACHED",
|
||||
"android.hardware.usb.action.USB_DEVICE_DETACHED",
|
||||
"android.intent.action.ACTION_IDLE_MAINTENANCE_END",
|
||||
"android.intent.action.ACTION_IDLE_MAINTENANCE_START",
|
||||
"android.intent.action.ACTION_POWER_CONNECTED",
|
||||
"android.intent.action.ACTION_POWER_DISCONNECTED",
|
||||
"android.intent.action.ACTION_PREFERRED_ACTIVITY_CHANGED",
|
||||
"android.intent.action.ACTION_SHUTDOWN",
|
||||
"android.intent.action.AIRPLANE_MODE",
|
||||
"android.intent.action.ALARM_CHANGED",
|
||||
"android.intent.action.APPLICATION_RESTRICTIONS_CHANGED",
|
||||
"android.intent.action.BATTERY_CHANGED",
|
||||
"android.intent.action.BATTERY_LOW",
|
||||
"android.intent.action.BATTERY_OKAY",
|
||||
"android.intent.action.BOOT_COMPLETED",
|
||||
"android.intent.action.CALL_DISCONNECT_CAUSE",
|
||||
"android.intent.action.CAMERA_BUTTON",
|
||||
"android.intent.action.CANCEL_ENABLE_ROLLBACK",
|
||||
"android.intent.action.CLEAR_DNS_CACHE",
|
||||
"android.intent.action.CLOSE_SYSTEM_DIALOGS",
|
||||
"android.intent.action.CONFIGURATION_CHANGED",
|
||||
"android.intent.action.CONTENT_CHANGED",
|
||||
"android.intent.action.DATA_SMS_RECEIVED",
|
||||
"android.intent.action.DATA_STALL_DETECTED",
|
||||
"android.intent.action.DATE_CHANGED",
|
||||
"android.intent.action.DEVICE_STORAGE_FULL",
|
||||
"android.intent.action.DEVICE_STORAGE_LOW",
|
||||
"android.intent.action.DEVICE_STORAGE_NOT_FULL",
|
||||
"android.intent.action.DEVICE_STORAGE_OK",
|
||||
"android.intent.action.DISTRACTING_PACKAGES_CHANGED",
|
||||
"android.intent.action.DOCK_EVENT",
|
||||
"android.intent.action.DOWNLOAD_COMPLETE",
|
||||
"android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED",
|
||||
"android.intent.action.DREAMING_STARTED",
|
||||
"android.intent.action.DREAMING_STOPPED",
|
||||
"android.intent.action.DROPBOX_ENTRY_ADDED",
|
||||
"android.intent.action.DYNAMIC_SENSOR_CHANGED",
|
||||
"android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED",
|
||||
"android.intent.action.EMERGENCY_CALL_STATE_CHANGED",
|
||||
"android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE",
|
||||
"android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE",
|
||||
"android.intent.action.FACTORY_RESET",
|
||||
"android.intent.action.FETCH_VOICEMAIL",
|
||||
"android.intent.action.GTALK_CONNECTED",
|
||||
"android.intent.action.GTALK_DISCONNECTED",
|
||||
"android.intent.action.HEADSET_PLUG",
|
||||
"android.intent.action.HEADSET_PLUG",
|
||||
"android.intent.action.INPUT_METHOD_CHANGED",
|
||||
"android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION",
|
||||
"android.intent.action.LOCALE_CHANGED",
|
||||
"android.intent.action.LOCKED_BOOT_COMPLETED",
|
||||
"android.intent.action.MANAGE_PACKAGE_STORAGE",
|
||||
"android.intent.action.MASTER_CLEAR_NOTIFICATION",
|
||||
"android.intent.action.MEDIA_BAD_REMOVAL",
|
||||
"android.intent.action.MEDIA_BUTTON",
|
||||
"android.intent.action.MEDIA_CHECKING",
|
||||
"android.intent.action.MEDIA_EJECT",
|
||||
"android.intent.action.MEDIA_MOUNTED",
|
||||
"android.intent.action.MEDIA_NOFS",
|
||||
"android.intent.action.MEDIA_REMOVED",
|
||||
"android.intent.action.MEDIA_SCANNER_FINISHED",
|
||||
"android.intent.action.MEDIA_SCANNER_SCAN_FILE",
|
||||
"android.intent.action.MEDIA_SCANNER_STARTED",
|
||||
"android.intent.action.MEDIA_SHARED",
|
||||
"android.intent.action.MEDIA_UNMOUNTABLE",
|
||||
"android.intent.action.MEDIA_UNMOUNTED",
|
||||
"android.intent.action.MY_PACKAGE_REPLACED",
|
||||
"android.intent.action.MY_PACKAGE_SUSPENDED",
|
||||
"android.intent.action.MY_PACKAGE_UNSUSPENDED",
|
||||
"android.intent.action.NEW_OUTGOING_CALL",
|
||||
"android.intent.action.NEW_VOICEMAIL",
|
||||
"android.intent.action.PACKAGES_SUSPENDED",
|
||||
"android.intent.action.PACKAGES_UNSUSPENDED",
|
||||
"android.intent.action.PACKAGE_ADDED",
|
||||
"android.intent.action.PACKAGE_CHANGED",
|
||||
"android.intent.action.PACKAGE_DATA_CLEARED",
|
||||
"android.intent.action.PACKAGE_ENABLE_ROLLBACK",
|
||||
"android.intent.action.PACKAGE_FIRST_LAUNCH",
|
||||
"android.intent.action.PACKAGE_FULLY_REMOVED",
|
||||
"android.intent.action.PACKAGE_INSTALL",
|
||||
"android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION",
|
||||
"android.intent.action.PACKAGE_NEEDS_VERIFICATION",
|
||||
"android.intent.action.PACKAGE_REMOVED",
|
||||
"android.intent.action.PACKAGE_REPLACED",
|
||||
"android.intent.action.PACKAGE_RESTARTED",
|
||||
"android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY",
|
||||
"android.intent.action.PACKAGE_VERIFIED",
|
||||
"android.intent.action.PHONE_STATE",
|
||||
"android.intent.action.PROVIDER_CHANGED",
|
||||
"android.intent.action.PROXY_CHANGE",
|
||||
"android.intent.action.QUERY_PACKAGE_RESTART",
|
||||
"android.intent.action.REBOOT",
|
||||
"android.intent.action.ROLLBACK_COMMITTED",
|
||||
"android.intent.action.SCREEN_OFF",
|
||||
"android.intent.action.SCREEN_ON",
|
||||
"android.intent.action.SERVICE_STATE",
|
||||
"android.intent.action.SIM_STATE_CHANGED",
|
||||
"android.intent.action.SPLIT_CONFIGURATION_CHANGED",
|
||||
"android.intent.action.SUB_DEFAULT_CHANGED",
|
||||
"android.intent.action.TIMEZONE_CHANGED",
|
||||
"android.intent.action.TIME_SET",
|
||||
"android.intent.action.TIME_TICK",
|
||||
"android.intent.action.UID_REMOVED",
|
||||
"android.intent.action.UMS_CONNECTED",
|
||||
"android.intent.action.UMS_DISCONNECTED",
|
||||
"android.intent.action.USER_PRESENT",
|
||||
"android.intent.action.USER_UNLOCKED",
|
||||
"android.intent.action.WALLPAPER_CHANGED",
|
||||
"android.media.ACTION_SCO_AUDIO_STATE_UPDATED",
|
||||
"android.media.AUDIO_BECOMING_NOISY",
|
||||
"android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION",
|
||||
"android.media.MASTER_MUTE_CHANGED_ACTION",
|
||||
"android.media.RINGER_MODE_CHANGED",
|
||||
"android.media.SCO_AUDIO_STATE_CHANGED",
|
||||
"android.media.STREAM_DEVICES_CHANGED_ACTION",
|
||||
"android.media.STREAM_MUTE_CHANGED_ACTION",
|
||||
"android.media.VIBRATE_SETTING_CHANGED",
|
||||
"android.media.VOLUME_CHANGED_ACTION",
|
||||
"android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION",
|
||||
"android.media.action.HDMI_AUDIO_PLUG",
|
||||
"android.media.action.MICROPHONE_MUTE_CHANGED",
|
||||
"android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION",
|
||||
"android.media.action.SPEAKERPHONE_STATE_CHANGED",
|
||||
"android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED",
|
||||
"android.media.tv.action.INITIALIZE_PROGRAMS",
|
||||
"android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT",
|
||||
"android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED",
|
||||
"android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED",
|
||||
"android.net.conn.BACKGROUND_DATA_SETTING_CHANGED",
|
||||
"android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
|
||||
"android.net.conn.CONNECTIVITY_CHANGE",
|
||||
"android.net.conn.DATA_ACTIVITY_CHANGE",
|
||||
"android.net.conn.INET_CONDITION_ACTION",
|
||||
"android.net.conn.RESTRICT_BACKGROUND_CHANGED",
|
||||
"android.net.conn.TETHER_STATE_CHANGED",
|
||||
"android.net.nsd.STATE_CHANGED",
|
||||
"android.net.scoring.SCORER_CHANGED",
|
||||
"android.net.scoring.SCORE_NETWORKS",
|
||||
"android.net.sip.action.SIP_CALL_OPTION_CHANGED",
|
||||
"android.net.sip.action.SIP_INCOMING_CALL",
|
||||
"android.net.sip.action.SIP_REMOVE_PROFILE",
|
||||
"android.net.sip.action.SIP_SERVICE_UP",
|
||||
"android.net.sip.action.START_SIP",
|
||||
"android.net.wifi.BATCHED_RESULTS",
|
||||
"android.net.wifi.NETWORK_IDS_CHANGED",
|
||||
"android.net.wifi.RSSI_CHANGED",
|
||||
"android.net.wifi.SCAN_RESULTS",
|
||||
"android.net.wifi.STATE_CHANGE",
|
||||
"android.net.wifi.WIFI_STATE_CHANGED",
|
||||
"android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION",
|
||||
"android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED",
|
||||
"android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED",
|
||||
"android.net.wifi.p2p.CONNECTION_STATE_CHANGE",
|
||||
"android.net.wifi.p2p.DISCOVERY_STATE_CHANGE",
|
||||
"android.net.wifi.p2p.PEERS_CHANGED",
|
||||
"android.net.wifi.p2p.STATE_CHANGED",
|
||||
"android.net.wifi.p2p.THIS_DEVICE_CHANGED",
|
||||
"android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED",
|
||||
"android.net.wifi.supplicant.CONNECTION_CHANGE",
|
||||
"android.net.wifi.supplicant.STATE_CHANGE",
|
||||
"android.nfc.action.ADAPTER_STATE_CHANGED",
|
||||
"android.nfc.action.PREFERRED_PAYMENT_CHANGED",
|
||||
"android.nfc.action.TRANSACTION_DETECTED",
|
||||
"android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED",
|
||||
"android.os.action.DEVICE_IDLE_MODE_CHANGED",
|
||||
"android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED",
|
||||
"android.os.action.POWER_SAVE_MODE_CHANGED",
|
||||
"android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL",
|
||||
"android.os.action.POWER_SAVE_MODE_CHANGING",
|
||||
"android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED",
|
||||
"android.os.action.POWER_SAVE_WHITELIST_CHANGED",
|
||||
"android.os.action.UPDATE_EMERGENCY_NUMBER_DB",
|
||||
"android.provider.Telephony.MMS_DOWNLOADED",
|
||||
"android.provider.Telephony.SECRET_CODE",
|
||||
"android.provider.Telephony.SIM_FULL",
|
||||
"android.provider.Telephony.SMS_CARRIER_PROVISION",
|
||||
"android.provider.Telephony.SMS_CB_RECEIVED",
|
||||
"android.provider.Telephony.SMS_DELIVER",
|
||||
"android.provider.Telephony.SMS_RECEIVED",
|
||||
"android.provider.Telephony.SMS_REJECTED",
|
||||
"android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED",
|
||||
"android.provider.Telephony.WAP_PUSH_DELIVER",
|
||||
"android.provider.Telephony.WAP_PUSH_RECEIVED",
|
||||
"android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED",
|
||||
"android.provider.action.EXTERNAL_PROVIDER_CHANGE",
|
||||
"android.provider.action.SMS_EMERGENCY_CB_RECEIVED",
|
||||
"android.provider.action.SMS_MMS_DB_CREATED",
|
||||
"android.provider.action.SMS_MMS_DB_LOST",
|
||||
"android.provider.action.SYNC_VOICEMAIL",
|
||||
"android.security.STORAGE_CHANGED",
|
||||
"android.security.action.KEYCHAIN_CHANGED",
|
||||
"android.security.action.KEY_ACCESS_CHANGED",
|
||||
"android.security.action.TRUST_STORE_CHANGED",
|
||||
"android.service.controls.action.ADD_CONTROL",
|
||||
"android.settings.ENABLE_MMS_DATA_REQUEST",
|
||||
"android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED",
|
||||
"android.speech.tts.engine.TTS_DATA_INSTALLED",
|
||||
"android.telephony.action.AREA_INFO_UPDATED",
|
||||
"android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED",
|
||||
"android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED",
|
||||
"android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED",
|
||||
"android.telephony.action.REFRESH_SUBSCRIPTION_PLANS",
|
||||
"android.telephony.action.SECRET_CODE",
|
||||
"android.telephony.action.SERVICE_PROVIDERS_UPDATED",
|
||||
"android.telephony.action.SIM_APPLICATION_STATE_CHANGED",
|
||||
"android.telephony.action.SIM_CARD_STATE_CHANGED",
|
||||
"android.telephony.action.SIM_SLOT_STATUS_CHANGED",
|
||||
"android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
|
||||
"android.telephony.action.SUBSCRIPTION_PLANS_CHANGED",
|
||||
"android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED",
|
||||
"android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE",
|
||||
"android.telephony.euicc.action.OTA_STATUS_CHANGED",
|
||||
"android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR",
|
||||
"com.android.intent.action.DISMISS_KEYBOARD_SHORTCUTS",
|
||||
"com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS",
|
||||
"com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
|
||||
"com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED"
|
||||
};
|
||||
}
|
@ -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,6 +31,13 @@ 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;
|
||||
@ -256,7 +263,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bSaveTriggerNotification = (Button)findViewById(R.id.bSaveTriggerNotification);
|
||||
bSaveTriggerNotification = (Button)findViewById(R.id.bSaveActionCloseNotification);
|
||||
spinnerTitleDirection = (Spinner)findViewById(R.id.spinnerTitleDirection);
|
||||
spinnerTextDirection = (Spinner)findViewById(R.id.spinnerTextDirection);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etActivityOrActionPath);
|
||||
@ -265,6 +272,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringDoesNotContain),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
@ -305,7 +313,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
{
|
||||
String app;
|
||||
if(tvSelectedApplication.getText().toString().equalsIgnoreCase(getResources().getString(R.string.anyApp)))
|
||||
app = "-1";
|
||||
app = Trigger.anyAppString;
|
||||
else
|
||||
app = tvSelectedApplication.getText().toString();
|
||||
|
||||
@ -314,23 +322,14 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
String textDir = Trigger.getMatchCode(spinnerTextDirection.getSelectedItem().toString());
|
||||
String text = etNotificationText.getText().toString();
|
||||
|
||||
if(edit)
|
||||
{
|
||||
editedNotificationTrigger.setTriggerParameter(chkNotificationDirection.isChecked());
|
||||
editedNotificationTrigger.setTriggerParameter2(app + triggerParameter2Split + titleDir + triggerParameter2Split + title + triggerParameter2Split + textDir + triggerParameter2Split + text);
|
||||
ActivityManageTriggerNotification.this.setResult(RESULT_OK);
|
||||
}
|
||||
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);
|
||||
ActivityManageTriggerNotification.this.setResult(RESULT_OK, data);
|
||||
}
|
||||
Intent data = new Intent();
|
||||
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);
|
||||
|
||||
finish();
|
||||
}
|
||||
@ -360,7 +359,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
else
|
||||
text = "";
|
||||
|
||||
if(!app.equals("-1"))
|
||||
if(!app.equals(Trigger.anyAppString))
|
||||
tvSelectedApplication.setText(app);
|
||||
|
||||
for(int i = 0; i < directions.length; i++)
|
||||
@ -395,4 +394,4 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -86,8 +86,8 @@ public class ActivityManageTriggerPhoneCall extends Activity
|
||||
else
|
||||
{
|
||||
Intent data = new Intent();
|
||||
data.putExtra("triggerParameter", false);
|
||||
data.putExtra("triggerParameter2", tp2Result);
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, false);
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, tp2Result);
|
||||
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK, data);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,124 @@
|
||||
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();
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for(int i = 0; i < profileList.size(); i++)
|
||||
{
|
||||
if(profileList.get(i).getName().equals(profileName))
|
||||
{
|
||||
spinnerProfiles.setSelection(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.profileWasNotFound), ActivityManageTriggerProfile.this).show();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,21 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
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.TextView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@ -18,10 +24,12 @@ 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;
|
||||
TextView tvDaysHint;
|
||||
|
||||
public static Trigger editedTimeFrameTrigger = null;
|
||||
static Trigger editedTimeFrameTrigger = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@ -44,17 +52,20 @@ 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);
|
||||
tvDaysHint = (TextView)findViewById(R.id.tvDaysHint);
|
||||
|
||||
bSaveTimeFrame.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Time startTime = new Time(0);
|
||||
TimeObject startTime = new TimeObject();
|
||||
startTime.setHours(startPicker.getCurrentHour());
|
||||
startTime.setMinutes(startPicker.getCurrentMinute());
|
||||
|
||||
Time stopTime = new Time(0);
|
||||
TimeObject stopTime = new TimeObject();
|
||||
stopTime.setHours(stopPicker.getCurrentHour());
|
||||
stopTime.setMinutes(stopPicker.getCurrentMinute());
|
||||
|
||||
@ -92,11 +103,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,17 +147,67 @@ 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());
|
||||
|
||||
setResult(RESULT_OK);
|
||||
editedTimeFrameTrigger.setTriggerParameter2(editedTimeFrameTrigger.getTimeFrame().toTriggerParameter2String());
|
||||
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, editedTimeFrameTrigger.getTriggerParameter());
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, editedTimeFrameTrigger.getTriggerParameter2());
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
if(editedTimeFrameTrigger.getTimeFrame() != null)
|
||||
|
||||
chkRepeat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
etRepeatEvery.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
editedTimeFrameTrigger = new Trigger();
|
||||
editedTimeFrameTrigger.setTriggerParameter(getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
editedTimeFrameTrigger.setTriggerParameter2(getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
|
||||
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(editedTimeFrameTrigger.getTriggerParameter2()));
|
||||
loadVariableIntoGui();
|
||||
}
|
||||
|
||||
TimePicker.OnTimeChangedListener pickerListener = new TimePicker.OnTimeChangedListener()
|
||||
{
|
||||
@Override
|
||||
public void onTimeChanged(TimePicker timePicker, int i, int i1)
|
||||
{
|
||||
if(
|
||||
startPicker.getCurrentHour() > stopPicker.getCurrentHour()
|
||||
||
|
||||
(
|
||||
startPicker.getCurrentHour() == stopPicker.getCurrentHour()
|
||||
&&
|
||||
startPicker.getCurrentMinute() >= stopPicker.getCurrentMinute()
|
||||
)
|
||||
)
|
||||
tvDaysHint.setText(getResources().getString(R.string.timeFrameDaysHint));
|
||||
else
|
||||
tvDaysHint.setText("");
|
||||
}
|
||||
};
|
||||
startPicker.setOnTimeChangedListener(pickerListener);
|
||||
stopPicker.setOnTimeChangedListener(pickerListener);
|
||||
|
||||
// Perform check once
|
||||
pickerListener.onTimeChanged(null, 0, 0);
|
||||
}
|
||||
|
||||
private void loadVariableIntoGui()
|
||||
@ -158,6 +251,11 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(editedTimeFrameTrigger.getTimeFrame().getRepetition() > 0)
|
||||
{
|
||||
chkRepeat.setChecked(true);
|
||||
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
|
||||
}
|
||||
}
|
||||
}
|
@ -35,6 +35,9 @@ 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;
|
||||
|
@ -3,8 +3,8 @@ package com.jens.automation2;
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@ -15,14 +15,13 @@ import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
|
||||
@ -46,6 +45,8 @@ public class ActivityPermissions extends Activity
|
||||
private static final int requestCodeForPermissionsNotificationPolicy = 12044;
|
||||
private static final int requestCodeForPermissionsBackgroundLocation = 12045;
|
||||
private static final int requestCodeForPermissionsNotifications = 12046;
|
||||
private static final int requestCodeForPermissionsDeviceAdmin = 12047;
|
||||
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
|
||||
protected String[] specificPermissionsToRequest = null;
|
||||
|
||||
public static String intentExtraName = "permissionsToBeRequested";
|
||||
@ -223,7 +224,7 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
protected static void addToArrayListUnique(String value, ArrayList<String> list)
|
||||
public static void addToArrayListUnique(String value, List<String> list)
|
||||
{
|
||||
if (!list.contains(value))
|
||||
list.add(value);
|
||||
@ -238,9 +239,9 @@ public class ActivityPermissions extends Activity
|
||||
if(
|
||||
s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
||
|
||||
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
||
|
||||
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
)
|
||||
{
|
||||
if (!Miscellaneous.googleToBlameForLocation(true))
|
||||
@ -282,6 +283,16 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
return verifyNotificationPermission();
|
||||
}
|
||||
else if (s.equals(Manifest.permission.BIND_DEVICE_ADMIN))
|
||||
{
|
||||
return haveDeviceAdmin();
|
||||
}
|
||||
else if (s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
|
||||
{
|
||||
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
String packageName = context.getApplicationContext().getPackageName();
|
||||
return pm.isIgnoringBatteryOptimizations(packageName);
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = context.checkCallingOrSelfPermission(s);
|
||||
@ -292,6 +303,28 @@ public class ActivityPermissions extends Activity
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean haveDeviceAdmin()
|
||||
{
|
||||
DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
ComponentName compName = new ComponentName(Miscellaneous.getAnyContext(), DeviceAdmin.class);
|
||||
boolean active = deviceManger.isAdminActive(compName);
|
||||
return active;
|
||||
}
|
||||
|
||||
public static void requestDeviceAdmin()
|
||||
{
|
||||
if(!haveDeviceAdmin())
|
||||
{
|
||||
// DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
ComponentName compName = new ComponentName(ActivityPermissions.getInstance(), DeviceAdmin.class) ;
|
||||
|
||||
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN );
|
||||
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN , compName );
|
||||
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION , Miscellaneous.getAnyContext().getResources().getString(R.string.deviceAdminNote));
|
||||
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsDeviceAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getRequiredPermissions(boolean onlyGeneral)
|
||||
{
|
||||
ArrayList<String> requiredPermissions = new ArrayList<String>();
|
||||
@ -308,47 +341,53 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique("android.permission.RECEIVE_BOOT_COMPLETED", requiredPermissions);
|
||||
*/
|
||||
|
||||
// if (!havePermission(ActivityPermissions.writeExternalStoragePermissionName, workingContext))
|
||||
// addToArrayListUnique(ActivityPermissions.writeExternalStoragePermissionName, requiredPermissions);
|
||||
|
||||
if(!havePermission(Manifest.permission.WRITE_SETTINGS, workingContext))
|
||||
{
|
||||
for (Profile profile : Profile.getProfileCollection())
|
||||
{
|
||||
if (profile.changeIncomingCallsRingtone)
|
||||
{
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
|
||||
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
|
||||
|
||||
for(Profile p : Profile.getProfileCollection())
|
||||
{
|
||||
if(p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
}
|
||||
|
||||
if (!onlyGeneral)
|
||||
{
|
||||
for (Rule rule : Rule.getRuleCollection())
|
||||
{
|
||||
for (String singlePermission : getPermissionsForRule(rule))
|
||||
{
|
||||
if (!havePermission(singlePermission, workingContext))
|
||||
{
|
||||
if(
|
||||
if (
|
||||
|
||||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
||
|
||||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
||
|
||||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
)
|
||||
{
|
||||
if (!Miscellaneous.googleToBlameForLocation(true))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
else if(singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection))
|
||||
else if (singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection))
|
||||
{
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
if (!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
else
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,6 +526,9 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique(Manifest.permission.MODIFY_AUDIO_SETTINGS, requiredPermissions);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NOTIFICATION_POLICY, requiredPermissions);
|
||||
Profile targetProfile = Profile.getByName(action.getParameter2());
|
||||
if(targetProfile.changeIncomingCallsRingtone || targetProfile.changeNotificationRingtone)
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
break;
|
||||
case disableScreenRotation:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
@ -496,9 +538,13 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case playMusic:
|
||||
break;
|
||||
case controlMediaPlayback:
|
||||
// addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.MEDIA_CONTENT_CONTROL, requiredPermissions);
|
||||
break;
|
||||
case sendTextMessage:
|
||||
addToArrayListUnique(Manifest.permission.SEND_SMS, requiredPermissions);
|
||||
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
|
||||
getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions);
|
||||
break;
|
||||
case setAirplaneMode:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
@ -531,6 +577,12 @@ public class ActivityPermissions extends Activity
|
||||
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case setBluetoothTethering:
|
||||
//addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
break;
|
||||
case setWifi:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
|
||||
@ -551,15 +603,15 @@ public class ActivityPermissions extends Activity
|
||||
// addToArrayListUnique("android.permission.TETHER_PRIVILEGED", requiredPermissions);
|
||||
break;
|
||||
case speakText:
|
||||
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
|
||||
getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions);
|
||||
break;
|
||||
case startOtherActivity:
|
||||
if(
|
||||
action.getParameter2().contains(Actions.wireguard_tunnel_up)
|
||||
||
|
||||
action.getParameter2().contains(Actions.wireguard_tunnel_down)
|
||||
action.getParameter2().contains(Actions.wireguard_tunnel_down)
|
||||
||
|
||||
action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
|
||||
action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
|
||||
)
|
||||
addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions);
|
||||
// if(
|
||||
@ -571,7 +623,7 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case triggerUrl:
|
||||
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
|
||||
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
|
||||
getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions);
|
||||
break;
|
||||
case turnBluetoothOff:
|
||||
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
|
||||
@ -587,40 +639,40 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case turnUsbTetheringOff:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case turnUsbTetheringOn:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case turnWifiOff:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case turnWifiOn:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case turnWifiTetheringOff:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case turnWifiTetheringOn:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
break;
|
||||
case waitBeforeNextAction:
|
||||
break;
|
||||
case wakeupDevice:
|
||||
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
|
||||
break;
|
||||
case playSound:
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
break;
|
||||
case closeNotification:
|
||||
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
|
||||
break;
|
||||
case turnScreenOnOrOff:
|
||||
if(action.getParameter1())
|
||||
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
|
||||
else
|
||||
addToArrayListUnique(Manifest.permission.BIND_DEVICE_ADMIN, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -696,13 +748,6 @@ public class ActivityPermissions extends Activity
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.ACCESS_COARSE_LOCATION:
|
||||
// usingElements.add(getResources().getString(R.string.android_permission_ACCESS_COARSE_LOCATION));
|
||||
usingElements.add(getResources().getString(R.string.manageLocations));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.ACCESS_FINE_LOCATION:
|
||||
usingElements.add(getResources().getString(R.string.manageLocations));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
|
||||
@ -759,14 +804,6 @@ public class ActivityPermissions extends Activity
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
/*case "android.permission.BATTERY_STATS":
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.batteryLevel))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.charging))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;*/
|
||||
case Manifest.permission.BLUETOOTH_ADMIN:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
@ -833,6 +870,42 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.READ_EXTERNAL_STORAGE:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.playSound))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.changeSoundProfile))
|
||||
{
|
||||
Rule tempRule = Rule.getByName(ruleName);
|
||||
if(tempRule != null)
|
||||
{
|
||||
for (Action a : tempRule.getActionSet())
|
||||
{
|
||||
if (a.getAction().equals(Action.Action_Enum.changeSoundProfile))
|
||||
{
|
||||
Profile p = Profile.getByName(a.getParameter2());
|
||||
if (p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Profile p : Profile.getProfileCollection())
|
||||
{
|
||||
if(p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
{
|
||||
usingElements.add(String.format(getResources().getString(R.string.profileXrequiresThis), p.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Manifest.permission.BIND_DEVICE_ADMIN:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.turnScreenOnOrOff))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS:
|
||||
usingElements.add(getResources().getString(R.string.recommendedForBetterReliability));
|
||||
break;
|
||||
case Manifest.permission.QUERY_ALL_PACKAGES:
|
||||
usingElements.add(getResources().getString(R.string.queryAllPackages));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -861,6 +934,14 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
if (requestCode == requestCodeForPermissionsDeviceAdmin)
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) ActivityPermissions.this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
if (mNotificationManager.isNotificationPolicyAccessGranted())
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
if (requestCode == requestCodeForPermissionsBackgroundLocation)
|
||||
@ -873,6 +954,10 @@ public class ActivityPermissions extends Activity
|
||||
if (requestCode == requestCodeForPermissionsNotifications)
|
||||
if(havePermission(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsBatteryOptimization)
|
||||
if(havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -923,12 +1008,18 @@ public class ActivityPermissions extends Activity
|
||||
startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
|
||||
return;
|
||||
}
|
||||
if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestDeviceAdmin();
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
|
||||
// intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
|
||||
return;
|
||||
}
|
||||
@ -936,10 +1027,20 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
|
||||
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotifications);
|
||||
return;
|
||||
}
|
||||
else if(s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
String packageName = getApplicationContext().getPackageName();
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
startActivityForResult(intent, requestCodeForPermissionsBatteryOptimization);
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.readLocation), getResources().getString(R.string.pleaseGiveBgLocation), ActivityPermissions.this);
|
||||
@ -968,7 +1069,7 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
|
||||
&&
|
||||
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
|
||||
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
|
||||
)
|
||||
{
|
||||
requiredPermissions.remove(Manifest.permission.PROCESS_OUTGOING_CALLS);
|
||||
@ -978,8 +1079,6 @@ public class ActivityPermissions extends Activity
|
||||
if(requiredPermissions.contains(Manifest.permission.SEND_SMS))
|
||||
{
|
||||
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
|
||||
// &&
|
||||
// Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
|
||||
)
|
||||
{
|
||||
requiredPermissions.remove(Manifest.permission.SEND_SMS);
|
||||
@ -996,11 +1095,8 @@ public class ActivityPermissions extends Activity
|
||||
|
||||
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
|
||||
|
||||
// Toast.makeText(ActivityPermissions.this, "Requesting permissions. Amount: " + String.valueOf(requiredPermissions.size()), Toast.LENGTH_LONG).show();
|
||||
if(requiredPermissions.size() > 0)
|
||||
requestPermissions(requiredPermissions.toArray(new String[requiredPermissions.size()]), requestCodeForPermissions);
|
||||
// else
|
||||
// Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.permissionsRequiredNotAvailable), ActivityPermissions.this).show();
|
||||
}
|
||||
else
|
||||
setHaveAllPermissions();
|
||||
@ -1018,17 +1114,11 @@ public class ActivityPermissions extends Activity
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "onRequestPermissionsResult()", "onRequestPermissionsResult()", 3);
|
||||
// Toast.makeText(ActivityPermissions.this, "onRequestPermissionsResult()", Toast.LENGTH_LONG).show();
|
||||
|
||||
// ArrayList<String> disabledFeatures = new ArrayList<String>();
|
||||
ArrayList<String> deniedPermissions = new ArrayList<String>();
|
||||
|
||||
if (requestCode == requestCodeForPermissions)
|
||||
{
|
||||
/*ArrayList<String> affectedGeneralList = new ArrayList<String>();
|
||||
ArrayList<String> affectedTriggersList = new ArrayList<String>();
|
||||
ArrayList<String> affectedActionList = new ArrayList<String>();*/
|
||||
|
||||
for (int i=0; i < grantResults.length; i++)
|
||||
{
|
||||
if(permissions[i].equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
@ -1088,8 +1178,8 @@ public class ActivityPermissions extends Activity
|
||||
if(deniedPermissions.size() > 0)
|
||||
{
|
||||
/*
|
||||
The user denied certain permissions. With the exception of write-storage we need to live with that
|
||||
and simply disable features while keeping the notification alive. The user may dismiss it anyway.
|
||||
The user denied certain permissions. We need to live with that and simply disable
|
||||
features while keeping the notification alive. The user may dismiss it anyway.
|
||||
*/
|
||||
|
||||
Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(", ", deniedPermissions), 3);
|
||||
@ -1107,7 +1197,7 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
static ArrayList<String> checkPermissionsInVariableUse(String text, ArrayList<String> permsList)
|
||||
static ArrayList<String> getPermissionsForVariablesInUse(String text, ArrayList<String> permsList)
|
||||
{
|
||||
/*
|
||||
[uniqueid]
|
||||
@ -1314,10 +1404,7 @@ public class ActivityPermissions extends Activity
|
||||
mapActionPermissions.put("setWifiTethering", Manifest.permission.WRITE_SETTINGS);
|
||||
mapActionPermissions.put("setWifiTethering", Manifest.permission.CHANGE_NETWORK_STATE);
|
||||
mapActionPermissions.put("setWifiTethering", Manifest.permission.ACCESS_NETWORK_STATE);
|
||||
// mapActionPermissions.put("speakText", Manifest.permission.ACCESS_NOTIFICATION_POLICY);
|
||||
// mapActionPermissions.put("startOtherActivity", "");
|
||||
mapActionPermissions.put("triggerUrl", Manifest.permission.INTERNET);
|
||||
// Hier müßte ein Hinweis kommen, daß nur die Variablen verwendet werden können, für die es Rechte gibt.
|
||||
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH_ADMIN);
|
||||
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH);
|
||||
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.ACCESS_NETWORK_STATE);
|
||||
@ -1347,209 +1434,6 @@ public class ActivityPermissions extends Activity
|
||||
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK);
|
||||
}
|
||||
|
||||
/*
|
||||
<string name="android.permission.SEND_SMS"></string>
|
||||
<string name="android.permission.SEND_SMS_NO_CONFIRMATION"></string>
|
||||
<string name="android.permission.RECEIVE_SMS"></string>
|
||||
<string name="android.permission.RECEIVE_MMS"></string>
|
||||
<string name="android.permission.RECEIVE_EMERGENCY_BROADCAST"></string>
|
||||
<string name="android.permission.READ_CELL_BROADCASTS"></string>
|
||||
<string name="android.permission.READ_SMS"></string>
|
||||
<string name="android.permission.WRITE_SMS"></string>
|
||||
<string name="android.permission.RECEIVE_WAP_PUSH"></string>
|
||||
<string name="android.permission.READ_CONTACTS"></string>
|
||||
<string name="android.permission.WRITE_CONTACTS"></string>
|
||||
<string name="android.permission.BIND_DIRECTORY_SEARCH"></string>
|
||||
<string name="android.permission.READ_CALL_LOG"></string>
|
||||
<string name="android.permission.WRITE_CALL_LOG"></string>
|
||||
<string name="android.permission.READ_SOCIAL_STREAM"></string>
|
||||
<string name="android.permission.WRITE_SOCIAL_STREAM"></string>
|
||||
<string name="android.permission.READ_PROFILE"></string>
|
||||
<string name="android.permission.WRITE_PROFILE"></string>
|
||||
<string name="android.permission.READ_CALENDAR"></string>
|
||||
<string name="android.permission.WRITE_CALENDAR"></string>
|
||||
<string name="android.permission.READ_USER_DICTIONARY"></string>
|
||||
<string name="android.permission.WRITE_USER_DICTIONARY"></string>
|
||||
<string name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"></string>
|
||||
<string name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"></string>
|
||||
<string name="com.android.alarm.permission.SET_ALARM"></string>
|
||||
<string name="com.android.voicemail.permission.ADD_VOICEMAIL"></string>
|
||||
<string name="android.permission.ACCESS_FINE_LOCATION"></string>
|
||||
<string name="android.permission.ACCESS_COARSE_LOCATION"></string>
|
||||
<string name="android.permission.ACCESS_MOCK_LOCATION"></string>
|
||||
<string name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></string>
|
||||
<string name="android.permission.INSTALL_LOCATION_PROVIDER"></string>
|
||||
<string name="android.permission.INTERNET"></string>
|
||||
<string name="android.permission.ACCESS_NETWORK_STATE"></string>
|
||||
<string name="android.permission.ACCESS_WIFI_STATE"></string>
|
||||
<string name="android.permission.CHANGE_WIFI_STATE"></string>
|
||||
<string name="android.permission.ACCESS_WIMAX_STATE"></string>
|
||||
<string name="android.permission.CHANGE_WIMAX_STATE"></string>
|
||||
<string name="android.permission.BLUETOOTH"></string>
|
||||
<string name="android.permission.BLUETOOTH_ADMIN"></string>
|
||||
<string name="android.permission.BLUETOOTH_STACK"></string>
|
||||
<string name="android.permission.NFC"></string>
|
||||
<string name="android.permission.CONNECTIVITY_INTERNAL"></string>
|
||||
<string name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"></string>
|
||||
<string name="android.permission.GET_ACCOUNTS"></string>
|
||||
<string name="android.permission.AUTHENTICATE_ACCOUNTS"></string>
|
||||
<string name="android.permission.USE_CREDENTIALS"></string>
|
||||
<string name="android.permission.MANAGE_ACCOUNTS"></string>
|
||||
<string name="android.permission.ACCOUNT_MANAGER"></string>
|
||||
<string name="android.permission.CHANGE_WIFI_MULTICAST_STATE"></string>
|
||||
<string name="android.permission.VIBRATE"></string>
|
||||
<string name="android.permission.FLASHLIGHT"></string>
|
||||
<string name="android.permission.WAKE_LOCK"></string>
|
||||
<string name="android.permission.MODIFY_AUDIO_SETTINGS"></string>
|
||||
<string name="android.permission.MANAGE_USB"></string>
|
||||
<string name="android.permission.ACCESS_MTP"></string>
|
||||
<string name="android.permission.HARDWARE_TEST"></string>
|
||||
<string name="android.permission.NET_ADMIN"></string>
|
||||
<string name="android.permission.REMOTE_AUDIO_PLAYBACK"></string>
|
||||
<string name="android.permission.RECORD_AUDIO"></string>
|
||||
<string name="android.permission.CAMERA"></string>
|
||||
<string name="android.permission.PROCESS_OUTGOING_CALLS"></string>
|
||||
<string name="android.permission.MODIFY_PHONE_STATE"></string>
|
||||
<string name="android.permission.READ_PHONE_STATE"></string>
|
||||
<string name="android.permission.READ_PRIVILEGED_PHONE_STATE"></string>
|
||||
<string name="android.permission.CALL_PHONE"></string>
|
||||
<string name="android.permission.USE_SIP"></string>
|
||||
<string name="android.permission.READ_EXTERNAL_STORAGE"></string>
|
||||
<string name="android.permission.WRITE_EXTERNAL_STORAGE"></string>
|
||||
<string name="android.permission.WRITE_MEDIA_STORAGE"></string>
|
||||
<string name="android.permission.DISABLE_KEYGUARD"></string>
|
||||
<string name="android.permission.GET_TASKS"></string>
|
||||
<string name="android.permission.INTERACT_ACROSS_USERS"></string>
|
||||
<string name="android.permission.INTERACT_ACROSS_USERS_FULL"></string>
|
||||
<string name="android.permission.MANAGE_USERS"></string>
|
||||
<string name="android.permission.GET_DETAILED_TASKS"></string>
|
||||
<string name="android.permission.REORDER_TASKS"></string>
|
||||
<string name="android.permission.REMOVE_TASKS"></string>
|
||||
<string name="android.permission.START_ANY_ACTIVITY"></string>
|
||||
<string name="android.permission.RESTART_PACKAGES"></string>
|
||||
<string name="android.permission.KILL_BACKGROUND_PROCESSES"></string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW"></string>
|
||||
<string name="android.permission.SET_WALLPAPER"></string>
|
||||
<string name="android.permission.SET_WALLPAPER_HINTS"></string>
|
||||
<string name="android.permission.SET_TIME"></string>
|
||||
<string name="android.permission.SET_TIME_ZONE"></string>
|
||||
<string name="android.permission.EXPAND_STATUS_BAR"></string>
|
||||
<string name="android.permission.READ_SYNC_SETTINGS"></string>
|
||||
<string name="android.permission.WRITE_SYNC_SETTINGS"></string>
|
||||
<string name="android.permission.READ_SYNC_STATS"></string>
|
||||
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
|
||||
<string name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE"></string>
|
||||
<string name="android.permission.CHANGE_CONFIGURATION"></string>
|
||||
<string name="android.permission.WRITE_SETTINGS"></string>
|
||||
<string name="android.permission.WRITE_GSERVICES"></string>
|
||||
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
|
||||
<string name="android.permission.CHANGE_CONFIGURATION"></string>
|
||||
<string name="android.permission.FORCE_STOP_PACKAGES"></string>
|
||||
<string name="android.permission.RETRIEVE_WINDOW_CONTENT"></string>
|
||||
<string name="android.permission.SET_ANIMATION_SCALE"></string>
|
||||
<string name="android.permission.PERSISTENT_ACTIVITY"></string>
|
||||
<string name="android.permission.GET_PACKAGE_SIZE"></string>
|
||||
<string name="android.permission.SET_PREFERRED_APPLICATIONS"></string>
|
||||
<string name="android.permission.RECEIVE_BOOT_COMPLETED"></string>
|
||||
<string name="android.permission.BROADCAST_STICKY"></string>
|
||||
<string name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></string>
|
||||
<string name="android.permission.MOUNT_FORMAT_FILESYSTEMS"></string>
|
||||
<string name="android.permission.ASEC_ACCESS"></string>
|
||||
<string name="android.permission.ASEC_CREATE"></string>
|
||||
<string name="android.permission.ASEC_DESTROY"></string>
|
||||
<string name="android.permission.ASEC_MOUNT_UNMOUNT"></string>
|
||||
<string name="android.permission.ASEC_RENAME"></string>
|
||||
<string name="android.permission.WRITE_APN_SETTINGS"></string>
|
||||
<string name="android.permission.SUBSCRIBED_FEEDS_READ"></string>
|
||||
<string name="android.permission.SUBSCRIBED_FEEDS_WRITE"></string>
|
||||
<string name="android.permission.CHANGE_NETWORK_STATE"></string>
|
||||
<string name="android.permission.CLEAR_APP_CACHE"></string>
|
||||
<string name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"></string>
|
||||
<string name="android.permission.WRITE_SECURE_SETTINGS"></string>
|
||||
<string name="android.permission.DUMP"></string>
|
||||
<string name="android.permission.READ_LOGS"></string>
|
||||
<string name="android.permission.SET_DEBUG_APP"></string>
|
||||
<string name="android.permission.SET_PROCESS_LIMIT"></string>
|
||||
<string name="android.permission.SET_ALWAYS_FINISH"></string>
|
||||
<string name="android.permission.SIGNAL_PERSISTENT_PROCESSES"></string>
|
||||
<string name="android.permission.DIAGNOSTIC"></string>
|
||||
<string name="android.permission.STATUS_BAR"></string>
|
||||
<string name="android.permission.STATUS_BAR_SERVICE"></string>
|
||||
<string name="android.permission.FORCE_BACK"></string>
|
||||
<string name="android.permission.UPDATE_DEVICE_STATS"></string>
|
||||
<string name="android.permission.INTERNAL_SYSTEM_WINDOW"></string>
|
||||
<string name="android.permission.MANAGE_APP_TOKENS"></string>
|
||||
<string name="android.permission.FREEZE_SCREEN"></string>
|
||||
<string name="android.permission.INJECT_EVENTS"></string>
|
||||
<string name="android.permission.FILTER_EVENTS"></string>
|
||||
<string name="android.permission.RETRIEVE_WINDOW_INFO"></string>
|
||||
<string name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"></string>
|
||||
<string name="android.permission.MAGNIFY_DISPLAY"></string>
|
||||
<string name="android.permission.SET_ACTIVITY_WATCHER"></string>
|
||||
<string name="android.permission.SHUTDOWN"></string>
|
||||
<string name="android.permission.STOP_APP_SWITCHES"></string>
|
||||
<string name="android.permission.READ_INPUT_STATE"></string>
|
||||
<string name="android.permission.BIND_INPUT_METHOD"></string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE"></string>
|
||||
<string name="android.permission.BIND_TEXT_SERVICE"></string>
|
||||
<string name="android.permission.BIND_VPN_SERVICE"></string>
|
||||
<string name="android.permission.BIND_WALLPAPER"></string>
|
||||
<string name="android.permission.BIND_DEVICE_ADMIN"></string>
|
||||
<string name="android.permission.SET_ORIENTATION"></string>
|
||||
<string name="android.permission.SET_POINTER_SPEED"></string>
|
||||
<string name="android.permission.SET_KEYBOARD_LAYOUT"></string>
|
||||
<string name="android.permission.INSTALL_PACKAGES"></string>
|
||||
<string name="android.permission.CLEAR_APP_USER_DATA"></string>
|
||||
<string name="android.permission.DELETE_CACHE_FILES"></string>
|
||||
<string name="android.permission.DELETE_PACKAGES"></string>
|
||||
<string name="android.permission.MOVE_PACKAGE"></string>
|
||||
<string name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"></string>
|
||||
<string name="android.permission.GRANT_REVOKE_PERMISSIONS"></string>
|
||||
<string name="android.permission.ACCESS_SURFACE_FLINGER"></string>
|
||||
<string name="android.permission.READ_FRAME_BUFFER"></string>
|
||||
<string name="android.permission.CONFIGURE_WIFI_DISPLAY"></string>
|
||||
<string name="android.permission.CONTROL_WIFI_DISPLAY"></string>
|
||||
<string name="android.permission.BRICK"></string>
|
||||
<string name="android.permission.REBOOT"></string>
|
||||
<string name="android.permission.DEVICE_POWER"></string>
|
||||
<string name="android.permission.NET_TUNNELING"></string>
|
||||
<string name="android.permission.FACTORY_TEST"></string>
|
||||
<string name="android.permission.BROADCAST_PACKAGE_REMOVED"></string>
|
||||
<string name="android.permission.BROADCAST_SMS"></string>
|
||||
<string name="android.permission.BROADCAST_WAP_PUSH"></string>
|
||||
<string name="android.permission.MASTER_CLEAR"></string>
|
||||
<string name="android.permission.CALL_PRIVILEGED"></string>
|
||||
<string name="android.permission.PERFORM_CDMA_PROVISIONING"></string>
|
||||
<string name="android.permission.CONTROL_LOCATION_UPDATES"></string>
|
||||
<string name="android.permission.ACCESS_CHECKIN_PROPERTIES"></string>
|
||||
<string name="android.permission.PACKAGE_USAGE_STATS"></string>
|
||||
<string name="android.permission.BATTERY_STATS"></string>
|
||||
<string name="android.permission.BACKUP"></string>
|
||||
<string name="android.permission.CONFIRM_FULL_BACKUP"></string>
|
||||
<string name="android.permission.BIND_REMOTEVIEWS"></string>
|
||||
<string name="android.permission.BIND_APPWIDGET"></string>
|
||||
<string name="android.permission.BIND_KEYGUARD_APPWIDGET"></string>
|
||||
<string name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"></string>
|
||||
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"></string>
|
||||
<string name="android.permission.GLOBAL_SEARCH"></string>
|
||||
<string name="android.permission.GLOBAL_SEARCH_CONTROL"></string>
|
||||
<string name="android.permission.SET_WALLPAPER_COMPONENT"></string>
|
||||
<string name="android.permission.READ_DREAM_STATE"></string>
|
||||
<string name="android.permission.WRITE_DREAM_STATE"></string>
|
||||
<string name="android.permission.ACCESS_CACHE_FILESYSTEM"></string>
|
||||
<string name="android.permission.COPY_PROTECTED_DATA"></string>
|
||||
<string name="android.permission.CRYPT_KEEPER"></string>
|
||||
<string name="android.permission.READ_NETWORK_USAGE_HISTORY"></string>
|
||||
<string name="android.permission.MANAGE_NETWORK_POLICY"></string>
|
||||
<string name="android.permission.MODIFY_NETWORK_ACCOUNTING"></string>
|
||||
<string name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"></string>
|
||||
<string name="android.permission.PACKAGE_VERIFICATION_AGENT"></string>
|
||||
<string name="android.permission.BIND_PACKAGE_VERIFIER"></string>
|
||||
<string name="android.permission.SERIAL_PORT"></string>
|
||||
<string name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"></string>
|
||||
<string name="android.permission.UPDATE_LOCK"></string>
|
||||
*/
|
||||
|
||||
public static boolean isPermissionDeclaratedInManifest(Context context, String permission)
|
||||
{
|
||||
PackageManager pm = context.getPackageManager();
|
||||
@ -1568,12 +1452,11 @@ public class ActivityPermissions extends Activity
|
||||
ArrayList<String> requestedPermissionsArrayList = new ArrayList<String>();
|
||||
requestedPermissionsArrayList.addAll(requestedPermissionsList);
|
||||
return (requestedPermissionsArrayList.contains(permission));
|
||||
// Log.i(ExConsts.TAG, ""+requestedPermissionsArrayList);
|
||||
}
|
||||
}
|
||||
catch (PackageManager.NameNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("w", "ActivityPermissions", Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -28,10 +28,12 @@ import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.DateTimeListener;
|
||||
import com.jens.automation2.receivers.PackageReplacedReceiver;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class AutomationService extends Service implements OnInitListener
|
||||
@ -41,8 +43,14 @@ public class AutomationService extends Service implements OnInitListener
|
||||
protected final static int notificationIdRestrictions = 1005;
|
||||
protected final static int notificationIdLocationRestriction = 1006;
|
||||
|
||||
final static String NOTIFICATION_CHANNEL_ID = "com.jens.automation2";
|
||||
final static String channelName = "Service notification";
|
||||
final static String NOTIFICATION_CHANNEL_ID_SERVICE = "com.jens.automation2_service";
|
||||
final static String NOTIFICATION_CHANNEL_NAME_SERVICE = "Service notification";
|
||||
|
||||
final static String NOTIFICATION_CHANNEL_ID_FUNCTIONALITY = "com.jens.automation2_functionality";
|
||||
final static String NOTIFICATION_CHANNEL_NAME_FUNCTIONALITY = "Functionality information";
|
||||
|
||||
final static String NOTIFICATION_CHANNEL_ID_RULES = "com.jens.automation2_rules";
|
||||
final static String NOTIFICATION_CHANNEL_NAME_RULES = "Rule notifications";
|
||||
|
||||
protected static Notification myNotification;
|
||||
protected static NotificationCompat.Builder notificationBuilder = null;
|
||||
@ -51,6 +59,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
protected Calendar lockSoundChangesEnd = null;
|
||||
protected boolean isRunning;
|
||||
|
||||
protected static AutomationService centralInstance = null;
|
||||
|
||||
public void nullLockSoundChangesEnd()
|
||||
{
|
||||
lockSoundChangesEnd = null;
|
||||
@ -65,7 +75,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
lockSoundChangesEnd = Calendar.getInstance();
|
||||
|
||||
lockSoundChangesEnd.add(Calendar.MINUTE, Settings.lockSoundChangesInterval);
|
||||
// ActivityMainScreen.getActivityMainScreenInstance().updateMainScreen();
|
||||
}
|
||||
|
||||
public void checkLockSoundChangesTimeElapsed()
|
||||
@ -89,8 +98,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
return myLocationProvider;
|
||||
}
|
||||
|
||||
protected static AutomationService centralInstance = null;
|
||||
|
||||
public static AutomationService getInstance()
|
||||
{
|
||||
return centralInstance;
|
||||
@ -109,18 +116,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
|
||||
{
|
||||
// if (!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, AutomationService.this))
|
||||
// {
|
||||
// /*
|
||||
// Don't have permission to access external storage. This is a show stopper as
|
||||
// the configuration file is stored on external storage.
|
||||
// */
|
||||
// Miscellaneous.logEvent("e", "Permission", "Don't have permission to access external storage. Will request it now.", 4);
|
||||
//// Toast.makeText(AutomationService.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
// ActivityPermissions.requestSpecificPermission(ActivityPermissions.writeExternalStoragePermissionName);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 28)
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE, AutomationService.this))
|
||||
@ -135,10 +130,15 @@ public class AutomationService extends Service implements OnInitListener
|
||||
}
|
||||
}
|
||||
|
||||
if (PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0
|
||||
|
|
||||
Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0
|
||||
)
|
||||
if (
|
||||
PointOfInterest.getPointOfInterestCollection() == null
|
||||
||
|
||||
PointOfInterest.getPointOfInterestCollection().size() == 0
|
||||
||
|
||||
Rule.getRuleCollection() == null
|
||||
||
|
||||
Rule.getRuleCollection().size() == 0
|
||||
)
|
||||
{
|
||||
if (startAtBoot)
|
||||
{
|
||||
@ -173,7 +173,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
}
|
||||
|
||||
//if still no POIs...
|
||||
if (Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0)
|
||||
if (Rule.getRuleCollection() == null || Rule.getRuleCollection().size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "AutomationService", context.getResources().getString(R.string.serviceWontStart), 1);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
@ -194,17 +194,21 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
Bundle b = intent.getExtras();
|
||||
startAtBoot = b.getBoolean("startAtBoot", false);
|
||||
|
||||
if(startAtBoot)
|
||||
Settings.deviceStartDone = false;
|
||||
}
|
||||
|
||||
if (checkStartupRequirements(this, startAtBoot))
|
||||
{
|
||||
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", ActivityControlCenter.getSystemInfo(), 1);
|
||||
|
||||
startUpRoutine();
|
||||
|
||||
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
notificationBuilder = createDefaultNotificationBuilder();
|
||||
notificationBuilder = createServiceNotificationBuilder();
|
||||
|
||||
updateNotification();
|
||||
|
||||
@ -212,14 +216,18 @@ public class AutomationService extends Service implements OnInitListener
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
this.isRunning = true;
|
||||
|
||||
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);
|
||||
// Actions.setData(true);
|
||||
// ********** Test area **********
|
||||
|
||||
return START_STICKY;
|
||||
/*
|
||||
On normal phones the app is supposed to automatically restart in case of any problems.
|
||||
In the emulator we want it to stop to be able to better pinpoint the root cause.
|
||||
*/
|
||||
if(Miscellaneous.isAndroidEmulator())
|
||||
return START_NOT_STICKY;
|
||||
else
|
||||
return START_STICKY;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -240,8 +248,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
reloadSettings, reloadPointsOfInterest, reloadRules, updateNotification
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public void serviceInterface(serviceCommands command)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Bind", "Ahhhh, customers... How can I help you?", 5);
|
||||
@ -273,16 +279,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();
|
||||
@ -290,6 +287,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
|
||||
ReceiverCoordinator.applySettingsAndRules();
|
||||
|
||||
DateTimeListener.reloadAlarms();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -305,7 +304,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);
|
||||
@ -318,18 +317,29 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
private void startUpRoutine()
|
||||
{
|
||||
Settings.serviceStartDone = false;
|
||||
|
||||
checkForTtsEngine();
|
||||
checkForPermissions();
|
||||
checkForRestrictedFeatures();
|
||||
checkForMissingBackgroundLocationPermission();
|
||||
|
||||
Actions.context = this;
|
||||
Actions.autoMationServerRef = this;
|
||||
Actions.automationServerRef = this;
|
||||
|
||||
startLocationProvider();
|
||||
ReceiverCoordinator.startAllReceivers();
|
||||
|
||||
PackageReplacedReceiver.setHasServiceBeenRunning(true, this);
|
||||
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
{
|
||||
if(r.getsGreenLight(AutomationService.this))
|
||||
r.activate(AutomationService.this, false);
|
||||
}
|
||||
|
||||
Settings.serviceStartDone = true;
|
||||
Settings.deviceStartDone = true;
|
||||
}
|
||||
|
||||
protected void startLocationProvider()
|
||||
@ -352,12 +362,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
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;
|
||||
@ -377,9 +383,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
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);
|
||||
Miscellaneous.createDismissibleNotificationWithDelay(1010, null, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
Miscellaneous.createDismissibleNotification(null, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, false, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,19 +407,16 @@ public class AutomationService extends Service implements OnInitListener
|
||||
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);
|
||||
Miscellaneous.createDismissibleNotificationWithDelay(3300, null, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
|
||||
Miscellaneous.createDismissibleNotification(null, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, false, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelNotification()
|
||||
{
|
||||
// stopForeground(false);
|
||||
NotificationManagerCompat.from(AutomationService.this).cancelAll();
|
||||
// NotificationManagerCompat.from(AutomationService.this).cancel(ActivityPermissions.notificationIdPermissions);
|
||||
// NotificationManagerCompat.from(AutomationService.this).cancel(AutomationService.notificationIdRestrictions);
|
||||
}
|
||||
|
||||
protected void checkForMissingBackgroundLocationPermission()
|
||||
@ -426,9 +429,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
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);
|
||||
Miscellaneous.createDismissibleNotificationWithDelay(2200, null, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
Miscellaneous.createDismissibleNotification(null, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, false, AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, pi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,7 +453,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
private void stopRoutine()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
|
||||
// Log.i("STOP", "Stopping");
|
||||
try
|
||||
{
|
||||
myLocationProvider.stopLocationService();
|
||||
@ -465,6 +467,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
ttsEngine.shutdown();
|
||||
|
||||
PackageReplacedReceiver.setHasServiceBeenRunning(false, this);
|
||||
|
||||
centralInstance = null;
|
||||
}
|
||||
|
||||
protected static Builder createDefaultNotificationBuilderOld()
|
||||
@ -479,7 +483,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;
|
||||
@ -497,34 +500,9 @@ 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()
|
||||
protected static NotificationCompat.Builder createServiceNotificationBuilder()
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
@ -532,14 +510,14 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
chan.enableVibration(false);
|
||||
chan.setSound(null, null);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(chan);
|
||||
NotificationChannel channel = Miscellaneous.getNotificationChannel(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE);
|
||||
// channel.setLightColor(Color.BLUE);
|
||||
channel.enableVibration(false);
|
||||
channel.setSound(null, null);
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID);
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID_SERVICE);
|
||||
}
|
||||
else
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
@ -571,79 +549,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(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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// {
|
||||
if(notificationBuilder == null)
|
||||
notificationBuilder = createDefaultNotificationBuilder();
|
||||
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.";
|
||||
}
|
||||
|
||||
notificationBuilder.setContentText(textToDisplay);
|
||||
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
String textToDisplay = bodyText + " " + lastRuleString;
|
||||
|
||||
myNotification = notificationBuilder.build();
|
||||
myNotification.defaults = 0;
|
||||
// }
|
||||
if(notificationBuilder == null)
|
||||
notificationBuilder = createServiceNotificationBuilder();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -667,18 +634,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
|
||||
)
|
||||
{
|
||||
@ -708,12 +675,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -726,31 +693,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)
|
||||
@ -762,7 +704,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;
|
||||
}
|
||||
}
|
||||
@ -771,9 +712,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;
|
||||
}
|
||||
}
|
||||
}
|
22
app/src/main/java/com/jens/automation2/DeviceAdmin.java
Normal file
22
app/src/main/java/com/jens/automation2/DeviceAdmin.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -8,13 +8,16 @@ import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
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.media.AudioAttributes;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
@ -22,6 +25,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
@ -71,16 +75,23 @@ import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.MessageDigest;
|
||||
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;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
@ -95,13 +106,10 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import static android.provider.CalendarContract.CalendarCache.URI;
|
||||
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
||||
import static com.jens.automation2.AutomationService.channelName;
|
||||
|
||||
public class Miscellaneous extends Service
|
||||
{
|
||||
protected static String writeableFolderStringCache = null;
|
||||
@ -213,7 +221,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
|
||||
@ -465,6 +481,8 @@ public class Miscellaneous extends Service
|
||||
return !haystack.equalsIgnoreCase(needle);
|
||||
case Trigger.directionContains:
|
||||
return haystack.toLowerCase().contains(needle.toLowerCase());
|
||||
case Trigger.directionNotContains:
|
||||
return !haystack.toLowerCase().contains(needle.toLowerCase());
|
||||
case Trigger.directionStartsWith:
|
||||
return haystack.toLowerCase().startsWith(needle.toLowerCase());
|
||||
case Trigger.directionEndsWith:
|
||||
@ -474,7 +492,7 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
}
|
||||
|
||||
public static int compareTimes(Time time1, Time time2)
|
||||
public static int compareTimes(TimeObject time1, TimeObject time2)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
|
||||
|
||||
@ -541,6 +559,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
|
||||
@ -604,27 +638,43 @@ public class Miscellaneous extends Service
|
||||
|
||||
if(source.contains("[notificationTitle]"))
|
||||
{
|
||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||
if(NotificationListener.getLastNotification() != null)
|
||||
{
|
||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||
|
||||
if(notificationTitle != null && notificationTitle.length() > 0)
|
||||
source = source.replace("[notificationTitle]", notificationTitle);
|
||||
if (notificationTitle != null && notificationTitle.length() > 0)
|
||||
source = source.replace("[notificationTitle]", notificationTitle);
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationTitle]", "notificationTitle unknown");
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationTitle was empty.", 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
source = source.replace("notificationTitle unknown", notificationTitle);
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationTitle was empty.", 3);
|
||||
source = source.replace("[notificationTitle]", "notificationTitle unknown");
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "lastNotification was empty.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if(source.contains("[notificationText]"))
|
||||
{
|
||||
String notificationText = NotificationListener.getLastNotification().getText();
|
||||
if(NotificationListener.getLastNotification() != null)
|
||||
{
|
||||
String notificationText = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if(notificationText != null && notificationText.length() > 0)
|
||||
source = source.replace("[notificationText]", notificationText);
|
||||
if (notificationText != null && notificationText.length() > 0)
|
||||
source = source.replace("[notificationText]", notificationText);
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationText]", "notificationText unknown");
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationText was empty.", 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
source = source.replace("notificationText unknown", notificationText);
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationText was empty.", 3);
|
||||
source = source.replace("[notificationText]", "notificationText unknown");
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "lastNotification was empty.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,14 +712,6 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
});
|
||||
|
||||
// alertDialog.setNegativeButton(context.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
|
||||
// {
|
||||
// public void onClick(DialogInterface dialog, int whichButton)
|
||||
// {
|
||||
// // Canceled.
|
||||
// }
|
||||
// });
|
||||
|
||||
return alertDialog.create();
|
||||
}
|
||||
|
||||
@ -850,7 +892,7 @@ public class Miscellaneous extends Service
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void createDismissableNotificationWithDelay(long delay, String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
public static void createDismissibleNotificationWithDelay(long delay, String title, String textToDisplay, int notificationId, String notificationChannelId, PendingIntent pendingIntent)
|
||||
{
|
||||
/*
|
||||
Now what's this about?
|
||||
@ -876,7 +918,7 @@ public class Miscellaneous extends Service
|
||||
catch(Exception e)
|
||||
{}
|
||||
|
||||
createDismissableNotification(textToDisplay, notificationId, pendingIntent);
|
||||
createDismissibleNotification(title, textToDisplay, notificationId, true, notificationChannelId, pendingIntent);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -897,40 +939,88 @@ public class Miscellaneous extends Service
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void createDismissableNotification(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
public static void createDismissibleNotification(String title, String textToDisplay, int notificationId, boolean vibrate, String notificationChannelId, PendingIntent pendingIntent)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
createDismissableNotificationSdk26(textToDisplay, notificationId, pendingIntent);
|
||||
createDismissibleNotificationSdk26(title, textToDisplay, notificationId, vibrate, notificationChannelId, pendingIntent);
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationCompat.Builder dismissableNotificationBuilder = createDismissableNotificationBuilder(pendingIntent);
|
||||
dismissableNotificationBuilder.setContentText(textToDisplay);
|
||||
dismissableNotificationBuilder.setContentIntent(pendingIntent);
|
||||
dismissableNotificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
dismissableNotificationBuilder.setAutoCancel(true);
|
||||
NotificationCompat.Builder dismissibleNotificationBuilder = createDismissibleNotificationBuilder(vibrate, notificationChannelId, pendingIntent);
|
||||
|
||||
Notification dismissableNotification = dismissableNotificationBuilder.build();
|
||||
if(title == null)
|
||||
dismissibleNotificationBuilder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||
else
|
||||
dismissibleNotificationBuilder.setContentTitle(title);
|
||||
|
||||
mNotificationManager.notify(notificationId, dismissableNotification);
|
||||
dismissibleNotificationBuilder.setContentText(textToDisplay);
|
||||
dismissibleNotificationBuilder.setContentIntent(pendingIntent);
|
||||
dismissibleNotificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
dismissibleNotificationBuilder.setAutoCancel(true);
|
||||
|
||||
/*NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_launcher) // notification icon
|
||||
.setContentTitle("Notification!") // title for notification
|
||||
.setContentText("Hello word") // message for notification
|
||||
.setAutoCancel(true); // clear notification after click
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mBuilder.setContentIntent(pi);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.notify(0, dismissableNotification);*/
|
||||
if(notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_RULES))
|
||||
dismissibleNotificationBuilder.setSmallIcon(R.drawable.info);
|
||||
|
||||
Notification dismissibleNotification = dismissibleNotificationBuilder.build();
|
||||
|
||||
mNotificationManager.notify(notificationId, dismissibleNotification);
|
||||
}
|
||||
|
||||
static void createDismissableNotificationSdk26(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
static NotificationChannel findExistingChannel(List<NotificationChannel> channels, String channelId)
|
||||
{
|
||||
for(NotificationChannel c : channels)
|
||||
{
|
||||
if(c.getId().equals(channelId))
|
||||
return c;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
static NotificationChannel getNotificationChannel(String channelId)
|
||||
{
|
||||
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
List<NotificationChannel> channels = nm.getNotificationChannels();
|
||||
|
||||
if(!Settings.hasBeenDone(Settings.constNotificationChannelCleanupApk118) && BuildConfig.VERSION_CODE < 120)
|
||||
{
|
||||
// Perform a one-time cleanup of notification channels as they have been redesigned.
|
||||
|
||||
for(NotificationChannel c : channels)
|
||||
nm.deleteNotificationChannel(c.getId());
|
||||
|
||||
Settings.considerDone(Settings.constNotificationChannelCleanupApk118);
|
||||
Settings.writeSettings(Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
NotificationChannel channel = findExistingChannel(channels, channelId);
|
||||
|
||||
if(channel == null)
|
||||
{
|
||||
switch (channelId)
|
||||
{
|
||||
case AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE:
|
||||
channel = new NotificationChannel(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE, AutomationService.NOTIFICATION_CHANNEL_NAME_SERVICE, NotificationManager.IMPORTANCE_LOW);
|
||||
break;
|
||||
case AutomationService.NOTIFICATION_CHANNEL_ID_FUNCTIONALITY:
|
||||
channel = new NotificationChannel(AutomationService.NOTIFICATION_CHANNEL_ID_FUNCTIONALITY, AutomationService.NOTIFICATION_CHANNEL_NAME_FUNCTIONALITY, NotificationManager.IMPORTANCE_HIGH);
|
||||
break;
|
||||
case AutomationService.NOTIFICATION_CHANNEL_ID_RULES:
|
||||
channel = new NotificationChannel(AutomationService.NOTIFICATION_CHANNEL_ID_RULES, AutomationService.NOTIFICATION_CHANNEL_NAME_RULES, NotificationManager.IMPORTANCE_HIGH);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void createDismissibleNotificationSdk26(String title, String textToDisplay, int notificationId, boolean vibrate, String notificationChannelId, PendingIntent pendingIntent)
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
@ -938,29 +1028,44 @@ public class Miscellaneous extends Service
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Functionality warnings", NotificationManager.IMPORTANCE_HIGH);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
chan.enableVibration(false);
|
||||
// chan.setSound(null, null);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(chan);
|
||||
NotificationChannel notificationChannel = getNotificationChannel(notificationChannelId);
|
||||
// notificationChannel.setLightColor(Color.BLUE);
|
||||
notificationChannel.enableVibration(vibrate);
|
||||
try
|
||||
{
|
||||
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
// Uri notificationSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+ "://" +mContext.getPackageName()+"/"+R.raw.apple_ring));
|
||||
// Ringtone r = RingtoneManager.getRingtone(Miscellaneous.getAnyContext(), notification);
|
||||
AudioAttributes.Builder b = new AudioAttributes.Builder();
|
||||
b.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN);
|
||||
notificationChannel.setSound(notificationSound, b.build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Notification", Log.getStackTraceString(e), 2);
|
||||
}
|
||||
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(notificationChannel);
|
||||
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID);
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), notificationChannel.getId());
|
||||
}
|
||||
else
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
// builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setContentIntent(pendingIntent);
|
||||
|
||||
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||
if(title == null)
|
||||
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||
else
|
||||
builder.setContentTitle(title);
|
||||
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
else if(!notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
builder.setSmallIcon(R.drawable.info);
|
||||
|
||||
builder.setContentText(textToDisplay);
|
||||
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
@ -968,7 +1073,6 @@ public class Miscellaneous extends Service
|
||||
NotificationManager notificationManager = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(1, builder.build());
|
||||
|
||||
|
||||
// Intent notifyIntent = new Intent(context, notification.class);
|
||||
// notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
//
|
||||
@ -990,7 +1094,7 @@ public class Miscellaneous extends Service
|
||||
// notificationManager.notify(1, notification);
|
||||
}
|
||||
|
||||
protected static NotificationCompat.Builder createDismissableNotificationBuilder(PendingIntent myPendingIntent)
|
||||
protected static NotificationCompat.Builder createDismissibleNotificationBuilder(boolean vibrate, String notificationChannelId, PendingIntent myPendingIntent)
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
@ -998,14 +1102,14 @@ public class Miscellaneous extends Service
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
// chan.enableVibration(false);
|
||||
// chan.setSound(null, null);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(chan);
|
||||
NotificationChannel notificationChannel = getNotificationChannel(notificationChannelId);
|
||||
// notificationChannel.setLightColor(Color.BLUE);
|
||||
notificationChannel.enableVibration(vibrate);
|
||||
// notificationChannel.setSound(null, null);
|
||||
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(notificationChannel);
|
||||
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID);
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), notificationChannelId);
|
||||
}
|
||||
else
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
@ -1046,6 +1150,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;
|
||||
@ -1066,7 +1187,8 @@ public class Miscellaneous extends Service
|
||||
|
||||
public static double round(double value, int places)
|
||||
{
|
||||
if (places < 0) throw new IllegalArgumentException();
|
||||
if (places < 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
BigDecimal bd = new BigDecimal(Double.toString(value));
|
||||
bd = bd.setScale(places, RoundingMode.HALF_UP);
|
||||
@ -1078,7 +1200,7 @@ public class Miscellaneous extends Service
|
||||
Cursor cursor = null;
|
||||
try
|
||||
{
|
||||
String[] proj = { MediaStore.Images.Media.DATA };
|
||||
String[] proj = { MediaStore.Images.Media.DATA, MediaStore.Audio.Media.DATA };
|
||||
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
@ -1098,6 +1220,114 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRealPathFromURI2(final Context context, final Uri uri)
|
||||
{
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
|
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
|
||||
{
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri))
|
||||
{
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
if ("primary".equalsIgnoreCase(type))
|
||||
{
|
||||
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
}
|
||||
}
|
||||
// DownloadsProvider
|
||||
else if (isDownloadsDocument(uri))
|
||||
{
|
||||
|
||||
final String id = DocumentsContract.getDocumentId(uri);
|
||||
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
||||
|
||||
return getDataColumn(context, contentUri, null, null);
|
||||
}
|
||||
// MediaProvider
|
||||
else if (isMediaDocument(uri))
|
||||
{
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
Uri contentUri = null;
|
||||
if ("image".equals(type))
|
||||
{
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
else if ("video".equals(type))
|
||||
{
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
else if ("audio".equals(type))
|
||||
{
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
|
||||
final String selection = "_id=?";
|
||||
final String[] selectionArgs = new String[] { split[1] };
|
||||
|
||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
}
|
||||
}
|
||||
// MediaStore (and general)
|
||||
else if ("content".equalsIgnoreCase(uri.getScheme()))
|
||||
{
|
||||
return getDataColumn(context, uri, null, null);
|
||||
}
|
||||
// File
|
||||
else if ("file".equalsIgnoreCase(uri.getScheme()))
|
||||
{
|
||||
return uri.getPath();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs)
|
||||
{
|
||||
Cursor cursor = null;
|
||||
final String column = "_data";
|
||||
final String[] projection = { column };
|
||||
|
||||
try
|
||||
{
|
||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
||||
null);
|
||||
if (cursor != null && cursor.moveToFirst())
|
||||
{
|
||||
final int column_index = cursor.getColumnIndexOrThrow(column);
|
||||
return cursor.getString(column_index);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isExternalStorageDocument(Uri uri)
|
||||
{
|
||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
public static boolean isDownloadsDocument(Uri uri)
|
||||
{
|
||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
public static boolean isMediaDocument(Uri uri)
|
||||
{
|
||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
public static Method getClassMethodReflective(String className, String methodName)
|
||||
{
|
||||
Class foundClass = null;
|
||||
@ -1133,11 +1363,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;
|
||||
@ -1532,4 +1762,135 @@ public class Miscellaneous extends Service
|
||||
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;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
if(matchFullLine)
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.equals(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().equals(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.contains(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().contains(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(ArrayList<String> requestList, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
return arraySearch(requestList.toArray(new String[requestList.size()]), needle, caseSensitive, matchFullLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
|
||||
* @param context Context reference to get the TelephonyManager instance from
|
||||
* @return country code or null
|
||||
*/
|
||||
public static String getUserCountry(Context context)
|
||||
{
|
||||
try
|
||||
{
|
||||
final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
final String simCountry = tm.getSimCountryIso();
|
||||
if (simCountry != null && simCountry.length() == 2)
|
||||
{ // SIM country code is available
|
||||
return simCountry.toLowerCase(Locale.US);
|
||||
}
|
||||
else if (tm.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA)
|
||||
{ // device is not 3G (would be unreliable)
|
||||
String networkCountry = tm.getNetworkCountryIso();
|
||||
if (networkCountry != null && networkCountry.length() == 2)
|
||||
{ // network country code is available
|
||||
return networkCountry.toLowerCase(Locale.US);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
catch (Exception e)
|
||||
{ }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String checksumSha(String filepath) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
MessageDigest md = null;
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
// file hashing with DigestInputStream
|
||||
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md))
|
||||
{
|
||||
while (dis.read() != -1)
|
||||
; //empty loop to clear the data
|
||||
md = dis.getMessageDigest();
|
||||
}
|
||||
|
||||
// bytes to hex
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : md.digest())
|
||||
{
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "shaChecksum", Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -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
|
||||
@ -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);
|
||||
|
@ -1,12 +1,15 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -14,10 +17,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;
|
||||
@ -267,7 +272,7 @@ public class Profile implements Comparable<Profile>
|
||||
return hapticFeedback;
|
||||
}
|
||||
|
||||
public static ArrayList<Profile> getProfileCollection()
|
||||
public static List<Profile> getProfileCollection()
|
||||
{
|
||||
return profileCollection;
|
||||
}
|
||||
@ -288,18 +293,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);
|
||||
@ -309,29 +308,31 @@ public class Profile implements Comparable<Profile>
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MediaStore.MediaColumns.DATA, ringtoneFile.getAbsolutePath());
|
||||
// values.put(MediaStore.MediaColumns.TITLE, context.getResources().getString(R.string.app_name) + " ringtone");
|
||||
// values.put(MediaStore.MediaColumns.TITLE, ringtoneFile.getName().replace(".mp3", "").replace(".", ""));
|
||||
values.put(MediaStore.MediaColumns.TITLE, ringtoneFile.getName());
|
||||
// values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
|
||||
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
|
||||
values.put(MediaStore.MediaColumns.SIZE, ringtoneFile.length());
|
||||
// values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
|
||||
values.put(MediaStore.Audio.Media.IS_RINGTONE, ringtoneType == RingtoneManager.TYPE_RINGTONE);
|
||||
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, ringtoneType == RingtoneManager.TYPE_NOTIFICATION);
|
||||
values.put(MediaStore.Audio.Media.IS_ALARM, false);
|
||||
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
|
||||
|
||||
Uri existingRingTone = MediaStore.Audio.Media.getContentUriForPath(ringtoneFile.getAbsolutePath());
|
||||
if(existingRingTone != null)
|
||||
context.getContentResolver().delete(existingRingTone, MediaStore.MediaColumns.DATA + "=\"" + ringtoneFile.getAbsolutePath() + "\"", null);
|
||||
Uri newRingTone = context.getContentResolver().insert(existingRingTone, values);
|
||||
|
||||
try
|
||||
{
|
||||
Uri newRingTone = null;
|
||||
|
||||
//TODO: This part needs to be made compatible with Android 11 and above.
|
||||
if(Build.VERSION.SDK_INT > 30)
|
||||
{
|
||||
Uri existingRingTone = MediaStore.Audio.Media.getContentUriForPath(ringtoneFile.getAbsolutePath());
|
||||
|
||||
if (existingRingTone != null)
|
||||
context.getContentResolver().delete(existingRingTone, MediaStore.MediaColumns.DATA + "=\"" + ringtoneFile.getAbsolutePath() + "\"", null);
|
||||
|
||||
newRingTone = context.getContentResolver().insert(existingRingTone, values);
|
||||
}
|
||||
|
||||
RingtoneManager.setActualDefaultRingtoneUri(context, ringtoneType, newRingTone);
|
||||
Miscellaneous.logEvent("i", "Profile", "Ringtone set to: " + newRingTone.toString(), 1);
|
||||
// Ringtone tone = RingtoneManager.getRingtone(context, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
|
||||
// tone.play();
|
||||
return true;
|
||||
}
|
||||
catch (Throwable t)
|
||||
@ -390,11 +391,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)
|
||||
@ -423,20 +436,39 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
|
||||
{
|
||||
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
|
||||
{
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean delete(Context context)
|
||||
{
|
||||
Rule usingRule = this.isInUseByRules();
|
||||
if(usingRule != null)
|
||||
{
|
||||
Toast.makeText(context, String.format(context.getResources().getString(R.string.ruleXIsUsingProfileY), usingRule.getName(), this.getName()), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
profileCollection.remove(this);
|
||||
return XmlFileInterface.writeFile();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean plausibilityCheck()
|
||||
@ -463,6 +495,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)
|
||||
@ -534,6 +568,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
|
||||
{
|
||||
@ -541,6 +589,146 @@ 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)
|
||||
{
|
||||
Uri ringtone_uri = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE);
|
||||
|
||||
if (ringtone_uri != null)
|
||||
{
|
||||
// if ringtone_uri is null get Default Ringtone
|
||||
ringtone_uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
|
||||
|
||||
Ringtone currentRingtone = RingtoneManager.getRingtone(context, ringtone_uri);
|
||||
String title = currentRingtone.getTitle(context);
|
||||
*//* Ringtone desiredRingtone = RingtoneManager.getRingtone(context, Uri.fromFile(notificationRingtone));
|
||||
boolean result = currentRingtone.equals(desiredRingtone);*//*
|
||||
|
||||
Uri desired_ringtone = MediaStore.Audio.Media.getContentUriForPath(incomingCallsRingtone.getAbsolutePath());
|
||||
|
||||
// File currentRingtoneFile = new File(Miscellaneous.getRealPathFromURI(context, ringtone_uri));
|
||||
String currentChecksum = Miscellaneous.checksumSha(ringtone_uri.getPath());
|
||||
String desiredChecksum = Miscellaneous.checksumSha(incomingCallsRingtone.getAbsolutePath());
|
||||
|
||||
if (!currentChecksum.equals(desiredChecksum))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
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)
|
||||
{
|
||||
Uri ringtone_uri = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION);
|
||||
|
||||
if (ringtone_uri == null)
|
||||
{
|
||||
// if ringtone_uri is null get Default Ringtone
|
||||
ringtone_uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
|
||||
|
||||
File currentRingtone = new File(Settings.System.DEFAULT_NOTIFICATION_URI.getPath());
|
||||
|
||||
// File currentRingtone = new File(Miscellaneous.getRealPathFromURI(context, ringtone_uri));
|
||||
|
||||
String currentChecksum = Miscellaneous.checksumSha(currentRingtone.getAbsolutePath());
|
||||
String desiredChecksum = Miscellaneous.checksumSha(notificationRingtone.getAbsolutePath());
|
||||
|
||||
if(!currentChecksum.equals(desiredChecksum))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
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()
|
||||
{
|
||||
@ -576,4 +764,11 @@ public class Profile implements Comparable<Profile>
|
||||
return this.oldName;
|
||||
}
|
||||
|
||||
public static Profile getLastActivatedProfile()
|
||||
{
|
||||
if(Profile.profileActivationHistory != null && Profile.profileActivationHistory.size() > 0)
|
||||
return Profile.profileActivationHistory.get(Profile.profileActivationHistory.size() - 1);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,19 @@ 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.BroadcastListener;
|
||||
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.MediaPlayerListener;
|
||||
import com.jens.automation2.receivers.NoiseListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
import com.jens.automation2.receivers.ProcessListener;
|
||||
import com.jens.automation2.receivers.ScreenStateReceiver;
|
||||
import com.jens.automation2.receivers.TimeZoneListener;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
@ -42,32 +46,37 @@ 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,
|
||||
//NotificationListener.class,
|
||||
PhoneStatusListener.class,
|
||||
ProcessListener.class,
|
||||
MediaPlayerListener.class,
|
||||
ScreenStateReceiver.class,
|
||||
TimeZoneListener.class
|
||||
};
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
|
||||
allImplementers = new Class[] {
|
||||
AlarmListener.class,
|
||||
DateTimeListener.class,
|
||||
BatteryReceiver.class,
|
||||
BluetoothReceiver.class,
|
||||
BroadcastListener.class,
|
||||
ConnectivityReceiver.class,
|
||||
DeviceOrientationListener.class,
|
||||
HeadphoneJackListener.class,
|
||||
//NfcReceiver.class,
|
||||
NoiseListener.class,
|
||||
PhoneStatusListener.class,
|
||||
ProcessListener.class,
|
||||
ScreenStateReceiver.class,
|
||||
TimeZoneListener.class
|
||||
};
|
||||
}
|
||||
@ -131,12 +140,6 @@ public class ReceiverCoordinator
|
||||
Miscellaneous.logEvent("w", "Error in new model", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
// if(Settings.useAccelerometerForPositioning && !Miscellaneous.isAndroidEmulator())
|
||||
// {
|
||||
// accelerometerHandler = new AccelerometerHandler();
|
||||
// mySensorActivity = new SensorActivity(this);
|
||||
// }
|
||||
|
||||
// startPhoneStateListener
|
||||
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
|
||||
|
||||
@ -155,39 +158,47 @@ public class ReceiverCoordinator
|
||||
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
|
||||
|
||||
// startAlarmListener
|
||||
AlarmListener.startAlarmListener(AutomationService.getInstance());
|
||||
DateTimeListener.startAlarmListener(AutomationService.getInstance());
|
||||
TimeZoneListener.startTimeZoneListener(AutomationService.getInstance());
|
||||
|
||||
// startNoiseListener
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.noiseLevel))
|
||||
NoiseListener.startNoiseListener(AutomationService.getInstance());
|
||||
|
||||
// startNoiseListener
|
||||
// startBroadcastListener
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.broadcastReceived))
|
||||
BroadcastListener.getInstance().startListener(AutomationService.getInstance());
|
||||
|
||||
// startProcessListener
|
||||
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)
|
||||
{
|
||||
// Nothing to do, just not starting this one.
|
||||
}
|
||||
|
||||
//startBluetoothReceiver
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.bluetoothConnection))
|
||||
BluetoothReceiver.startBluetoothReceiver();
|
||||
|
||||
//startHeadsetJackListener
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.headsetPlugged))
|
||||
HeadphoneJackListener.getInstance().startListener(AutomationService.getInstance());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.musicPlaying))
|
||||
MediaPlayerListener.getInstance().startListener(AutomationService.getInstance());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
|
||||
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
public static void stopAllReceivers()
|
||||
@ -199,23 +210,26 @@ public class ReceiverCoordinator
|
||||
WifiBroadcastReceiver.stopWifiReceiver();
|
||||
BatteryReceiver.stopBatteryReceiver();
|
||||
TimeZoneListener.stopTimeZoneListener();
|
||||
AlarmListener.stopAlarmListener(AutomationService.getInstance());
|
||||
DateTimeListener.stopAlarmListener(AutomationService.getInstance());
|
||||
NoiseListener.stopNoiseListener();
|
||||
BroadcastListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
ProcessListener.stopProcessListener(AutomationService.getInstance());
|
||||
MediaPlayerListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
|
||||
try
|
||||
{
|
||||
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
|
||||
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
|
||||
}
|
||||
catch(ClassNotFoundException e)
|
||||
catch(Exception e)
|
||||
{
|
||||
// Nothing to do, just not stopping this one.
|
||||
}
|
||||
|
||||
BluetoothReceiver.stopBluetoothReceiver();
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -239,7 +253,7 @@ public class ReceiverCoordinator
|
||||
|
||||
// timeFrame -> too inexpensive to shutdown
|
||||
|
||||
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))
|
||||
{
|
||||
if(BatteryReceiver.haveAllPermission())
|
||||
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
|
||||
@ -259,6 +273,17 @@ public class ReceiverCoordinator
|
||||
NoiseListener.stopNoiseListener();
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.broadcastReceived))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting BroadcastReceiver because used in a new/changed rule.", 4);
|
||||
BroadcastListener.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down BroadcastReceiver because not used in any rule.", 4);
|
||||
BroadcastListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting ProcessListener because used in a new/changed rule.", 4);
|
||||
@ -271,6 +296,28 @@ public class ReceiverCoordinator
|
||||
ProcessListener.stopProcessListener(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting ScreenStateListener because used in a new/changed rule.", 4);
|
||||
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ScreenStateListener because not used in any rule.", 4);
|
||||
ScreenStateReceiver.stopScreenStateReceiver();
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.musicPlaying))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting MediaPlayerListener because used in a new/changed rule.", 4);
|
||||
MediaPlayerListener.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down MediaPlayerListener because not used in any rule.", 4);
|
||||
MediaPlayerListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
{
|
||||
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
@ -350,6 +397,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();
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import java.util.Set;
|
||||
public class Settings implements SharedPreferences
|
||||
{
|
||||
public static final int rulesThatHaveBeenRanHistorySize = 10;
|
||||
public final static int lockSoundChangesInterval = 15;
|
||||
public static final int lockSoundChangesInterval = 15;
|
||||
public static final int newsPollEveryXDays = 3;
|
||||
public static final int newsDisplayForXDays = 3;
|
||||
public static final int updateCheckFrequencyDays = 7;
|
||||
@ -20,6 +20,7 @@ public class Settings implements SharedPreferences
|
||||
public static final String zipFileName = "automation.zip";
|
||||
|
||||
public static final String constNewsOptInDone ="newsOptInDone";
|
||||
public static final String constNotificationChannelCleanupApk118 ="notificationChannelCleanupApk118";
|
||||
|
||||
public static long minimumDistanceChangeForGpsUpdate;
|
||||
public static long minimumDistanceChangeForNetworkUpdate;
|
||||
@ -56,6 +57,7 @@ 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;
|
||||
@ -64,6 +66,7 @@ public class Settings implements SharedPreferences
|
||||
public static boolean executeRulesAndProfilesWithSingleClick;
|
||||
public static boolean displayNewsOnMainScreen;
|
||||
public static boolean automaticUpdateCheck;
|
||||
public static long musicCheckFrequency;
|
||||
|
||||
public static boolean lockSoundChanges;
|
||||
public static boolean noticeAndroid9MicrophoneShown;
|
||||
@ -74,56 +77,64 @@ public class Settings implements SharedPreferences
|
||||
public static ArrayList<String> whatHasBeenDone;
|
||||
|
||||
/*
|
||||
Generic settings valid for all installations and not changable
|
||||
Not saved permanently.
|
||||
*/
|
||||
public static boolean deviceStartDone = true; // by default assume device has not just been started
|
||||
public static boolean serviceStartDone = false;
|
||||
|
||||
/*
|
||||
Generic settings valid for all installations and not changeable
|
||||
*/
|
||||
public static final String dateFormat = "E dd.MM.yyyy HH:mm:ss:ssss";
|
||||
|
||||
protected static final int default_positioningEngine = 0;
|
||||
protected static final long default_minimumDistanceChangeForGpsUpdate = 100;
|
||||
protected static final long default_minimumDistanceChangeForNetworkUpdate = 500; // in Meters
|
||||
protected static final long default_satisfactoryAccuracyGps = 50;
|
||||
protected static final long default_satisfactoryAccuracyNetwork = 1000;
|
||||
protected static final int default_gpsTimeout = 300; // seconds
|
||||
protected static final long default_minimumTimeBetweenUpdate = 30000; // in Milliseconds
|
||||
protected static final boolean default_startServiceAtSystemBoot = false;
|
||||
protected static final boolean default_writeLogFile = false;
|
||||
protected static final long default_logLevel = 2;
|
||||
protected static final int default_logFileMaxSize = 10;
|
||||
protected static final boolean default_useTextToSpeechOnNormal = false;
|
||||
protected static final boolean default_useTextToSpeechOnVibrate = false;
|
||||
protected static final boolean default_useTextToSpeechOnSilent = false;
|
||||
protected static final boolean default_muteTextToSpeechDuringCalls = true;
|
||||
protected static final boolean default_useWifiForPositioning = true;
|
||||
protected static final boolean default_useAccelerometerForPositioning = true;
|
||||
protected static final long default_useAccelerometerAfterIdleTime = 5;
|
||||
protected static final long default_accelerometerMovementThreshold = 2;
|
||||
protected static final long default_speedMaximumTimeBetweenLocations = 4;
|
||||
protected static final long default_timeBetweenNoiseLevelMeasurements = 60;
|
||||
protected static final long default_lengthOfNoiseLevelMeasurements = 5;
|
||||
protected static final long default_referenceValueForNoiseLevelMeasurements = 20;
|
||||
protected static final boolean default_hasServiceBeenRunning = false;
|
||||
protected static final boolean default_startServiceAfterAppUpdate = true;
|
||||
protected static final boolean default_startNewThreadForRuleActivation = true;
|
||||
protected static final boolean default_showIconWhenServiceIsRunning = true;
|
||||
protected static final boolean default_httpAcceptAllCertificates = false;
|
||||
protected static final int default_httpAttempts = 3;
|
||||
protected static final int default_httpAttemptsTimeout = 60;
|
||||
protected static final int default_httpAttemptGap = 2;
|
||||
protected static final PointOfInterest default_lastActivePoi = null;
|
||||
protected static final boolean default_rememberLastActivePoi = true;
|
||||
protected static final int default_locationRingBufferSize=3;
|
||||
protected static final long default_timeBetweenProcessMonitorings = 60;
|
||||
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;
|
||||
public static final int default_positioningEngine = 0;
|
||||
public static final long default_minimumDistanceChangeForGpsUpdate = 100;
|
||||
public static final long default_minimumDistanceChangeForNetworkUpdate = 500; // in Meters
|
||||
public static final long default_satisfactoryAccuracyGps = 50;
|
||||
public static final long default_satisfactoryAccuracyNetwork = 1000;
|
||||
public static final int default_gpsTimeout = 300; // seconds
|
||||
public static final long default_minimumTimeBetweenUpdate = 30000; // in Milliseconds
|
||||
public static final boolean default_startServiceAtSystemBoot = false;
|
||||
public static final boolean default_writeLogFile = false;
|
||||
public static final long default_logLevel = 2;
|
||||
public static final int default_logFileMaxSize = 10;
|
||||
public static final boolean default_useTextToSpeechOnNormal = false;
|
||||
public static final boolean default_useTextToSpeechOnVibrate = false;
|
||||
public static final boolean default_useTextToSpeechOnSilent = false;
|
||||
public static final boolean default_muteTextToSpeechDuringCalls = true;
|
||||
public static final boolean default_useWifiForPositioning = true;
|
||||
public static final boolean default_useAccelerometerForPositioning = true;
|
||||
public static final long default_useAccelerometerAfterIdleTime = 5;
|
||||
public static final long default_accelerometerMovementThreshold = 2;
|
||||
public static final long default_speedMaximumTimeBetweenLocations = 4;
|
||||
public static final long default_timeBetweenNoiseLevelMeasurements = 60;
|
||||
public static final long default_lengthOfNoiseLevelMeasurements = 5;
|
||||
public static final long default_referenceValueForNoiseLevelMeasurements = 20;
|
||||
public static final boolean default_hasServiceBeenRunning = false;
|
||||
public static final boolean default_startServiceAfterAppUpdate = true;
|
||||
public static final boolean default_startNewThreadForRuleActivation = true;
|
||||
public static final boolean default_showIconWhenServiceIsRunning = true;
|
||||
public static final boolean default_httpAcceptAllCertificates = false;
|
||||
public static final int default_httpAttempts = 3;
|
||||
public static final int default_httpAttemptsTimeout = 60;
|
||||
public static final int default_httpAttemptGap = 2;
|
||||
public static final PointOfInterest default_lastActivePoi = null;
|
||||
public static final boolean default_rememberLastActivePoi = true;
|
||||
public static final int default_locationRingBufferSize=3;
|
||||
public static final long default_timeBetweenProcessMonitorings = 60;
|
||||
public static final long default_acceptDevicePositionSignalEveryX_MilliSeconds = 1000;
|
||||
public static final int default_activityDetectionFrequency = 60;
|
||||
public static final int default_activityDetectionRequiredProbability = 75;
|
||||
public static final boolean default_privacyLocationing = false;
|
||||
public static final int default_startScreen = 0;
|
||||
public static final int default_tabsPlacement = 0;
|
||||
public static final boolean default_executeRulesAndProfilesWithSingleClick = false;
|
||||
public static final boolean default_displayNewsOnMainScreen = false;
|
||||
public static final boolean default_automaticUpdateCheck = false;
|
||||
public static final boolean default_lockSoundChanges = false;
|
||||
public static final long default_lastNewsPolltime = -1;
|
||||
public static final long default_lastUpdateCheck = -1;
|
||||
public static final long default_musicCheckFrequency = 2500;
|
||||
|
||||
@Override
|
||||
public boolean contains(String arg0)
|
||||
@ -236,6 +247,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)));
|
||||
@ -257,6 +269,11 @@ public class Settings implements SharedPreferences
|
||||
startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
|
||||
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
|
||||
|
||||
musicCheckFrequency = Long.parseLong(prefs.getString("musicCheckFrequency", String.valueOf(default_musicCheckFrequency)));
|
||||
|
||||
if(Settings.musicCheckFrequency == 0)
|
||||
Settings.musicCheckFrequency = Settings.default_musicCheckFrequency;
|
||||
|
||||
executeRulesAndProfilesWithSingleClick = prefs.getBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
automaticUpdateCheck = prefs.getBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
displayNewsOnMainScreen = prefs.getBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
@ -323,151 +340,154 @@ public class Settings implements SharedPreferences
|
||||
|
||||
Editor editor = prefs.edit();
|
||||
|
||||
if(!prefs.contains("startServiceAtSystemBoot") | force)
|
||||
if(!prefs.contains("startServiceAtSystemBoot") || force)
|
||||
editor.putBoolean("startServiceAtSystemBoot", default_startServiceAtSystemBoot);
|
||||
|
||||
if(!prefs.contains("writeLogFile") | force)
|
||||
if(!prefs.contains("writeLogFile") || force)
|
||||
editor.putBoolean("writeLogFile", default_writeLogFile);
|
||||
|
||||
// if(!prefs.contains("useTextToSpeech") | force)
|
||||
// editor.putBoolean("useTextToSpeech", default_useTextToSpeech);
|
||||
|
||||
if(!prefs.contains("useTextToSpeechOnNormal") | force)
|
||||
if(!prefs.contains("useTextToSpeechOnNormal") || force)
|
||||
editor.putBoolean("useTextToSpeechOnNormal", default_useTextToSpeechOnNormal);
|
||||
|
||||
if(!prefs.contains("useTextToSpeechOnVibrate") | force)
|
||||
if(!prefs.contains("useTextToSpeechOnVibrate") || force)
|
||||
editor.putBoolean("useTextToSpeechOnVibrate", default_useTextToSpeechOnVibrate);
|
||||
|
||||
if(!prefs.contains("useTextToSpeechOnSilent") | force)
|
||||
if(!prefs.contains("useTextToSpeechOnSilent") || force)
|
||||
editor.putBoolean("useTextToSpeechOnSilent", default_useTextToSpeechOnSilent);
|
||||
|
||||
if(!prefs.contains("muteTextToSpeechDuringCalls") | force)
|
||||
if(!prefs.contains("muteTextToSpeechDuringCalls") || force)
|
||||
editor.putBoolean("muteTextToSpeechDuringCalls", default_muteTextToSpeechDuringCalls);
|
||||
|
||||
if(!prefs.contains("positioningEngine") | force)
|
||||
if(!prefs.contains("positioningEngine") || force)
|
||||
editor.putString("positioningEngine", String.valueOf(default_positioningEngine));
|
||||
|
||||
if(!prefs.contains("useWifiForPositioning") | force)
|
||||
if(!prefs.contains("useWifiForPositioning") || force)
|
||||
editor.putBoolean("useWifiForPositioning", default_useWifiForPositioning);
|
||||
|
||||
if(!prefs.contains("hasServiceBeenRunning") | force)
|
||||
if(!prefs.contains("hasServiceBeenRunning") || force)
|
||||
editor.putBoolean("hasServiceBeenRunning", default_hasServiceBeenRunning);
|
||||
|
||||
if(!prefs.contains("startServiceAfterAppUpdate") | force)
|
||||
if(!prefs.contains("startServiceAfterAppUpdate") || force)
|
||||
editor.putBoolean("startServiceAfterAppUpdate", default_startServiceAfterAppUpdate);
|
||||
|
||||
if(!prefs.contains("startNewThreadForRuleActivation") | force)
|
||||
if(!prefs.contains("startNewThreadForRuleActivation") || force)
|
||||
editor.putBoolean("startNewThreadForRuleActivation", default_startNewThreadForRuleActivation);
|
||||
|
||||
if(!prefs.contains("showIconWhenServiceIsRunning") | force)
|
||||
if(!prefs.contains("showIconWhenServiceIsRunning") || force)
|
||||
editor.putBoolean("showIconWhenServiceIsRunning", default_showIconWhenServiceIsRunning);
|
||||
|
||||
if(!prefs.contains("useAccelerometerForPositioning") | force)
|
||||
if(!prefs.contains("useAccelerometerForPositioning") || force)
|
||||
editor.putBoolean("useAccelerometerForPositioning", default_useAccelerometerForPositioning);
|
||||
|
||||
if(!prefs.contains("useAccelerometerAfterIdleTime") | force)
|
||||
if(!prefs.contains("useAccelerometerAfterIdleTime") || force)
|
||||
editor.putString("useAccelerometerAfterIdleTime", String.valueOf(default_useAccelerometerAfterIdleTime));
|
||||
|
||||
if(!prefs.contains("accelerometerMovementThreshold") | force)
|
||||
if(!prefs.contains("accelerometerMovementThreshold") || force)
|
||||
editor.putString("accelerometerMovementThreshold", String.valueOf(default_accelerometerMovementThreshold));
|
||||
|
||||
if(!prefs.contains("speedMaximumTimeBetweenLocations") | force)
|
||||
if(!prefs.contains("speedMaximumTimeBetweenLocations") || force)
|
||||
editor.putString("speedMaximumTimeBetweenLocations", String.valueOf(default_speedMaximumTimeBetweenLocations));
|
||||
|
||||
if(!prefs.contains("MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE") | force)
|
||||
if(!prefs.contains("MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE") || force)
|
||||
editor.putString("MINIMUM_DISTANCE_CHANGE_FOR_GPS_UPDATE", String.valueOf(default_minimumDistanceChangeForGpsUpdate));
|
||||
|
||||
if(!prefs.contains("MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE") | force)
|
||||
if(!prefs.contains("MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE") || force)
|
||||
editor.putString("MINIMUM_DISTANCE_CHANGE_FOR_NETWORK_UPDATE", String.valueOf(default_minimumDistanceChangeForNetworkUpdate));
|
||||
|
||||
if(!prefs.contains("SATISFACTORY_ACCURACY_GPS") | force)
|
||||
if(!prefs.contains("SATISFACTORY_ACCURACY_GPS") || force)
|
||||
editor.putString("SATISFACTORY_ACCURACY_GPS", String.valueOf(default_satisfactoryAccuracyGps));
|
||||
|
||||
if(!prefs.contains("SATISFACTORY_ACCURACY_NETWORK") | force)
|
||||
if(!prefs.contains("SATISFACTORY_ACCURACY_NETWORK") || force)
|
||||
editor.putString("SATISFACTORY_ACCURACY_NETWORK", String.valueOf(default_satisfactoryAccuracyNetwork));
|
||||
|
||||
if(!prefs.contains("gpsTimeout") | force)
|
||||
if(!prefs.contains("gpsTimeout") || force)
|
||||
editor.putString("gpsTimeout", String.valueOf(default_gpsTimeout));
|
||||
|
||||
if(!prefs.contains("MINIMUM_TIME_BETWEEN_UPDATE") | force)
|
||||
if(!prefs.contains("MINIMUM_TIME_BETWEEN_UPDATE") || force)
|
||||
editor.putString("MINIMUM_TIME_BETWEEN_UPDATE", String.valueOf(default_minimumTimeBetweenUpdate));
|
||||
|
||||
if(!prefs.contains("timeBetweenNoiseLevelMeasurements") | force)
|
||||
if(!prefs.contains("timeBetweenNoiseLevelMeasurements") || force)
|
||||
editor.putString("timeBetweenNoiseLevelMeasurements", String.valueOf(default_timeBetweenNoiseLevelMeasurements));
|
||||
|
||||
if(!prefs.contains("lengthOfNoiseLevelMeasurements") | force)
|
||||
if(!prefs.contains("lengthOfNoiseLevelMeasurements") || force)
|
||||
editor.putString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements));
|
||||
|
||||
if(!prefs.contains("referenceValueForNoiseLevelMeasurements") | force)
|
||||
if(!prefs.contains("referenceValueForNoiseLevelMeasurements") || force)
|
||||
editor.putString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements));
|
||||
|
||||
if(!prefs.contains("logLevel") | force)
|
||||
if(!prefs.contains("logLevel") || force)
|
||||
editor.putString("logLevel", String.valueOf(default_logLevel));
|
||||
|
||||
if(!prefs.contains("logFileMaxSize") | force)
|
||||
if(!prefs.contains("logFileMaxSize") || force)
|
||||
editor.putString("logFileMaxSize", String.valueOf(default_logFileMaxSize));
|
||||
|
||||
if(!prefs.contains("httpAcceptAllCertificates") | force)
|
||||
if(!prefs.contains("httpAcceptAllCertificates") || force)
|
||||
editor.putBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates);
|
||||
|
||||
if(!prefs.contains("httpAttempts") | force)
|
||||
if(!prefs.contains("httpAttempts") || force)
|
||||
editor.putString("httpAttempts", String.valueOf(default_httpAttempts));
|
||||
|
||||
if(!prefs.contains("httpAttemptsTimeout") | force)
|
||||
if(!prefs.contains("httpAttemptsTimeout") || force)
|
||||
editor.putString("httpAttemptsTimeout", String.valueOf(default_httpAttemptsTimeout));
|
||||
|
||||
if(!prefs.contains("httpAttemptGap") | force)
|
||||
if(!prefs.contains("httpAttemptGap") || force)
|
||||
editor.putString("httpAttemptGap", String.valueOf(default_httpAttemptGap));
|
||||
|
||||
if(!prefs.contains("lastActivePoi") | force)
|
||||
if(!prefs.contains("lastActivePoi") || force)
|
||||
editor.putString("lastActivePoi", "null");
|
||||
|
||||
if(!prefs.contains("rememberLastActivePoi") | force)
|
||||
if(!prefs.contains("rememberLastActivePoi") || force)
|
||||
editor.putBoolean("rememberLastActivePoi", default_rememberLastActivePoi);
|
||||
|
||||
if(!prefs.contains("locationRingBufferSize") | force)
|
||||
if(!prefs.contains("locationRingBufferSize") || force)
|
||||
editor.putString("locationRingBufferSize", String.valueOf(default_locationRingBufferSize));
|
||||
|
||||
if(!prefs.contains("timeBetweenProcessMonitorings") | force)
|
||||
if(!prefs.contains("timeBetweenProcessMonitorings") || force)
|
||||
editor.putString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings));
|
||||
|
||||
if(!prefs.contains("activityDetectionFrequency") | force)
|
||||
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));
|
||||
|
||||
if(!prefs.contains("activityDetectionRequiredProbability") | force)
|
||||
if(!prefs.contains("activityDetectionRequiredProbability") || force)
|
||||
editor.putString("activityDetectionRequiredProbability", String.valueOf(default_activityDetectionRequiredProbability));
|
||||
|
||||
if(!prefs.contains("privacyLocationing") | force)
|
||||
if(!prefs.contains("privacyLocationing") || force)
|
||||
editor.putBoolean("privacyLocationing", default_privacyLocationing);
|
||||
|
||||
if(!prefs.contains("startScreen") | force)
|
||||
if(!prefs.contains("startScreen") || force)
|
||||
editor.putString("startScreen", String.valueOf(default_startScreen));
|
||||
|
||||
if(!prefs.contains("tabsPlacement") | force)
|
||||
if(!prefs.contains("tabsPlacement") || force)
|
||||
editor.putString("tabsPlacement", String.valueOf(default_tabsPlacement));
|
||||
|
||||
if(!prefs.contains("executeRulesAndProfilesWithSingleClick") | force)
|
||||
if(!prefs.contains("executeRulesAndProfilesWithSingleClick") || force)
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
|
||||
if(!prefs.contains("automaticUpdateCheck") | force)
|
||||
if(!prefs.contains("automaticUpdateCheck") || force)
|
||||
editor.putBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
|
||||
if(!prefs.contains("displayNewsOnMainScreen") | force)
|
||||
if(!prefs.contains("displayNewsOnMainScreen") || force)
|
||||
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
|
||||
if(!prefs.contains("lockSoundChanges") | force)
|
||||
if(!prefs.contains("musicCheckFrequency") || force)
|
||||
editor.putLong("musicCheckFrequency", default_musicCheckFrequency);
|
||||
|
||||
if(!prefs.contains("lockSoundChanges") || force)
|
||||
editor.putBoolean("lockSoundChanges", default_lockSoundChanges);
|
||||
|
||||
if(!prefs.contains("noticeAndroid9MicrophoneShown") | force)
|
||||
if(!prefs.contains("noticeAndroid9MicrophoneShown") || force)
|
||||
editor.putBoolean("noticeAndroid9MicrophoneShown", false);
|
||||
|
||||
if(!prefs.contains("lastNewsPolltime") | force)
|
||||
if(!prefs.contains("lastNewsPolltime") || force)
|
||||
editor.putLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
|
||||
if(!prefs.contains("lastUpdateCheck") | force)
|
||||
if(!prefs.contains("lastUpdateCheck") || force)
|
||||
editor.putLong("lastUpdateCheck", default_lastUpdateCheck);
|
||||
|
||||
if(!prefs.contains("whatHasBeenDone") | force)
|
||||
if(!prefs.contains("whatHasBeenDone") || force)
|
||||
editor.putString("whatHasBeenDone", "");
|
||||
|
||||
editor.commit();
|
||||
@ -526,6 +546,7 @@ 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);
|
||||
@ -535,6 +556,10 @@ public class Settings implements SharedPreferences
|
||||
editor.putBoolean("automaticUpdateCheck", automaticUpdateCheck);
|
||||
editor.putBoolean("displayNewsOnMainScreen", displayNewsOnMainScreen);
|
||||
|
||||
if(Settings.musicCheckFrequency == 0)
|
||||
Settings.musicCheckFrequency = Settings.default_musicCheckFrequency;
|
||||
editor.putString("musicCheckFrequency", String.valueOf(musicCheckFrequency));
|
||||
|
||||
editor.putBoolean("lockSoundChanges", lockSoundChanges);
|
||||
editor.putBoolean("noticeAndroid9MicrophoneShown", noticeAndroid9MicrophoneShown);
|
||||
editor.putBoolean("noticeAndroid10WifiShown", noticeAndroid10WifiShown);
|
||||
@ -581,5 +606,4 @@ public class Settings implements SharedPreferences
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -6,70 +6,113 @@ import java.util.ArrayList;
|
||||
public class TimeFrame
|
||||
{
|
||||
// Defines a timeframe
|
||||
private Time triggerTimeStart;
|
||||
private Time triggerTimeStop;
|
||||
protected TimeObject triggerTimeStart;
|
||||
protected TimeObject 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()
|
||||
public TimeObject getTriggerTimeStart()
|
||||
{
|
||||
return triggerTimeStart;
|
||||
}
|
||||
public void setTriggerTimeStart(TimeObject triggerTimeStart)
|
||||
{
|
||||
this.triggerTimeStart = triggerTimeStart;
|
||||
}
|
||||
|
||||
public TimeObject getTriggerTimeStop()
|
||||
{
|
||||
return triggerTimeStop;
|
||||
}
|
||||
public void setTriggerTimeStop(TimeObject triggerTimeStop)
|
||||
{
|
||||
this.triggerTimeStop = triggerTimeStop;
|
||||
}
|
||||
|
||||
public long getRepetition()
|
||||
{
|
||||
return repetition;
|
||||
}
|
||||
|
||||
public void setRepetition(long repetition)
|
||||
{
|
||||
this.repetition = repetition;
|
||||
}
|
||||
|
||||
public TimeFrame (TimeObject timeStart, TimeObject 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(TimeObject.valueOf(dateArray[0]));
|
||||
this.setTriggerTimeStop(TimeObject.valueOf(dateArray[1]));
|
||||
this.setDayListFromString(dateArray[2]);
|
||||
if(dateArray.length > 3) // may not exist in old config files
|
||||
this.setRepetition(Long.parseLong(dateArray[3]));
|
||||
}
|
||||
|
||||
public String toTriggerParameter2String()
|
||||
{
|
||||
StringBuilder response = new StringBuilder();
|
||||
response.append(this.getTriggerTimeStart().getHours() + ":" + this.getTriggerTimeStart().getMinutes() + ":0");
|
||||
response.append(separator);
|
||||
response.append(this.getTriggerTimeStop().getHours() + ":" + this.getTriggerTimeStop().getMinutes() + ":0");
|
||||
response.append(separator);
|
||||
|
||||
StringBuilder days = new StringBuilder();
|
||||
|
||||
for(int day : dayList)
|
||||
days.append(String.valueOf(day));
|
||||
|
||||
response.append(days.toString());
|
||||
|
||||
if(this.repetition > 0)
|
||||
{
|
||||
return triggerTimeStart;
|
||||
response.append(separator + this.getRepetition());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String returnString = this.getTriggerTimeStart().toString() + separator + this.getTriggerTimeStop().toString() + separator;
|
||||
|
||||
for(Integer oneDay : this.getDayList())
|
||||
returnString += String.valueOf(oneDay);
|
||||
|
||||
returnString += separator + String.valueOf(repetition);
|
||||
|
||||
return returnString;
|
||||
}
|
||||
}
|
68
app/src/main/java/com/jens/automation2/TimeObject.java
Normal file
68
app/src/main/java/com/jens/automation2/TimeObject.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import java.sql.Time;
|
||||
|
||||
public class TimeObject
|
||||
{
|
||||
int hours, minutes, seconds;
|
||||
|
||||
public TimeObject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int getHours()
|
||||
{
|
||||
return hours;
|
||||
}
|
||||
|
||||
public void setHours(int hours)
|
||||
{
|
||||
this.hours = hours;
|
||||
}
|
||||
|
||||
public int getMinutes()
|
||||
{
|
||||
return minutes;
|
||||
}
|
||||
|
||||
public void setMinutes(int minutes)
|
||||
{
|
||||
this.minutes = minutes;
|
||||
}
|
||||
|
||||
public int getSeconds()
|
||||
{
|
||||
return seconds;
|
||||
}
|
||||
|
||||
public void setSeconds(int seconds)
|
||||
{
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
public TimeObject(int hours, int minutes, int seconds)
|
||||
{
|
||||
this.hours = hours;
|
||||
this.minutes = minutes;
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
public static TimeObject valueOf(String input)
|
||||
{
|
||||
TimeObject ro = null;
|
||||
|
||||
if(input.contains(":"))
|
||||
{
|
||||
String[] parts = input.split(":");
|
||||
if(parts.length == 2)
|
||||
ro = new TimeObject(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 0);
|
||||
else if(parts.length == 3)
|
||||
ro = new TimeObject(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
|
||||
else
|
||||
Miscellaneous.logEvent("w", "TimeObject", "Invalid length for time. Input: " + input, 4);
|
||||
}
|
||||
|
||||
return ro;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -254,8 +254,6 @@ public class XmlFileInterface
|
||||
else
|
||||
serializer.text("null");
|
||||
}
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.timeFrame)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTimeFrame().toString());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.speed)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getSpeed()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.noiseLevel)
|
||||
@ -263,11 +261,9 @@ public class XmlFileInterface
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.process_started_stopped)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getProcessName());
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.batteryLevel)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getBatteryLevel()));
|
||||
// else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.phoneCall)
|
||||
// serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneDirection()) + "," + String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneNumber()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.nfcTag)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getNfcTagId());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.activityDetection)
|
||||
@ -764,6 +760,8 @@ public class XmlFileInterface
|
||||
try
|
||||
{
|
||||
newRule.setTriggerSet(readTriggerCollection(parser));
|
||||
for(Trigger t : newRule.getTriggerSet())
|
||||
t.setParentRule(newRule);
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
@ -779,6 +777,8 @@ public class XmlFileInterface
|
||||
try
|
||||
{
|
||||
newRule.setActionSet(readActionCollection(parser));
|
||||
for(Action a : newRule.getActionSet())
|
||||
a.setParentRule(newRule);
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
@ -815,7 +815,15 @@ public class XmlFileInterface
|
||||
// Starts by looking for the entry tag
|
||||
if (name.equals("Trigger"))
|
||||
{
|
||||
triggerCollection.add(readTrigger(parser));
|
||||
try
|
||||
{
|
||||
triggerCollection.add(readTrigger(parser));
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown trigger found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
|
||||
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -826,10 +834,8 @@ public class XmlFileInterface
|
||||
return (triggerCollection);
|
||||
}
|
||||
|
||||
|
||||
private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException
|
||||
{
|
||||
|
||||
/* FILE EXAMPE:
|
||||
* *****************
|
||||
* <Automation>
|
||||
@ -878,7 +884,7 @@ public class XmlFileInterface
|
||||
{
|
||||
String triggerEventString = readTag(parser, "TriggerEvent");
|
||||
|
||||
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
|
||||
if(triggerEventString.equals("process_started_stopped") || triggerEventString.equals("process_running"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
|
||||
else
|
||||
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
|
||||
@ -928,13 +934,20 @@ public class XmlFileInterface
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
{
|
||||
// newTrigger.setWifiName(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped)
|
||||
{
|
||||
newTrigger.setProcessName(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
|
||||
if(triggerParameter2.contains(triggerParameter2Split))
|
||||
{
|
||||
String[] parts = triggerParameter2.split(triggerParameter2Split);
|
||||
newTrigger.setProcessName(parts[1]);
|
||||
}
|
||||
else
|
||||
newTrigger.setProcessName(triggerParameter2);
|
||||
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.phoneCall)
|
||||
{
|
||||
@ -1051,7 +1064,15 @@ public class XmlFileInterface
|
||||
// Starts by looking for the entry tag
|
||||
if (name.equals("Action"))
|
||||
{
|
||||
actionCollection.add(readAction(parser));
|
||||
try
|
||||
{
|
||||
actionCollection.add(readAction(parser));
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown action found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
|
||||
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1060,7 +1081,6 @@ public class XmlFileInterface
|
||||
}
|
||||
return (actionCollection);
|
||||
}
|
||||
|
||||
|
||||
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
|
||||
{
|
||||
@ -1135,7 +1155,19 @@ public class XmlFileInterface
|
||||
newAction.setAction(Action_Enum.enableScreenRotation);
|
||||
else if(actionNameString.equals("disableScreenRotation"))
|
||||
newAction.setAction(Action_Enum.disableScreenRotation);
|
||||
// *** deprecated
|
||||
else if(actionNameString.equals("disableScreenRotation"))
|
||||
newAction.setAction(Action_Enum.disableScreenRotation);
|
||||
else if(actionNameString.equals("playMusic"))
|
||||
{
|
||||
newAction.setAction(Action_Enum.controlMediaPlayback);
|
||||
newAction.setParameter2("1");
|
||||
}
|
||||
else if(actionNameString.equals("wakeupDevice"))
|
||||
{
|
||||
newAction.setAction(Action_Enum.turnScreenOnOrOff);
|
||||
newAction.setParameter1(true);
|
||||
}
|
||||
// *** :deprecated
|
||||
|
||||
else
|
||||
newAction.setAction(Action_Enum.valueOf(actionNameString));
|
||||
@ -1203,6 +1235,18 @@ public class XmlFileInterface
|
||||
newAction.setParameter1(false);
|
||||
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
newAction.setParameter1(false);
|
||||
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.turnScreenOnOrOff) && newAction.getParameter1())
|
||||
{
|
||||
/*
|
||||
If param1 == true we will keep it because this action used to be of type wakeUpDevice.
|
||||
*/
|
||||
}
|
||||
else
|
||||
// exclusion for deprecated types
|
||||
newAction.setParameter1(Boolean.parseBoolean(readTag(parser, "ActionParameter1")));
|
||||
@ -1224,7 +1268,6 @@ public class XmlFileInterface
|
||||
{
|
||||
newAction.setParameter2(tag);
|
||||
}
|
||||
|
||||
/*
|
||||
androidx.security.crypto.MasterKey.Builder
|
||||
|
||||
@ -1238,14 +1281,14 @@ public class XmlFileInterface
|
||||
{
|
||||
String newTag;
|
||||
|
||||
if(tag.contains(Action.intentPairSeperator)) // already has new format
|
||||
if(tag.contains(Action.intentPairSeparator)) // already has new format
|
||||
newTag = tag;
|
||||
else
|
||||
newTag = tag.replace("/", Action.intentPairSeperator);
|
||||
newTag = tag.replace("/", Action.intentPairSeparator);
|
||||
|
||||
String[] newTagPieces = newTag.split(";");
|
||||
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeperator)))
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeparator)))
|
||||
{
|
||||
newTag = Actions.dummyPackageString + ";" + newTag;
|
||||
newTagPieces = newTag.split(";");
|
||||
@ -1255,7 +1298,7 @@ public class XmlFileInterface
|
||||
newTag += ";" + ActivityManageActionStartActivity.startByActivityString;
|
||||
else if(newTagPieces.length >= 3)
|
||||
{
|
||||
if(newTagPieces[2].contains(Action.intentPairSeperator))
|
||||
if(newTagPieces[2].contains(Action.intentPairSeparator))
|
||||
newTag = newTagPieces[0] + ";" + newTagPieces[1] + ";" + ActivityManageActionStartActivity.startByActivityString + ";" + newTagPieces[2];
|
||||
}
|
||||
|
||||
@ -1283,9 +1326,6 @@ public class XmlFileInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "New Rule from file", newPoi.name + "/" + String.valueOf(newPoi.radius) + "/" + String.valueOf(newPoi.location.getLatitude()) + "/" + String.valueOf(newPoi.location.getLongitude()) + "/" + String.valueOf(newPoi.changeWifiState) + "/" + String.valueOf(newPoi.desiredWifiState) + "/" + String.valueOf(newPoi.changeCameraState) + "/" + String.valueOf(newPoi.desiredCameraState) + "/" + String.valueOf(newPoi.changeSoundSetting) + "/" + String.valueOf(newPoi.desiredSoundSetting));
|
||||
|
||||
return newAction;
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
// Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
|
||||
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4);
|
||||
|
@ -121,9 +121,9 @@ public class LocationProvider
|
||||
if (
|
||||
locationList.size() >= 1
|
||||
&&
|
||||
locationList.get(locationList.size() - 1).getTime() == newLocation.getTime()
|
||||
locationList.get(locationList.size() - 1).getTime() == newLocation.getTime()
|
||||
&&
|
||||
locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider())
|
||||
locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider())
|
||||
)
|
||||
{
|
||||
// This is a duplicate update, do not store it
|
||||
@ -162,7 +162,7 @@ public class LocationProvider
|
||||
(
|
||||
(locationList.get(i).getProvider().equals(LocationManager.GPS_PROVIDER) && locationList.get(i).getAccuracy() > Settings.satisfactoryAccuracyGps)
|
||||
||
|
||||
(locationList.get(i).getProvider().equals(LocationManager.NETWORK_PROVIDER) && locationList.get(i).getAccuracy() > Settings.satisfactoryAccuracyNetwork)
|
||||
(locationList.get(i).getProvider().equals(LocationManager.NETWORK_PROVIDER) && locationList.get(i).getAccuracy() > Settings.satisfactoryAccuracyNetwork)
|
||||
)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Speed", "Not using 2 most recent locations for speed calculation because at least one does not have a satisfactory accuracy: " + locationList.get(i).toString(), 4);
|
||||
@ -189,7 +189,7 @@ public class LocationProvider
|
||||
/*
|
||||
Due to strange factors the time difference might be 0 resulting in mathematical error.
|
||||
*/
|
||||
if (Double.isInfinite(currentSpeed) | Double.isNaN(currentSpeed))
|
||||
if (Double.isInfinite(currentSpeed) || Double.isNaN(currentSpeed))
|
||||
Miscellaneous.logEvent("i", "Speed", "Error while calculating speed.", 4);
|
||||
else
|
||||
{
|
||||
@ -198,10 +198,10 @@ public class LocationProvider
|
||||
setSpeed(currentSpeed);
|
||||
|
||||
// execute matching rules containing speed
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesBySpeed();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.speed);
|
||||
for (Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if (oneRule.applies(this.getParentService()))
|
||||
if(oneRule.getsGreenLight(this.getParentService()))
|
||||
oneRule.activate(getParentService(), false);
|
||||
}
|
||||
}
|
||||
@ -232,12 +232,6 @@ public class LocationProvider
|
||||
|
||||
public void startLocationService()
|
||||
{
|
||||
// if(Settings.useAccelerometerForPositioning && !Miscellaneous.isAndroidEmulator())
|
||||
// {
|
||||
// accelerometerHandler = new AccelerometerHandler();
|
||||
// mySensorActivity = new SensorActivity(this);
|
||||
// }
|
||||
|
||||
// startPhoneStateListener
|
||||
PhoneStatusListener.startPhoneStatusListener(parentService); // also used to mute anouncements during calls
|
||||
|
||||
@ -246,10 +240,8 @@ public class LocationProvider
|
||||
|
||||
if(Settings.positioningEngine == 0)
|
||||
{
|
||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger_Enum.speed))
|
||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) || Rule.isAnyRuleUsing(Trigger_Enum.speed))
|
||||
{
|
||||
// TelephonyManager telephonyManager = (TelephonyManager) AutomationService.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
||||
// startCellLocationChangedReceiver
|
||||
if (CellLocationChangedReceiver.isCellLocationChangedReceiverPossible())
|
||||
{
|
||||
@ -432,7 +424,7 @@ public class LocationProvider
|
||||
}
|
||||
|
||||
// *********** RULE CHANGES ***********
|
||||
if(!CellLocationChangedReceiver.isCellLocationListenerActive() && (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger_Enum.speed)))
|
||||
if(!CellLocationChangedReceiver.isCellLocationListenerActive() && (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) || Rule.isAnyRuleUsing(Trigger_Enum.speed)))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting NoiseListener CellLocationChangedReceiver because used in a new/changed rule.", 4);
|
||||
if(CellLocationChangedReceiver.haveAllPermission())
|
||||
@ -514,7 +506,6 @@ public class LocationProvider
|
||||
Message msg = new Message();
|
||||
msg.what = 1;
|
||||
speedHandler.sendMessageAtTime(msg, timeOfForcedLocationCheck.getTimeInMillis());
|
||||
// speedHandler.sendMessageDelayed(msg, delayTime);
|
||||
speedTimerActive = true;
|
||||
}
|
||||
else
|
||||
@ -531,7 +522,7 @@ public class LocationProvider
|
||||
if(msg.what == 1)
|
||||
{
|
||||
// time is up, no cell location updates since x minutes, start accelerometer
|
||||
String text = "Timer triggered. Based on the last location and speed we may be at a POI. Forcing location update in case CellLocationChangedReceiver didn\'t fire.";
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Timer triggered. Based on the last location and speed we may be at a POI. Forcing location update in case CellLocationChangedReceiver didn\'t fire.", 5);
|
||||
|
||||
Location currentLocation = CellLocationChangedReceiver.getInstance().getLocation("coarse");
|
||||
AutomationService.getInstance().getLocationProvider().setCurrentLocation(currentLocation, false);
|
||||
|
@ -16,6 +16,7 @@ import com.jens.automation2.PointOfInterest;
|
||||
import com.jens.automation2.R;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Settings;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -39,8 +40,9 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
|
||||
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
|
||||
|
||||
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
|
||||
|
||||
if(newWifiSsid.length() > 0)
|
||||
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
|
||||
}
|
||||
|
||||
public static boolean isWifiListenerActive()
|
||||
@ -144,10 +146,10 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
|
||||
public static void findRules(AutomationService automationServiceInstance)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.wifiConnection);
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(automationServiceInstance))
|
||||
if(oneRule.getsGreenLight(automationServiceInstance))
|
||||
oneRule.activate(automationServiceInstance, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,301 +0,0 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class AlarmListener extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static AutomationService automationServiceRef;
|
||||
private static AlarmManager centralAlarmManagerInstance;
|
||||
// private static Intent alarmIntent;
|
||||
// private static PendingIntent alarmPendingIntent;
|
||||
private static boolean alarmListenerActive=false;
|
||||
private static ArrayList<Long> alarmCandidates = new ArrayList<Long>();
|
||||
|
||||
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
|
||||
|
||||
public static void startAlarmListener(final AutomationService automationServiceRef)
|
||||
{
|
||||
AlarmListener.startAlarmListenerInternal(automationServiceRef);
|
||||
}
|
||||
public static void stopAlarmListener(Context context)
|
||||
{
|
||||
AlarmListener.stopAlarmListenerInternal();
|
||||
}
|
||||
|
||||
public static boolean isAlarmListenerActive()
|
||||
{
|
||||
return alarmListenerActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
|
||||
Date now = new Date();
|
||||
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
|
||||
Time passTime = Time.valueOf(timeString);
|
||||
|
||||
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
|
||||
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
|
||||
{
|
||||
if(allRulesWithNowInTimeFrame.get(i).applies(context))
|
||||
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
setAlarms();
|
||||
}
|
||||
|
||||
public static void setAlarms()
|
||||
{
|
||||
alarmCandidates.clear();
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
|
||||
|
||||
clearAlarms();
|
||||
|
||||
int i=0;
|
||||
|
||||
// // get a Calendar object with current time
|
||||
// Calendar cal = Calendar.getInstance();
|
||||
// // add 5 minutes to the calendar object
|
||||
// cal.add(Calendar.SECOND, 10);
|
||||
// String calSetWorkingCopyString2 = null;
|
||||
// SimpleDateFormat sdf2 = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
|
||||
// if (cal != null)
|
||||
// {
|
||||
// calSetWorkingCopyString2 = sdf2.format(cal.getTime());
|
||||
// }
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
|
||||
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
|
||||
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
|
||||
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
|
||||
// requestCodeList.add(0);
|
||||
|
||||
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
|
||||
allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
|
||||
for(Rule oneRule : allRulesWithTimeFrames)
|
||||
{
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == Trigger_Enum.timeFrame)
|
||||
{
|
||||
Calendar calNow, calSet;
|
||||
Time setTime;
|
||||
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
setTime = oneTrigger.getTimeFrame().getTriggerTimeStart();
|
||||
else
|
||||
setTime = oneTrigger.getTimeFrame().getTriggerTimeStop();
|
||||
|
||||
calNow = Calendar.getInstance();
|
||||
calSet = (Calendar) calNow.clone();
|
||||
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
|
||||
calSet.set(Calendar.MINUTE, setTime.getMinutes());
|
||||
calSet.set(Calendar.SECOND, 0);
|
||||
calSet.set(Calendar.MILLISECOND, 0);
|
||||
// At this point calSet would be a scheduling candidate. It's just the day the might not be right, yet.
|
||||
|
||||
long milliSecondsInAWeek = 1000 * 60 * 60 * 24 * 7;
|
||||
|
||||
for(int dayOfWeek : oneTrigger.getTimeFrame().getDayList())
|
||||
{
|
||||
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
|
||||
|
||||
// calSetWorkingCopy.set(Calendar.HOUR_OF_DAY, setTime.getHours());
|
||||
// calSetWorkingCopy.set(Calendar.MINUTE, setTime.getMinutes());
|
||||
// calSetWorkingCopy.set(Calendar.SECOND, 0);
|
||||
// calSetWorkingCopy.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
|
||||
// Log.i("AlarmManager", "Today: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + " / Sched.Day: " + String.valueOf(dayOfWeek) + " Difference to target day is: " + String.valueOf(diff));
|
||||
if(diff == 0) //if we're talking about the current day, is the time still in the future?
|
||||
{
|
||||
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
|
||||
{
|
||||
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours(" + String.valueOf(calSetWorkingCopy.getTime().getHours()) + ") < calNow.getTime().getHours(" + String.valueOf(calNow.getTime().getHours()) + ")");
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
|
||||
}
|
||||
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
|
||||
{
|
||||
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours()");
|
||||
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
|
||||
{
|
||||
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getMinutes() < calNow.getTime().getMinutes()");
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(diff < 0)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff+7) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
|
||||
}
|
||||
else
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
|
||||
}
|
||||
|
||||
i++;
|
||||
i=(int)System.currentTimeMillis();
|
||||
String calSetWorkingCopyString = sdf.format(calSetWorkingCopy.getTime()) + " RequestCode: " + String.valueOf(i);
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of rule: " + oneRule.getName() + " beginning at " + calSetWorkingCopyString);
|
||||
|
||||
alarmCandidates.add(calSetWorkingCopy.getTimeInMillis());
|
||||
// Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
|
||||
// alarmIntent.setData(Uri.parse("myalarms://" + i));
|
||||
// PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, i, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, calSetWorkingCopy.getTimeInMillis(), milliSecondsInAWeek, alarmPendingIntent);
|
||||
// requestCodeList.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // get a Calendar object with current time
|
||||
// Calendar cal = Calendar.getInstance();
|
||||
// cal.add(Calendar.SECOND, 10);
|
||||
// String calSetWorkingCopyString2 = sdf.format(cal.getTime());
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
|
||||
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
|
||||
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
|
||||
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
|
||||
// requestCodeList.add(0);
|
||||
|
||||
scheduleNextAlarm();
|
||||
}
|
||||
|
||||
private static void scheduleNextAlarm()
|
||||
{
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
Long scheduleCandidate = null;
|
||||
|
||||
if(alarmCandidates.size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
|
||||
return;
|
||||
}
|
||||
else if(alarmCandidates.size() == 1)
|
||||
{
|
||||
// only one alarm, schedule that
|
||||
scheduleCandidate = alarmCandidates.get(0);
|
||||
}
|
||||
else if(alarmCandidates.size() > 1)
|
||||
{
|
||||
scheduleCandidate = alarmCandidates.get(0);
|
||||
|
||||
for(long alarmCandidate : alarmCandidates)
|
||||
{
|
||||
if(Math.abs(currentTime - alarmCandidate) < Math.abs(currentTime - scheduleCandidate))
|
||||
scheduleCandidate = alarmCandidate;
|
||||
}
|
||||
}
|
||||
|
||||
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
|
||||
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate, alarmPendingIntent);
|
||||
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(scheduleCandidate);
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
|
||||
|
||||
}
|
||||
|
||||
public static void clearAlarms()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
|
||||
for(int requestCode : requestCodeList)
|
||||
{
|
||||
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
|
||||
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
|
||||
centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
}
|
||||
requestCodeList.clear();
|
||||
}
|
||||
|
||||
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
|
||||
{
|
||||
if(!alarmListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
|
||||
AlarmListener.automationServiceRef = givenAutomationServiceRef;
|
||||
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
|
||||
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
|
||||
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
|
||||
alarmListenerActive = true;
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
|
||||
AlarmListener.setAlarms();
|
||||
|
||||
// // get a Calendar object with current time
|
||||
// Calendar cal = Calendar.getInstance();
|
||||
// // add 5 minutes to the calendar object
|
||||
// cal.add(Calendar.SECOND, 10);
|
||||
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
|
||||
}
|
||||
|
||||
private static void stopAlarmListenerInternal()
|
||||
{
|
||||
if(alarmListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
|
||||
clearAlarms();
|
||||
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
alarmListenerActive = false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
|
||||
}
|
||||
public static void reloadAlarms()
|
||||
{
|
||||
AlarmListener.setAlarms();
|
||||
}
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
AlarmListener.startAlarmListener(automationService);
|
||||
}
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
AlarmListener.stopAlarmListener(automationService);
|
||||
}
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return isAlarmListenerActive();
|
||||
}
|
||||
@Override
|
||||
public Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger_Enum[] { Trigger_Enum.timeFrame };
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -18,7 +19,7 @@ import java.util.ArrayList;
|
||||
|
||||
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static int batteryLevel=-1; // initialize with a better value than this
|
||||
private static int batteryLevel = -1; // initialize with a better value than this
|
||||
public static AutomationService automationServiceRef = null;
|
||||
private static boolean usbHostConnected = false;
|
||||
|
||||
@ -26,6 +27,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
private static IntentFilter batteryIntentFilter = null;
|
||||
private static Intent batteryStatus = null;
|
||||
private static BroadcastReceiver batteryInfoReceiverInstance = null;
|
||||
|
||||
public static void startBatteryReceiver(final AutomationService automationServiceRef)
|
||||
{
|
||||
if(!batteryReceiverActive)
|
||||
@ -78,11 +80,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
private static int deviceIsCharging = 0; //0=unknown, 1=no, 2=yes
|
||||
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
|
||||
|
||||
public static int getDeviceIsCharging()
|
||||
public static int getCurrentChargingState()
|
||||
{
|
||||
return deviceIsCharging;
|
||||
return currentChargingState;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,79 +99,48 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
|
||||
if(intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
|
||||
{
|
||||
Log.i("Battery", "Low battery event");
|
||||
Miscellaneous.logEvent("i", "Battery", "Low battery event", 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Received battery event.");
|
||||
// if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))
|
||||
// {
|
||||
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
// int scale = -1;
|
||||
// int voltage = -1;
|
||||
// int temp = -1;
|
||||
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
|
||||
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
|
||||
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
|
||||
this.actionBatteryLevel(context);
|
||||
|
||||
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged));
|
||||
|
||||
switch(statusPlugged)
|
||||
{
|
||||
case BatteryManager.BATTERY_PLUGGED_AC:
|
||||
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.");
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_PLUGGED_USB:
|
||||
this.actionUsbConnected(context);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(status)
|
||||
{
|
||||
// case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
// break;
|
||||
case BatteryManager.BATTERY_STATUS_FULL:
|
||||
// Toast.makeText(context, "Regular charging full", Toast.LENGTH_LONG).show();
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.");
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
this.actionDischarging(context);
|
||||
break;
|
||||
}
|
||||
// }
|
||||
// else if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED))
|
||||
// {
|
||||
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.");
|
||||
// deviceIsCharging = 2;
|
||||
// //activate rule(s)
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
||||
// for(int i=0; i<ruleCandidates.size(); i++)
|
||||
// {
|
||||
// if(ruleCandidates.get(i).applies(context))
|
||||
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
|
||||
// }
|
||||
// }
|
||||
// else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED))
|
||||
// {
|
||||
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.");
|
||||
// deviceIsCharging = 1;
|
||||
// //activate rule(s)
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
|
||||
// for(int i=0; i<ruleCandidates.size(); i++)
|
||||
// {
|
||||
// if(ruleCandidates.get(i).applies(context))
|
||||
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
|
||||
// }
|
||||
// }
|
||||
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
// int scale = -1;
|
||||
// int voltage = -1;
|
||||
// int temp = -1;
|
||||
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
|
||||
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
|
||||
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
|
||||
this.actionBatteryLevel(context);
|
||||
|
||||
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged), 5);
|
||||
|
||||
switch(statusPlugged)
|
||||
{
|
||||
case BatteryManager.BATTERY_PLUGGED_AC:
|
||||
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_PLUGGED_USB:
|
||||
this.actionUsbConnected(context);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case BatteryManager.BATTERY_STATUS_FULL:
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
this.actionDischarging(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -180,7 +151,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
|
||||
public static int isDeviceCharging(Context context)
|
||||
{
|
||||
switch(deviceIsCharging)
|
||||
switch(currentChargingState)
|
||||
{
|
||||
case 0:
|
||||
Miscellaneous.logEvent("w", "ChargingInfo", "Status of device charging was requested. Information isn't available, yet.", 4);
|
||||
@ -188,25 +159,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
case 1:
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is discharging.", 3);
|
||||
break;
|
||||
case 2:
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3);
|
||||
break;
|
||||
}
|
||||
|
||||
return deviceIsCharging;
|
||||
return currentChargingState;
|
||||
}
|
||||
|
||||
private void actionCharging(Context context)
|
||||
{
|
||||
if(deviceIsCharging != 2) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
if(currentChargingState != BatteryManager.BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
|
||||
deviceIsCharging = 2;
|
||||
currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING;
|
||||
//activate rule(s)
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(context))
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
@ -216,25 +188,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery level has changed.", 3);
|
||||
//activate rule(s)
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBatteryLevel();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.batteryLevel);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(context))
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void actionDischarging(Context context)
|
||||
{
|
||||
if(deviceIsCharging != 1) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
if(currentChargingState != BatteryManager.BATTERY_STATUS_UNKNOWN) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3);
|
||||
deviceIsCharging = 1;
|
||||
currentChargingState = BatteryManager.BATTERY_STATUS_UNKNOWN;
|
||||
//activate rule(s)
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(context))
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
@ -253,11 +226,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
usbHostConnected = true;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
|
||||
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(context))
|
||||
if(oneRule.getsGreenLight(context))
|
||||
oneRule.activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
@ -274,20 +248,23 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
usbHostConnected = false;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
|
||||
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(context))
|
||||
if(oneRule.getsGreenLight(context))
|
||||
oneRule.activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
BatteryReceiver.startBatteryReceiver(automationService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
@ -296,8 +273,8 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext()) &&
|
||||
ActivityPermissions.havePermission("android.permission.BATTERY_STATS", Miscellaneous.getAnyContext());
|
||||
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
|
||||
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -311,4 +288,4 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
// actually monitores several
|
||||
return new Trigger_Enum[] { Trigger_Enum.batteryLevel, Trigger_Enum.charging, Trigger_Enum.usb_host_connection };
|
||||
}
|
||||
}
|
||||
}
|
@ -124,10 +124,10 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDeviceInRange), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.bluetoothConnection);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(AutomationService.getInstance()))
|
||||
if(ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,168 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class BroadcastListener extends android.content.BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
ArrayList<EventOccurrence> broadcastsCollection = new ArrayList<>();
|
||||
public static AutomationService automationServiceRef = null;
|
||||
private static boolean broadcastReceiverActive = false;
|
||||
private static BroadcastListener broadcastReceiverInstance = null;
|
||||
private static IntentFilter broadcastIntentFilter = null;
|
||||
private static Intent broadcastStatus = null;
|
||||
|
||||
public static BroadcastListener getInstance()
|
||||
{
|
||||
if(broadcastReceiverInstance == null)
|
||||
broadcastReceiverInstance = new BroadcastListener();
|
||||
|
||||
return broadcastReceiverInstance;
|
||||
}
|
||||
|
||||
public static class EventOccurrence
|
||||
{
|
||||
Calendar time;
|
||||
String event;
|
||||
|
||||
public EventOccurrence(Calendar time, String event)
|
||||
{
|
||||
this.time = time;
|
||||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
broadcastsCollection.add(new EventOccurrence(Calendar.getInstance(), intent.getAction()));
|
||||
|
||||
for(String key : intent.getExtras().keySet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
// Object ob = intent.getExtras().get(key);
|
||||
// Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<EventOccurrence> getBroadcastsCollection()
|
||||
{
|
||||
return broadcastsCollection;
|
||||
}
|
||||
|
||||
public boolean hasBroadcastOccurred(String event)
|
||||
{
|
||||
for(EventOccurrence eo : broadcastsCollection)
|
||||
{
|
||||
if(eo.event.equalsIgnoreCase(event))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasBroadcastOccurredSince(String event, Calendar timeLimit)
|
||||
{
|
||||
for(EventOccurrence eo : broadcastsCollection)
|
||||
{
|
||||
if(eo.event.equalsIgnoreCase(event) && (timeLimit == null || eo.time.getTimeInMillis() > timeLimit.getTimeInMillis()))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
if(!broadcastReceiverActive)
|
||||
{
|
||||
BroadcastListener.automationServiceRef = automationService;
|
||||
|
||||
if(broadcastReceiverInstance == null)
|
||||
broadcastReceiverInstance = new BroadcastListener();
|
||||
|
||||
if(broadcastIntentFilter == null)
|
||||
{
|
||||
broadcastIntentFilter = new IntentFilter();
|
||||
|
||||
List<String> actionList = new ArrayList<>();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
for(Trigger t : ruleCandidates.get(i).getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
|
||||
{
|
||||
ActivityPermissions.addToArrayListUnique(t.getTriggerParameter2(), actionList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String s : actionList)
|
||||
broadcastIntentFilter.addAction(s);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
broadcastStatus = automationServiceRef.registerReceiver(broadcastReceiverInstance, broadcastIntentFilter);
|
||||
broadcastReceiverActive = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
/*
|
||||
We might be confronted with permission issues here.
|
||||
*/
|
||||
Miscellaneous.logEvent("e", "BroadcastListener", Log.getStackTraceString(e), 1);
|
||||
broadcastReceiverActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
if(broadcastReceiverActive)
|
||||
{
|
||||
if(broadcastReceiverInstance != null)
|
||||
{
|
||||
automationServiceRef.unregisterReceiver(broadcastReceiverInstance);
|
||||
broadcastReceiverInstance = null;
|
||||
}
|
||||
|
||||
broadcastReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return broadcastReceiverActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.broadcastReceived };
|
||||
}
|
||||
}
|
@ -112,7 +112,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
@SuppressLint("NewApi")
|
||||
public static boolean isAirplaneMode(Context context)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
{
|
||||
int value = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0);
|
||||
return value != 0;
|
||||
@ -138,10 +138,11 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
boolean isAirplaneMode = isAirplaneMode(context);
|
||||
automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.airplaneMode);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(automationServiceRef))
|
||||
if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
@ -170,11 +171,12 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
roamingLastState = isRoaming;
|
||||
|
||||
automationServiceRef.getLocationProvider().handleRoaming(isRoaming);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.roaming);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(automationServiceRef))
|
||||
if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,407 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.TimeFrame;
|
||||
import com.jens.automation2.TimeObject;
|
||||
import com.jens.automation2.Trigger;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static AutomationService automationServiceRef;
|
||||
private static AlarmManager centralAlarmManagerInstance;
|
||||
private static boolean alarmListenerActive=false;
|
||||
private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>();
|
||||
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
|
||||
static PendingIntent alarmPendingIntent = null;
|
||||
|
||||
public static void startAlarmListener(final AutomationService automationServiceRef)
|
||||
{
|
||||
DateTimeListener.startAlarmListenerInternal(automationServiceRef);
|
||||
}
|
||||
public static void stopAlarmListener(Context context)
|
||||
{
|
||||
DateTimeListener.stopAlarmListenerInternal();
|
||||
}
|
||||
|
||||
public static boolean isAlarmListenerActive()
|
||||
{
|
||||
return alarmListenerActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
|
||||
|
||||
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
|
||||
for(int i=0; i < allRulesWithNowInTimeFrame.size(); i++)
|
||||
{
|
||||
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context))
|
||||
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
setAlarms();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public static void setAlarms()
|
||||
{
|
||||
alarmCandidates.clear();
|
||||
|
||||
Calendar calNow = Calendar.getInstance();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
|
||||
|
||||
clearAlarms();
|
||||
|
||||
int i=0;
|
||||
|
||||
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
|
||||
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
|
||||
// allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
|
||||
/*
|
||||
* Take care of regular executions, no repetitions in between.
|
||||
*/
|
||||
Miscellaneous.logEvent("i", "DateTimeListener", "Checking rules for single run alarm candidates.", 5);
|
||||
for(Rule oneRule : allRulesWithTimeFrames)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for single run alarm candidates.", 5);
|
||||
if(oneRule.isRuleActive())
|
||||
{
|
||||
try
|
||||
{
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for single run alarm candidates.", 5);
|
||||
|
||||
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
|
||||
{
|
||||
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
|
||||
|
||||
Calendar calSet;
|
||||
TimeObject setTime;
|
||||
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
setTime = tf.getTriggerTimeStart();
|
||||
else
|
||||
setTime = tf.getTriggerTimeStop();
|
||||
|
||||
calSet = (Calendar) calNow.clone();
|
||||
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
|
||||
calSet.set(Calendar.MINUTE, setTime.getMinutes());
|
||||
calSet.set(Calendar.SECOND, 0);
|
||||
calSet.set(Calendar.MILLISECOND, 0);
|
||||
// At this point calSet would be a scheduling candidate. It's just the day that might not be right, yet.
|
||||
|
||||
for(int dayOfWeek : tf.getDayList())
|
||||
{
|
||||
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
|
||||
|
||||
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
|
||||
if(diff == 0) // We're talking about the current weekday, but is the time still in the future?
|
||||
{
|
||||
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
|
||||
{
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
|
||||
}
|
||||
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
|
||||
{
|
||||
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
|
||||
{
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(diff < 0)
|
||||
{
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
|
||||
}
|
||||
else
|
||||
{
|
||||
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
|
||||
}
|
||||
|
||||
i++;
|
||||
i = (int)System.currentTimeMillis();
|
||||
sdf.format(calSetWorkingCopy.getTime());
|
||||
String.valueOf(i);
|
||||
|
||||
alarmCandidates.add(new ScheduleElement(calSetWorkingCopy, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only take care of repeated executions.
|
||||
*/
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking rules for repeated run alarm candidates.", 5);
|
||||
for(Rule oneRule : allRulesWithTimeFrames)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for repeated run alarm candidates.", 5);
|
||||
if(oneRule.isRuleActive())
|
||||
{
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.toString() , 5);
|
||||
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for repeated run alarm candidates.", 5);
|
||||
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule trigger " + oneTrigger.toString() , 5);
|
||||
|
||||
/*
|
||||
* Check for next repeated execution:
|
||||
*
|
||||
* Check if the rule currently applies....
|
||||
*
|
||||
* If no -> do nothing
|
||||
* If yes -> Take starting time and calculate the next repeated execution
|
||||
* 1. Take starting time
|
||||
* 2. Take current time
|
||||
* 3. Calculate difference, but include check to see if we're after that time,
|
||||
* be it start or end of the timeframe.
|
||||
* 4. Take div result +1 and add this on top of starting time
|
||||
* 5. Is this next possible execution still inside timeframe? Also consider timeframes spanning over midnight
|
||||
*/
|
||||
Calendar calSet;
|
||||
Time setTime;
|
||||
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
|
||||
|
||||
if(tf.getRepetition() > 0)
|
||||
{
|
||||
if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
|
||||
{
|
||||
Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow);
|
||||
|
||||
alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scheduleNextAlarm();
|
||||
}
|
||||
|
||||
private static void scheduleNextAlarm()
|
||||
{
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
ScheduleElement scheduleCandidate = null;
|
||||
|
||||
if(alarmCandidates.size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
|
||||
return;
|
||||
}
|
||||
else if(alarmCandidates.size() == 1)
|
||||
{
|
||||
// only one alarm, schedule that
|
||||
scheduleCandidate = alarmCandidates.get(0);
|
||||
}
|
||||
else if(alarmCandidates.size() > 1)
|
||||
{
|
||||
scheduleCandidate = alarmCandidates.get(0);
|
||||
|
||||
for(ScheduleElement alarmCandidate : alarmCandidates)
|
||||
{
|
||||
if(Math.abs(currentTime - alarmCandidate.time.getTimeInMillis()) < Math.abs(currentTime - scheduleCandidate.time.getTimeInMillis()))
|
||||
scheduleCandidate = alarmCandidate;
|
||||
}
|
||||
}
|
||||
|
||||
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis());
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
|
||||
}
|
||||
|
||||
public static void clearAlarms()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
|
||||
for(int requestCode : requestCodeList)
|
||||
{
|
||||
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
|
||||
if(alarmPendingIntent == null)
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
|
||||
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
|
||||
centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
}
|
||||
requestCodeList.clear();
|
||||
}
|
||||
|
||||
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
|
||||
{
|
||||
if(!alarmListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
|
||||
DateTimeListener.automationServiceRef = givenAutomationServiceRef;
|
||||
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
|
||||
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
|
||||
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
|
||||
alarmListenerActive = true;
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
|
||||
DateTimeListener.setAlarms();
|
||||
|
||||
// // get a Calendar object with current time
|
||||
// Calendar cal = Calendar.getInstance();
|
||||
// // add 5 minutes to the calendar object
|
||||
// cal.add(Calendar.SECOND, 10);
|
||||
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
|
||||
}
|
||||
|
||||
private static void stopAlarmListenerInternal()
|
||||
{
|
||||
if(alarmListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
|
||||
clearAlarms();
|
||||
centralAlarmManagerInstance.cancel(alarmPendingIntent);
|
||||
alarmListenerActive = false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
|
||||
}
|
||||
public static void reloadAlarms()
|
||||
{
|
||||
DateTimeListener.setAlarms();
|
||||
}
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
DateTimeListener.startAlarmListener(automationService);
|
||||
}
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
DateTimeListener.stopAlarmListener(automationService);
|
||||
}
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return isAlarmListenerActive();
|
||||
}
|
||||
@Override
|
||||
public Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger_Enum[] { Trigger_Enum.timeFrame };
|
||||
}
|
||||
|
||||
static class ScheduleElement implements Comparable<ScheduleElement>
|
||||
{
|
||||
Calendar time;
|
||||
String reason;
|
||||
|
||||
public ScheduleElement(Calendar timestamp, String reason)
|
||||
{
|
||||
super();
|
||||
this.time = timestamp;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ScheduleElement o)
|
||||
{
|
||||
if(time.getTimeInMillis() == o.time.getTimeInMillis())
|
||||
return 0;
|
||||
if(time.getTimeInMillis() < o.time.getTimeInMillis())
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Miscellaneous.formatDate(time.getTime()) + ", reason : " + reason;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
|
||||
{
|
||||
Calendar calSet;
|
||||
TimeObject setTime;
|
||||
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
|
||||
|
||||
if(tf.getRepetition() > 0)
|
||||
{
|
||||
if(trigger.getTriggerParameter())
|
||||
setTime = tf.getTriggerTimeStart();
|
||||
else
|
||||
setTime = tf.getTriggerTimeStop();
|
||||
|
||||
calSet = (Calendar) now.clone();
|
||||
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
|
||||
calSet.set(Calendar.MINUTE, setTime.getMinutes());
|
||||
calSet.set(Calendar.SECOND, 0);
|
||||
calSet.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
// If the starting time is a day ahead remove 1 day.
|
||||
if(calSet.getTimeInMillis() > now.getTimeInMillis())
|
||||
calSet.add(Calendar.DAY_OF_MONTH, -1);
|
||||
|
||||
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calSet.getTimeInMillis()) / 1000;
|
||||
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
|
||||
long nextScheduleTimestamp = (calSet.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition());
|
||||
Calendar calSchedule = Calendar.getInstance();
|
||||
calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000);
|
||||
|
||||
/*
|
||||
* Das war mal aktiviert. Allerdings: Die ganze Funktion liefert zurück, wenn die Regel NOCH nicht
|
||||
* zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten.
|
||||
*/
|
||||
|
||||
return calSchedule;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "DateTimeListener", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,255 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import static android.content.Context.SENSOR_SERVICE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
|
||||
import com.jens.automation2.ActivityManageTriggerDeviceOrientation;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Settings;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class DeviceOrientationListener implements SensorEventListener, AutomationListenerInterface
|
||||
{
|
||||
// https://developer.android.com/guide/topics/sensors/sensors_position#java
|
||||
|
||||
ActivityManageTriggerDeviceOrientation activityManageTriggerDeviceOrientationInstance = null;
|
||||
|
||||
//the Sensor Manager
|
||||
private SensorManager sManager;
|
||||
static DeviceOrientationListener instance = null;
|
||||
boolean isRunning = false;
|
||||
|
||||
Calendar now = null;
|
||||
static Calendar lastTimeSignalArrived = null;
|
||||
static int sensorValueCounter = 0;
|
||||
|
||||
// Gravity rotational data
|
||||
float gravity[];
|
||||
// Magnetic rotational data
|
||||
float magnetic[]; //for magnetic rotational data
|
||||
float accels[] = new float[3];
|
||||
float mags[] = new float[3];
|
||||
float[] values = new float[3];
|
||||
boolean hasMagneticSensor=false;
|
||||
|
||||
// azimuth, pitch and roll
|
||||
float azimuth;
|
||||
float pitch;
|
||||
float roll;
|
||||
|
||||
boolean applies = false;
|
||||
boolean flipped = false;
|
||||
boolean toggable = false;
|
||||
|
||||
|
||||
public static DeviceOrientationListener getInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
instance = new DeviceOrientationListener();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public float getAzimuth()
|
||||
{
|
||||
return azimuth;
|
||||
}
|
||||
|
||||
public float getPitch()
|
||||
{
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public float getRoll()
|
||||
{
|
||||
return roll;
|
||||
}
|
||||
|
||||
public void startSensorFromConfigActivity(Context context, ActivityManageTriggerDeviceOrientation activityManageTriggerDeviceOrientationInstance)
|
||||
{
|
||||
this.activityManageTriggerDeviceOrientationInstance = activityManageTriggerDeviceOrientationInstance;
|
||||
|
||||
if(!isRunning)
|
||||
{
|
||||
sManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
|
||||
|
||||
/*
|
||||
register the sensor listener to listen to the gyroscope sensor, use the
|
||||
callbacks defined in this class, and gather the sensor information as quick
|
||||
as possible
|
||||
*/
|
||||
|
||||
isRunning = true;
|
||||
|
||||
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
|
||||
hasMagneticSensor = sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopSensorFromConfigActivity()
|
||||
{
|
||||
activityManageTriggerDeviceOrientationInstance = null;
|
||||
|
||||
if(isRunning)
|
||||
{
|
||||
if(!Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
|
||||
{
|
||||
//unregister the sensor listener
|
||||
sManager.unregisterListener(this);
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor arg0, int arg1)
|
||||
{
|
||||
//Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event)
|
||||
{
|
||||
switch (event.sensor.getType())
|
||||
{
|
||||
case Sensor.TYPE_MAGNETIC_FIELD:
|
||||
mags = event.values.clone();
|
||||
break;
|
||||
case Sensor.TYPE_ACCELEROMETER:
|
||||
accels = event.values.clone();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasMagneticSensor)
|
||||
mags=new float[]{1f,1f,1f};
|
||||
|
||||
if (mags != null && accels != null)
|
||||
{
|
||||
gravity = new float[9];
|
||||
magnetic = new float[9];
|
||||
SensorManager.getRotationMatrix(gravity, magnetic, accels, mags);
|
||||
float[] outGravity = new float[9];
|
||||
SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X, SensorManager.AXIS_Z, outGravity);
|
||||
SensorManager.getOrientation(outGravity, values);
|
||||
|
||||
azimuth = values[0] * 57.2957795f;
|
||||
pitch = values[1] * 57.2957795f;
|
||||
roll = values[2] * 57.2957795f;
|
||||
mags = null;
|
||||
accels = null;
|
||||
}
|
||||
|
||||
//else it will output the Roll, Pitch and Yawn values
|
||||
if(activityManageTriggerDeviceOrientationInstance != null)
|
||||
activityManageTriggerDeviceOrientationInstance.updateFields(azimuth, pitch, roll);
|
||||
|
||||
/*
|
||||
For some reason the first 3 values after starting the listener
|
||||
are crap.
|
||||
*/
|
||||
if(sensorValueCounter > 3)
|
||||
{
|
||||
now = Calendar.getInstance();
|
||||
if (lastTimeSignalArrived == null || now.getTimeInMillis() >= lastTimeSignalArrived.getTimeInMillis() + Settings.acceptDeviceOrientationSignalEveryX_MilliSeconds)
|
||||
{
|
||||
lastTimeSignalArrived = now;
|
||||
|
||||
Miscellaneous.logEvent("i", "DeviceOrientation", "Got device orientation update: azimuth: " + String.valueOf(azimuth) + ", pitch: " + String.valueOf(pitch) + ", roll: " + String.valueOf(pitch), 4);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(Miscellaneous.getAnyContext()))
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.deviceOrientation);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).getsGreenLight(Miscellaneous.getAnyContext()))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
sensorValueCounter++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
if(!isRunning)
|
||||
{
|
||||
sManager = (SensorManager) Miscellaneous.getAnyContext().getSystemService(SENSOR_SERVICE);
|
||||
|
||||
/*
|
||||
register the sensor listener to listen to the gyroscope sensor, use the
|
||||
callbacks defined in this class, and gather the sensor information as quick
|
||||
as possible
|
||||
*/
|
||||
|
||||
isRunning = true;
|
||||
|
||||
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
|
||||
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
this.activityManageTriggerDeviceOrientationInstance = null;
|
||||
|
||||
if(isRunning)
|
||||
{
|
||||
//unregister the sensor listener
|
||||
sManager.unregisterListener(this);
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.deviceOrientation};
|
||||
}
|
||||
|
||||
/*
|
||||
Azimuth (degrees of rotation about the -z axis).
|
||||
This is the angle between the device's current compass direction and magnetic north. If the top edge of the
|
||||
device faces magnetic north, the azimuth is 0 degrees; if the top edge faces south, the azimuth is 180 degrees.
|
||||
Similarly, if the top edge faces east, the azimuth is 90 degrees, and if the top edge faces west, the azimuth is 270 degrees.
|
||||
|
||||
Pitch (degrees of rotation about the x axis).
|
||||
This is the angle between a plane parallel to the device's screen and a plane parallel to the ground. If you hold the device
|
||||
parallel to the ground with the bottom edge closest to you and tilt the top edge of the device toward the ground, the pitch
|
||||
angle becomes positive. Tilting in the opposite direction— moving the top edge of the device away from the ground—causes
|
||||
the pitch angle to become negative. The range of values is -180 degrees to 180 degrees.
|
||||
|
||||
Roll (degrees of rotation about the y axis).
|
||||
This is the angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground.
|
||||
If you hold the device parallel to the ground with the bottom edge closest to you and tilt the left edge of the
|
||||
device toward the ground, the roll angle becomes positive. Tilting in the opposite direction—moving the right
|
||||
edge of the device toward the ground— causes the roll angle to become negative. The range of values is -90 degrees
|
||||
to 90 degrees.
|
||||
|
||||
Computes the device's orientation based on the rotation matrix.
|
||||
When it returns, the array values are as follows:
|
||||
values[0]: Azimuth, angle of rotation about the -z axis. This value represents the angle between the device's y axis and the magnetic north pole. When facing north, this angle is 0, when facing south, this angle is π. Likewise, when facing east, this angle is π/2, and when facing west, this angle is -π/2. The range of values is -π to π.
|
||||
values[1]: Pitch, angle of rotation about the x axis. This value represents the angle between a plane parallel to the device's screen and a plane parallel to the ground. Assuming that the bottom edge of the device faces the user and that the screen is face-up, tilting the top edge of the device toward the ground creates a positive pitch angle. The range of values is -π to π.
|
||||
values[2]: Roll, angle of rotation about the y axis. This value represents the angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground. Assuming that the bottom edge of the device faces the user and that the screen is face-up, tilting the left edge of the device toward the ground creates a positive roll angle. The range of values is -π/2 to π/2.
|
||||
Applying these three rotations in the azimuth, pitch, roll order transforms an identity matrix to the rotation matrix passed into this method. Also, note that all three orientation angles are expressed in radians.
|
||||
*/
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -73,11 +74,12 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
headsetConnected = true;
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Headset " + name + " plugged in.", 4);
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.headsetPlugged);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(context))
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
@ -133,7 +135,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext());
|
||||
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,105 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Settings;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class MediaPlayerListener implements AutomationListenerInterface
|
||||
{
|
||||
static MediaPlayerListener instance = null;
|
||||
static AudioManager mAudioManager = null;
|
||||
static boolean listenerActive = false;
|
||||
Timer timer = null;
|
||||
TimerTask task = null;
|
||||
|
||||
public static boolean isAudioPlaying(Context context)
|
||||
{
|
||||
if(mAudioManager == null)
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
return mAudioManager.isMusicActive();
|
||||
}
|
||||
|
||||
public static MediaPlayerListener getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new MediaPlayerListener();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "MediaPlayerListener", "Starting listener.",5);
|
||||
|
||||
if(!listenerActive)
|
||||
{
|
||||
if(timer == null)
|
||||
{
|
||||
timer = new Timer();
|
||||
}
|
||||
else
|
||||
{
|
||||
task.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
|
||||
task = new TimerTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.musicPlaying);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
timer.scheduleAtFixedRate(task, 0, Settings.musicCheckFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "MediaPlayerListener", "Stopping listener.",5);
|
||||
|
||||
if(listenerActive)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return listenerActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.musicPlaying };
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.R;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -171,10 +172,10 @@ public class NfcReceiver
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidatesByNfc();
|
||||
ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidates(Trigger.Trigger_Enum.nfcTag);
|
||||
for(int i=0; i<allRulesWithNfcTags.size(); i++)
|
||||
{
|
||||
if(allRulesWithNfcTags.get(i).applies(asInstance))
|
||||
if(allRulesWithNfcTags.get(i).getsGreenLight(asInstance))
|
||||
allRulesWithNfcTags.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
@ -215,23 +216,26 @@ public class NfcReceiver
|
||||
}
|
||||
|
||||
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
|
||||
|
||||
NdefRecord[] records = ndefMessage.getRecords();
|
||||
for (NdefRecord ndefRecord : records)
|
||||
{
|
||||
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT))
|
||||
{
|
||||
try
|
||||
{
|
||||
return readText(ndefRecord);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "NFC", "Unsupported Encoding: " + Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(ndefMessage != null)
|
||||
{
|
||||
NdefRecord[] records = ndefMessage.getRecords();
|
||||
for (NdefRecord ndefRecord : records)
|
||||
{
|
||||
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT))
|
||||
{
|
||||
try
|
||||
{
|
||||
return readText(ndefRecord);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "NFC", "Unsupported Encoding: " + Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -30,10 +30,10 @@ public class NoiseListener implements AutomationListenerInterface
|
||||
noiseLevelDb = msg.getData().getLong("noiseLevelDb");
|
||||
|
||||
// execute matching rules containing noise
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByNoiseLevel();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.noiseLevel);
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(automationService))
|
||||
if(oneRule.getsGreenLight(automationService))
|
||||
oneRule.activate(automationService, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@ -19,9 +25,10 @@ import java.util.Calendar;
|
||||
|
||||
@SuppressLint("OverrideAbstract")
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
public class NotificationListener extends NotificationListenerService
|
||||
public class NotificationListener extends NotificationListenerService// implements AutomationListenerInterface
|
||||
{
|
||||
static Calendar lastResponseToNotification = null;
|
||||
static boolean listenerRunning = false;
|
||||
static NotificationListener instance;
|
||||
static SimpleNotification lastNotification = null;
|
||||
|
||||
@ -37,6 +44,8 @@ public class NotificationListener extends NotificationListenerService
|
||||
// a bitmap to be used instead of the small icon when showing the notification payload
|
||||
public static final String EXTRA_LARGE_ICON = "android.largeIcon";
|
||||
|
||||
protected static IntentFilter notificationReceiverIntentFilter = null;
|
||||
|
||||
public static SimpleNotification getLastNotification()
|
||||
{
|
||||
return lastNotification;
|
||||
@ -78,35 +87,113 @@ public class NotificationListener extends NotificationListenerService
|
||||
{
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
lastNotification = convertNotificationToSimpleNotification(created, sbn);
|
||||
|
||||
lastNotification = new SimpleNotification();
|
||||
lastNotification.publishTime = Miscellaneous.calendarFromLong(sbn.getPostTime());
|
||||
lastNotification.created = created;
|
||||
lastNotification.app = app;
|
||||
lastNotification.title = title;
|
||||
lastNotification.text = text;
|
||||
if(created)
|
||||
Miscellaneous.logEvent("i", "New notification", lastNotification.toString(), 5);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Notification removed", lastNotification.toString(), 5);
|
||||
|
||||
// if(lastResponseToNotification == null || lastResponseToNotification.getTimeInMillis() < lastNotification.publishTime.getTimeInMillis())
|
||||
// {
|
||||
// lastResponseToNotification = Calendar.getInstance();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).applies(NotificationListener.this))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("e", "NotificationCheck", "Ignoring notification as it is old.", 5);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).getsGreenLight(NotificationListener.this))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public static SimpleNotification convertNotificationToSimpleNotification(boolean created, StatusBarNotification input)
|
||||
{
|
||||
String app = input.getPackageName();
|
||||
String title = "";
|
||||
String text = "";
|
||||
|
||||
Bundle extras = input.getNotification().extras;
|
||||
|
||||
try
|
||||
{
|
||||
if (extras.containsKey(EXTRA_TITLE))
|
||||
title = extras.getString(EXTRA_TITLE).toString();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
// https://www.b4x.com/android/forum/threads/solved-reading-statusbarnotifications-extras.64416/
|
||||
// Some notifications have an empty title, like KDE connect
|
||||
if(extras.containsKey(EXTRA_TITLE) && extras.get(EXTRA_TITLE) != null)
|
||||
title = extras.get(EXTRA_TITLE).toString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (extras.containsKey(EXTRA_TEXT))
|
||||
text = extras.getString(EXTRA_TEXT).toString();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
// in stacked notifications the "surrounding" element has no text, only a title
|
||||
if (extras.containsKey(EXTRA_TEXT) && extras.get(EXTRA_TEXT) != null)
|
||||
text = extras.get(EXTRA_TEXT).toString();
|
||||
}
|
||||
|
||||
SimpleNotification returnNotification = new SimpleNotification();
|
||||
returnNotification.publishTime = Miscellaneous.calendarFromLong(input.getPostTime());
|
||||
returnNotification.created = created;
|
||||
returnNotification.app = app;
|
||||
returnNotification.title = title;
|
||||
returnNotification.text = text;
|
||||
|
||||
return returnNotification;
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new NotificationListener();
|
||||
|
||||
if(notificationReceiverIntentFilter == null)
|
||||
{
|
||||
notificationReceiverIntentFilter = new IntentFilter();
|
||||
notificationReceiverIntentFilter.addAction("android.service.notification.NotificationListenerService");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if(!listenerRunning)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationListener", "Starting NotificationListener", 4);
|
||||
listenerRunning = true;
|
||||
AutomationService.getInstance().registerReceiver(instance, notificationReceiverIntentFilter);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "BluetoothReceiver", "Error starting BluetoothReceiver: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[0];
|
||||
}*/
|
||||
|
||||
public static class SimpleNotification
|
||||
{
|
||||
boolean created;
|
||||
@ -162,6 +249,18 @@ public class NotificationListener extends NotificationListenerService
|
||||
{
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "SimpleNotification{" +
|
||||
"created=" + created +
|
||||
", publishTime=" + publishTime +
|
||||
", app='" + app + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", text='" + text + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,4 +274,13 @@ public class NotificationListener extends NotificationListenerService
|
||||
{
|
||||
super.onListenerDisconnected();
|
||||
}
|
||||
|
||||
public void dismissNotification(StatusBarNotification sbn)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||
cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
|
||||
else
|
||||
cancelNotification(sbn.getKey());
|
||||
|
||||
}
|
||||
}
|
@ -14,29 +14,18 @@ public class PackageReplacedReceiver extends BroadcastReceiver
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
// Toast.makeText(context, "package replaced", Toast.LENGTH_LONG).show();
|
||||
// int intentUid = intent.getExtras().getInt("android.intent.extra.UID"); // userid of the application that has just been updated
|
||||
// int myUid = android.os.Process.myUid(); // userid of this application
|
||||
//
|
||||
// boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
|
||||
// if(intentUid == myUid)
|
||||
// {
|
||||
Settings.readFromPersistentStorage(context);
|
||||
Settings.readFromPersistentStorage(context);
|
||||
|
||||
Miscellaneous.logEvent("i", context.getResources().getString(R.string.applicationHasBeenUpdated), context.getResources().getString(R.string.applicationHasBeenUpdated), 2);
|
||||
if(hasServiceBeenRunning() && Settings.startServiceAfterAppUpdate)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", context.getResources().getString(R.string.logStartingServiceAfterAppUpdate), 1);
|
||||
AutomationService.startAutomationService(context, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", context.getResources().getString(R.string.logNotStartingServiceAfterAppUpdate), 2);
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", "Service", "Some other app has been updated.", 5);
|
||||
Miscellaneous.logEvent("i", context.getResources().getString(R.string.applicationHasBeenUpdated), context.getResources().getString(R.string.applicationHasBeenUpdated), 2);
|
||||
if(hasServiceBeenRunning() && Settings.startServiceAfterAppUpdate)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", context.getResources().getString(R.string.logStartingServiceAfterAppUpdate), 1);
|
||||
AutomationService.startAutomationService(context, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", context.getResources().getString(R.string.logNotStartingServiceAfterAppUpdate), 2);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasServiceBeenRunning()
|
||||
|
@ -109,12 +109,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).applies(asInstance))
|
||||
if(ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
@ -141,12 +141,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionIncoming);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if (asInstance != null)
|
||||
if (ruleCandidates.get(i).applies(asInstance))
|
||||
if (ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
@ -168,22 +168,18 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
*/
|
||||
setLastPhoneDirection(2);
|
||||
|
||||
// TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
|
||||
// int newState = tm.getCallState();
|
||||
// setCurrentState(newState);
|
||||
|
||||
setCurrentState(TelephonyManager.CALL_STATE_RINGING);
|
||||
|
||||
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
|
||||
setLastPhoneNumber(phoneNumber);
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).applies(asInstance))
|
||||
if(ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningAppProcessInfo;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
@ -8,6 +9,7 @@ import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import com.jens.automation2.Action;
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
@ -43,34 +45,27 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
@Override
|
||||
public void handleMessage(Message msg)
|
||||
{
|
||||
// try
|
||||
// {
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.processMonitoring), automationService.getResources().getString(R.string.messageReceivedStatingProcessMonitoringIsComplete), 5);
|
||||
// This will take care of results delivered by the actual monitoring instance
|
||||
|
||||
for(String entry : getRunningApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.runningApp), entry, 5);
|
||||
|
||||
// execute matching rules containing processes
|
||||
if(getRecentlyStartedApps().size()>0 | getRecentlyStoppedApps().size()>0)
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.processMonitoring), automationService.getResources().getString(R.string.messageReceivedStatingProcessMonitoringIsComplete), 5);
|
||||
// This will take care of results delivered by the actual monitoring instance
|
||||
|
||||
for(String entry : getRunningApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.runningApp), entry, 5);
|
||||
|
||||
// execute matching rules containing processes
|
||||
if(getRecentlyStartedApps().size()>0 | getRecentlyStoppedApps().size()>0)
|
||||
{
|
||||
for(String entry : getRecentlyStartedApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStarted), entry, 3);
|
||||
for(String entry : getRecentlyStoppedApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStopped), entry, 3);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.process_started_stopped);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
for(String entry : getRecentlyStartedApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStarted), entry, 3);
|
||||
for(String entry : getRecentlyStoppedApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStopped), entry, 3);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByProcess();
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(automationService))
|
||||
ruleCandidates.get(i).activate(automationService, false);
|
||||
}
|
||||
if(ruleCandidates.get(i).getsGreenLight(automationService))
|
||||
ruleCandidates.get(i).activate(automationService, false);
|
||||
}
|
||||
// }
|
||||
// catch(Exception e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("e", "Noise level", "Error in workHandler->handleMessage(): " + e.getMessage());
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -215,12 +210,12 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
workHandler.sendMessage(answer);
|
||||
|
||||
//activate rule(s)
|
||||
/*ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByProcess();
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.process_started_stopped);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).applies(automationService))
|
||||
ruleCandidates.get(i).activate(automationService);
|
||||
}*/
|
||||
if(ruleCandidates.get(i).getsGreenLight(automationService))
|
||||
ruleCandidates.get(i).activate(automationService, false);
|
||||
}
|
||||
|
||||
isMonitoringActive = false;
|
||||
|
||||
@ -238,6 +233,7 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
|
||||
final ActivityManager activityManager = (ActivityManager)automationService.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
final List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
|
||||
final List<RunningAppProcessInfo> apps = activityManager.getRunningAppProcesses();
|
||||
|
||||
ArrayList<String> runningAppsListReference;
|
||||
if(lastWritten == 1)
|
||||
@ -253,32 +249,23 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
|
||||
runningAppsListReference.clear();
|
||||
|
||||
for (int i = 0; i < services.size(); i++)
|
||||
/*for (int i = 0; i < services.size(); i++)
|
||||
{
|
||||
if(!runningAppsListReference.contains(services.get(i).baseActivity.getClassName()))
|
||||
{
|
||||
// you may broadcast a new application launch here.
|
||||
runningAppsListReference.add(services.get(i).baseActivity.getClassName());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
for (int i = 0; i < apps.size(); i++)
|
||||
{
|
||||
if(!runningAppsListReference.contains(apps.get(i).processName))
|
||||
{
|
||||
// you may broadcast a new application launch here.
|
||||
runningAppsListReference.add(apps.get(i).processName);
|
||||
}
|
||||
}
|
||||
|
||||
// for(String runningApp : runningAppsListReference)
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "Running app", runningApp, 5);
|
||||
// }
|
||||
|
||||
// List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
|
||||
// for(int i = 0; i < procInfos.size(); i++)
|
||||
// {
|
||||
// ArrayList<String> runningPkgs = new ArrayList<String>(Arrays.asList(procInfos.get(i).pkgList));
|
||||
//
|
||||
// Collection diff = subtractSets(runningPkgs, stalkList);
|
||||
//
|
||||
// if(diff != null)
|
||||
// {
|
||||
// stalkList.removeAll(diff);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Set marker to the one to be written next.
|
||||
if(lastWritten == 1)
|
||||
@ -358,7 +345,7 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkifThisIsActive(RunningAppProcessInfo target)
|
||||
private boolean checkIfThisIsActive(RunningAppProcessInfo target)
|
||||
{
|
||||
boolean result = false;
|
||||
RunningTaskInfo info;
|
||||
@ -404,7 +391,6 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
|
||||
Message message = new Message();
|
||||
message.arg1 = 1;
|
||||
// schedulingHandler.sendMessageDelayed(message, Settings.timeBetweenNoiseLevelMeasurements * 1000);
|
||||
schedulingHandler.sendMessageDelayed(message, 10000);
|
||||
}
|
||||
else
|
||||
@ -451,7 +437,7 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return ActivityPermissions.havePermission("android.permission.GET_TASKS", Miscellaneous.getAnyContext());
|
||||
return ActivityPermissions.havePermission(Manifest.permission.GET_TASKS, Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -465,6 +451,4 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
{
|
||||
return new Trigger_Enum[] { Trigger_Enum.process_started_stopped };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.Actions;
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ScreenStateReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
static int screenPowerState = -1; // initialize with a better value than this
|
||||
static int screenLockState = -1; // initialize with a better value than this
|
||||
public static AutomationService automationServiceRef = null;
|
||||
|
||||
private static boolean screenStateReceiverActive = false;
|
||||
private static IntentFilter screenStateIntentFilter = null;
|
||||
private static Intent screenStatusIntent = null;
|
||||
private static BroadcastReceiver screenStateReceiverInstance = null;
|
||||
|
||||
public final static String broadcastScreenLockedWithoutSecurity = "automation.system.screen_locked_without_security";
|
||||
public final static String broadcastScreenLockedWithSecurity = "automation.system.screen_locked_with_security";
|
||||
|
||||
public final static int SCREEN_STATE_OFF = 0;
|
||||
public final static int SCREEN_STATE_ON = 1;
|
||||
public final static int SCREEN_STATE_UNLOCKED = 2;
|
||||
public final static int SCREEN_STATE_LOCKED_WITHOUT_SECURITY = 3;
|
||||
public final static int SCREEN_STATE_LOCKED_WITH_SECURITY = 4;
|
||||
|
||||
public static BroadcastReceiver getScreenStateReceiverInstance()
|
||||
{
|
||||
if (screenStateReceiverInstance == null)
|
||||
screenStateReceiverInstance = new ScreenStateReceiver();
|
||||
|
||||
return screenStateReceiverInstance;
|
||||
}
|
||||
|
||||
public static void startScreenStateReceiver(final AutomationService automationServiceRef)
|
||||
{
|
||||
if (!screenStateReceiverActive)
|
||||
{
|
||||
ScreenStateReceiver.automationServiceRef = automationServiceRef;
|
||||
|
||||
if (screenStateReceiverInstance == null)
|
||||
screenStateReceiverInstance = new ScreenStateReceiver();
|
||||
|
||||
if (screenStateIntentFilter == null)
|
||||
{
|
||||
screenStateIntentFilter = new IntentFilter();
|
||||
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
screenStateIntentFilter.addAction(Intent.ACTION_USER_PRESENT); // also fired when device is unlocked
|
||||
screenStateIntentFilter.addAction(broadcastScreenLockedWithoutSecurity);
|
||||
screenStateIntentFilter.addAction(broadcastScreenLockedWithSecurity);
|
||||
// Intent.ACTION_USER_UNLOCKED
|
||||
}
|
||||
|
||||
screenStatusIntent = automationServiceRef.registerReceiver(screenStateReceiverInstance, screenStateIntentFilter);
|
||||
|
||||
screenStateReceiverActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopScreenStateReceiver()
|
||||
{
|
||||
if (screenStateReceiverActive)
|
||||
{
|
||||
if (screenStateReceiverInstance != null)
|
||||
{
|
||||
automationServiceRef.unregisterReceiver(screenStateReceiverInstance);
|
||||
screenStateReceiverInstance = null;
|
||||
}
|
||||
|
||||
screenStateReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isScreenStateReceiverActive()
|
||||
{
|
||||
return screenStateReceiverActive;
|
||||
}
|
||||
|
||||
public static int getScreenPowerState()
|
||||
{
|
||||
return screenPowerState;
|
||||
}
|
||||
|
||||
public static int getScreenLockState()
|
||||
{
|
||||
return screenLockState;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
if (intent == null)
|
||||
return;
|
||||
if (context == null)
|
||||
return;
|
||||
|
||||
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Received: " + intent.getAction(), 3);
|
||||
|
||||
try
|
||||
{
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
|
||||
{
|
||||
ScreenStateReceiver.screenPowerState = SCREEN_STATE_OFF;
|
||||
|
||||
KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
|
||||
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "Method 2: " + String.valueOf(pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked()), 4);
|
||||
// if (pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked())
|
||||
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "pm.isInteractive(): " + String.valueOf(pm.isInteractive()), 4);
|
||||
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "pm.isScreenOn(): " + String.valueOf(pm.isScreenOn()), 4);
|
||||
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isKeyguardLocked(): " + String.valueOf(keyguardManager.isKeyguardLocked()), 4);
|
||||
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isDeviceLocked(): " + String.valueOf(keyguardManager.isDeviceLocked()), 4);
|
||||
|
||||
if(keyguardManager.isKeyguardLocked() && !keyguardManager.isDeviceLocked())
|
||||
{
|
||||
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithoutSecurity);
|
||||
}
|
||||
else if(keyguardManager.isDeviceLocked())
|
||||
{
|
||||
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithSecurity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lock may be activated delayed, not at power button press
|
||||
ScreenLockMonitor mon = new ScreenLockMonitor();
|
||||
mon.startMonitor();
|
||||
}
|
||||
}
|
||||
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
|
||||
{
|
||||
ScreenStateReceiver.screenPowerState = SCREEN_STATE_ON;
|
||||
}
|
||||
else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT))
|
||||
{
|
||||
ScreenStateReceiver.screenLockState = SCREEN_STATE_UNLOCKED;
|
||||
}
|
||||
else if (intent.getAction().equals(broadcastScreenLockedWithoutSecurity))
|
||||
{
|
||||
ScreenStateReceiver.screenLockState = SCREEN_STATE_LOCKED_WITHOUT_SECURITY;
|
||||
}
|
||||
else if (intent.getAction().equals(broadcastScreenLockedWithSecurity))
|
||||
{
|
||||
ScreenStateReceiver.screenLockState = SCREEN_STATE_LOCKED_WITH_SECURITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Unknown state received: " + intent.getAction(), 3);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Error receiving screen state: " + e.getMessage(), 3);
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.screenState);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
ScreenStateReceiver.startScreenStateReceiver(automationService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
ScreenStateReceiver.stopScreenStateReceiver();
|
||||
}
|
||||
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
|
||||
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return ScreenStateReceiver.isScreenStateReceiverActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger_Enum[]{Trigger_Enum.screenState};
|
||||
}
|
||||
|
||||
class ScreenLockMonitor
|
||||
{
|
||||
long runs = 0;
|
||||
final long maxRuns = 20;
|
||||
final long interval = 1000;
|
||||
|
||||
Timer timer = new Timer();
|
||||
|
||||
TimerTask task = new TimerTask()
|
||||
{
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
KeyguardManager keyguardManager = (KeyguardManager) Miscellaneous.getAnyContext().getSystemService(Context.KEYGUARD_SERVICE);
|
||||
|
||||
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isKeyguardLocked(): " + String.valueOf(keyguardManager.isKeyguardLocked()), 4);
|
||||
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isDeviceLocked(): " + String.valueOf(keyguardManager.isDeviceLocked()), 4);
|
||||
|
||||
if(keyguardManager.isKeyguardLocked() && !keyguardManager.isDeviceLocked())
|
||||
{
|
||||
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithoutSecurity);
|
||||
timer.purge();
|
||||
timer.cancel();
|
||||
}
|
||||
else if(keyguardManager.isDeviceLocked())
|
||||
{
|
||||
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithSecurity);
|
||||
timer.purge();
|
||||
timer.cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (runs++ > maxRuns)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "ScreenStateReceiver->ScreenLockMonitor", "Lock never came.", 4);
|
||||
timer.purge();
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void startMonitor()
|
||||
{
|
||||
ContentResolver mResolver = Miscellaneous.getAnyContext().getContentResolver();
|
||||
long lockscreen_timeout = 0;
|
||||
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1)
|
||||
lockscreen_timeout = Settings.System.getInt(mResolver, "lock_screen_lock_after_timeout", 0);
|
||||
else
|
||||
lockscreen_timeout = Settings.Secure.getInt(mResolver, "lock_screen_lock_after_timeout", 0);
|
||||
|
||||
if(lockscreen_timeout > 0)
|
||||
timer.schedule(task, lockscreen_timeout);
|
||||
else
|
||||
timer.scheduleAtFixedRate(task, 0, interval);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ public class StartupIntentReceiver extends BroadcastReceiver
|
||||
{
|
||||
Settings.readFromPersistentStorage(context);
|
||||
|
||||
Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
|
||||
// Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
|
||||
|
||||
if(Settings.startServiceAtSystemBoot)
|
||||
{
|
||||
|
@ -14,14 +14,13 @@ import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
public class TimeZoneListener extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static TimeZoneListener timeZoneListenerInstance = null;
|
||||
protected static boolean timeZoneListenerActive = false;
|
||||
protected static boolean timezoneListenerActive = false;
|
||||
protected static AutomationService automationServiceRef = null;
|
||||
protected static IntentFilter timeZoneListenerIntentFilter = null;
|
||||
|
||||
protected static IntentFilter timezoneListenerIntentFilter = null;
|
||||
|
||||
public static boolean isTimeZoneListenerActive()
|
||||
public static boolean isTimezoneListenerActive()
|
||||
{
|
||||
return timeZoneListenerActive;
|
||||
return timezoneListenerActive;
|
||||
}
|
||||
|
||||
public static void startTimeZoneListener(AutomationService automationService)
|
||||
@ -33,19 +32,19 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
|
||||
|
||||
try
|
||||
{
|
||||
if(!timeZoneListenerActive && Rule.isAnyRuleUsing(Trigger_Enum.timeFrame))
|
||||
if(!timezoneListenerActive && Rule.isAnyRuleUsing(Trigger_Enum.timeFrame))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TimeZoneListener", "Starting TimeZoneListener", 4);
|
||||
timeZoneListenerActive = true;
|
||||
timezoneListenerActive = true;
|
||||
|
||||
if(timeZoneListenerIntentFilter == null)
|
||||
if(timezoneListenerIntentFilter == null)
|
||||
{
|
||||
timeZoneListenerIntentFilter = new IntentFilter();
|
||||
timeZoneListenerIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
timeZoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
timezoneListenerIntentFilter = new IntentFilter();
|
||||
timezoneListenerIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
timezoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
}
|
||||
|
||||
automationService.registerReceiver(timeZoneListenerInstance, timeZoneListenerIntentFilter);
|
||||
automationService.registerReceiver(timeZoneListenerInstance, timezoneListenerIntentFilter);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
@ -57,11 +56,11 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
|
||||
{
|
||||
try
|
||||
{
|
||||
if(timeZoneListenerActive)
|
||||
if(timezoneListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TimeZoneListener", "Stopping TimeZoneListener", 4);
|
||||
automationServiceRef.unregisterReceiver(timeZoneListenerInstance);
|
||||
timeZoneListenerActive = false;
|
||||
timezoneListenerActive = false;
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
@ -77,12 +76,12 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
|
||||
if(action.equals(Intent.ACTION_TIMEZONE_CHANGED))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3);
|
||||
AlarmListener.reloadAlarms();
|
||||
DateTimeListener.reloadAlarms();
|
||||
}
|
||||
else if(action.equals(Intent.ACTION_TIME_CHANGED))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 4);
|
||||
AlarmListener.reloadAlarms();
|
||||
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 3);
|
||||
DateTimeListener.reloadAlarms();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@ -104,7 +103,7 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return TimeZoneListener.isTimeZoneListenerActive();
|
||||
return TimeZoneListener.isTimezoneListenerActive();
|
||||
}
|
||||
@Override
|
||||
public Trigger_Enum[] getMonitoredTrigger()
|
||||
|
BIN
app/src/main/res/drawable-hdpi/smartphone.png
Normal file
BIN
app/src/main/res/drawable-hdpi/smartphone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable/arrow_azimuth.png
Normal file
BIN
app/src/main/res/drawable/arrow_azimuth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable/arrow_pitch.png
Normal file
BIN
app/src/main/res/drawable/arrow_pitch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/drawable/arrow_roll.png
Normal file
BIN
app/src/main/res/drawable/arrow_roll.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
10
app/src/main/res/drawable/info.xml
Normal file
10
app/src/main/res/drawable/info.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||
</vector>
|
BIN
app/src/main/res/drawable/satellite.png
Normal file
BIN
app/src/main/res/drawable/satellite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@ -16,14 +16,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
|
||||
android:text="@string/settings"
|
||||
android:text="@string/controlCenter"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bMoreSettings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/moreSettings" />
|
||||
android:text="@string/settings" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
@ -83,12 +83,37 @@
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bShareConfigAndLog"
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/emailPretext" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkShareConfigAndLog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/shareConfigAndLogFilesWithDev" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSendEmailToDev"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sendEmailToDev" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logsExplanation" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_span="2"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFileStoreLocation"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/closeNotifications"
|
||||
android:textSize="25dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/notificationCloseActionExplanation" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/application" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_marginHorizontal="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/etActivityOrActionPath"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/anyApp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSelectApp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectApplication" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/comparisonCaseInsensitive"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/title" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerTitleDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/text" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerTextDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveActionCloseNotification"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/actionMediaControl" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/actionMediaControlNotice" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaPlayPause"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/playPause" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaPlay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/play" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaPause"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pause" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaStop"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/stop" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaPrevious"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/previous" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbMediaNext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/next" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveControlMediaAction"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/createNotification"
|
||||
android:textSize="25dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:text="@string/title" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/text" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLegend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:text="@string/urlLegend" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveActionNotification"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/sendBroadcast" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/broadcastExplanation" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etBroadcastToSend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bBroadcastSendShowSuggestions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:text="@string/broadcastsShowSuggestions" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveSendBroadcast"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -46,7 +46,7 @@
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTimeFrameHelpText"
|
||||
android:id="@+id/tvLastRule"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/latitude"
|
||||
@ -57,7 +57,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="numberDecimal" />
|
||||
android:inputType="text" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
@ -72,14 +72,14 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/longitude"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etPoiLongitude"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="numberDecimal" />
|
||||
</TableRow>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etPoiLongitude"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="text" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
|
@ -52,6 +52,15 @@
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/profileWarning"
|
||||
android:textStyle="bold"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
||||
android:textColor="@color/lightRed"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/default_margin">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/broadcastReceivedTitle" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/explanationBroadcastTrigger" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvBroadcastUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:text="@string/broadcastListUrl" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbBroadcastReceived"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/broadcastReceived" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbBroadcastNotReceived"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/broadcastNotReceived" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etBroadcastTriggerAction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bBroadcastShowSuggestions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/broadcastsShowSuggestions" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerBroadcast"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
@ -0,0 +1,269 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/deviceOrientationExplanation"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TableRow
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" >
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:src="@drawable/arrow_azimuth"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationAzimuth"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentAzimuth"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" >
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:src="@drawable/arrow_pitch"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationPitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentOrientationPitch"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" >
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:src="@drawable/arrow_roll"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationRoll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentRoll"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bApplyPositionValues"
|
||||
android:text="@string/apply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="0"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:text=""
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientation"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/tolerance"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="@string/wouldCurrentlyApply"
|
||||
android:singleLine="false"
|
||||
android:maxLines="2"
|
||||
android:lines="2"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationAzimuth"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredAzimuth"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:enabled="false"
|
||||
android:inputType="number" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredAzimuthTolerance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:inputType="number" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAppliesAzimuth"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/unknown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationPitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredPitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:enabled="false"
|
||||
android:inputType="number" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredPitchTolerance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:inputType="number" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAppliesPitch"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/unknown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/orientationRoll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredRoll"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:enabled="false"
|
||||
android:inputType="number" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDesiredRollTolerance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="50dp"
|
||||
android:inputType="number" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAppliesRoll"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/unknown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkDevicePositionApplies"
|
||||
android:checked="true"
|
||||
android:text="@string/mustApply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/explanationDeviceOrientationDirection" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSavePositionValues"
|
||||
android:text="@string/save"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</ScrollView>
|
@ -45,6 +45,18 @@
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/automationNotificationsIgnored" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
@ -78,6 +90,20 @@
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/comparisonCaseInsensitive"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
@ -106,6 +132,13 @@
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
@ -139,7 +172,7 @@
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerNotification"
|
||||
android:id="@+id/bSaveActionCloseNotification"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
100
app/src/main/res/layout/activity_manage_trigger_profile.xml
Normal file
100
app/src/main/res/layout/activity_manage_trigger_profile.xml
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:stretchColumns="1" >
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:text="@string/profile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerProfiles"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<View
|
||||
android:layout_span="2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@android:color/darker_gray" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:text="@string/needsToBeActive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkProfileActive"
|
||||
android:checked="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<View
|
||||
android:layout_span="2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@android:color/darker_gray" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:text="@string/checkSettings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkProfileCheckSettings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_span="2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/profileTriggerCheckSettings" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerProfile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/save" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
@ -23,7 +23,7 @@
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTimeFrameHelpText"
|
||||
android:id="@+id/tvLastRule"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/end"
|
||||
@ -71,13 +71,20 @@
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentNfcIdValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/timeFrameWhichDays"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentNfcIdValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/timeFrameWhichDays"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDaysHint"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/red" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkMonday"
|
||||
android:layout_width="wrap_content"
|
||||
@ -119,6 +126,34 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sunday" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkRepeat"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/repeatEveryXseconds" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etRepeatEvery"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:minWidth="75dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:inputType="numberSigned" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTimeFrame"
|
||||
|
@ -262,6 +262,18 @@
|
||||
android:inputType="number"></EditTextPreference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:summary="@string/deviceOrientationSettings"
|
||||
android:title="@string/deviceOrientationSettings">
|
||||
|
||||
<EditTextPreference
|
||||
android:key="acceptDevicePositionSignalEveryX_MilliSeconds"
|
||||
android:summary="@string/deviceOrientationTimeAcceptIntervalSummary"
|
||||
android:title="@string/deviceOrientationTimeAcceptIntervalTitle"
|
||||
android:inputType="number"></EditTextPreference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:summary="@string/activityDetection"
|
||||
@ -280,6 +292,18 @@
|
||||
android:inputType="number"></EditTextPreference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:summary="@string/musicPlayingDetection"
|
||||
android:title="@string/musicPlayingDetection">
|
||||
|
||||
<EditTextPreference
|
||||
android:key="musicCheckFrequency"
|
||||
android:summary="@string/musicCheckFrequencySummary"
|
||||
android:title="@string/musicCheckFrequencyTitle"
|
||||
android:inputType="number"></EditTextPreference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
</PreferenceScreen>
|
@ -6,10 +6,10 @@
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvVolumeTestExplanation"
|
||||
android:id="@+id/tvVolumeCalibrationExplanation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/volumeTesterExplanation"
|
||||
android:text="@string/volumeCalibrationExplanation"
|
||||
android:layout_marginBottom="20dp" />
|
||||
|
||||
<TableLayout
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentVolume"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0dB"
|
||||
@ -45,6 +46,7 @@
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etReferenceValue"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="5"
|
@ -151,7 +151,7 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="10dp" >
|
||||
<TextView
|
||||
android:id="@+id/tvTimeFrameHelpText"
|
||||
android:id="@+id/tvLastRule"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/helpTextTimeFrame" />
|
||||
|
@ -193,7 +193,7 @@
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTimeFrameHelpText"
|
||||
android:id="@+id/tvLastRule"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="5"
|
||||
android:layout_height="wrap_content"
|
||||
@ -203,6 +203,34 @@
|
||||
android:singleLine="false"
|
||||
android:textSize="20dp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginTop="20dp" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="5"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:text="@string/lastProfile"
|
||||
android:scrollHorizontally="false"
|
||||
android:singleLine="false"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLastProfile"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_weight="5"
|
||||
android:scrollHorizontally="false"
|
||||
android:singleLine="false"
|
||||
android:text="n./a."
|
||||
android:textSize="20dp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
@ -327,12 +355,27 @@
|
||||
android:text="@string/privacy" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSettings"
|
||||
android:id="@+id/bControlCenter"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:text="@string/settings" />
|
||||
|
||||
android:text="@string/controlCenter" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bDonate"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:text="@string/donate" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/emailContactNotice" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -51,7 +51,7 @@
|
||||
android:background="@color/barBackgroundColor" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTimeFrameHelpText"
|
||||
android:id="@+id/tvLastRule"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ruleList"
|
||||
|
@ -2,7 +2,7 @@
|
||||
<resources>
|
||||
<string name="ruleActivate">Aktiviere Regel %1$s</string>
|
||||
<string name="profileActivate">Aktiviere Profil %1$s</string>
|
||||
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umschaltmodus</string>
|
||||
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umkehrmodus</string>
|
||||
<string name="addPoi">Ort hinzufügen</string>
|
||||
<string name="addRule">Regel hinzufügen</string>
|
||||
<string name="poiList">Orts-Liste:</string>
|
||||
@ -11,7 +11,7 @@
|
||||
<string name="pleaseSpecifiyTrigger">Bitte geben Sie mindestens einen Auslöser an.</string>
|
||||
<string name="pleaseSpecifiyAction">Bitte geben Sie mindestens eine Aktion an.</string>
|
||||
<string name="serviceWontStart">Weder Orte noch Regeln sind definitiv. Dienst wird nicht starten.</string>
|
||||
<string name="serviceStarted">Automations-Dienst gestarted.</string>
|
||||
<string name="serviceStarted">Automations-Dienst gestartet.</string>
|
||||
<string name="version">Version %1$s.</string>
|
||||
<string name="distanceBetween">Der Abstand zwischen GPS- und Mobilfunk-Position beträgt %1$d m. Dies +1 sollte der minimale Radius sein.</string>
|
||||
<string name="positioningWindowNotice">Falls Sie in einem Gebäude sind, wird empfohlen das Gerät in die Nähe eines Fensters zu bringen bis eine Position ermittelt werden konnte. Andernfalls kann es sehr lange dauern oder es funktioniert gar nicht.</string>
|
||||
@ -57,13 +57,13 @@
|
||||
<string name="end">Ende</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="urlToTrigger">URL, die ausgelöst werden soll:</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (< Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung</string>
|
||||
<string name="wifi">WLAN</string>
|
||||
<string name="activating">Aktiviere</string>
|
||||
<string name="deactivating">Deaktiviere</string>
|
||||
<string name="bluetoothFailed">Änderung des Bluetooth Status fehlgeschlagen. Verfügt dieses Gerät über Bluetooth?</string>
|
||||
<string name="urlTooShort">Die Adresse ist zu kurz. Sie muß aus mindestens 10 Buchstaben bestehen.</string>
|
||||
<string name="textTooShort">Der Text ist zu kurz. Er muß aus mindestens 10 Buchstaben bestehen.</string>
|
||||
<string name="enterPhoneNumberAndText">Geben Sie eine Telefonnummer und einen Text ein.</string>
|
||||
<string name="selectTypeOfTrigger">Welche Art von Auslöser</string>
|
||||
<string name="entering">betrete</string>
|
||||
<string name="leaving">verlasse</string>
|
||||
@ -116,8 +116,8 @@
|
||||
<string name="timeframes">Zeiträume</string>
|
||||
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
|
||||
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
|
||||
<string name="toggableRules">Umkehrbare Regeln</string>
|
||||
<string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umschaltbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umschaltbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
|
||||
<string name="toggableRules">Unschaltbare Regeln</string>
|
||||
<string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umkehrbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umkehrbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
|
||||
<string name="helpTextProcessMonitoring">Wenn Sie eine Regel mit einer Prozess Überwachung erstellen, wird die Anwendung in regelmäßigen Abständen nach diesem Prozess schauen. Wie häufig können Sie in den Einstellungen festlegen. Das mag zwar in vielen Fällen langsam reagieren, aber eine permanente Überwachung würde zuviel Akkuleistung kosten. Und das Betriebssystem stellt dafür keinen Broadcast zur Verfügung.</string>
|
||||
<string name="helpTitleEnergySaving">Energiespareinstellungen</string>
|
||||
<string name="helpTextEnergySaving">Viele Gerätehersteller versuchen Energie zu sparen, indem die Hintergrundaktivitäten vieler Anwendungen eingeschränkt werden. Unglücklicherweise führt das häufig dazu, dass diese Anwendungen nicht mehr zufällig funktionieren; das gilt auch für Automation. Schauen Sie sich <a href="https://dontkillmyapp.com/">diese Seite</a> an, um herauszufinden, wie Sie Automation auf Ihrem Gerät von dieser Behandlung ausschließen können.</string>
|
||||
@ -305,7 +305,7 @@
|
||||
<string name="currentId">Aktuelle Bezeichnung:</string>
|
||||
<string name="nfcTagDataNotUsable">Tag Daten nicht nutzbar, neu schreiben</string>
|
||||
<string name="nfcBringTagIntoRangeToRead">Bringen Sie einen Tag in Reichweite, um ihn zu lesen.</string>
|
||||
<string name="toggleRule">Umschaltregel</string>
|
||||
<string name="toggleRule">Umkehrregel</string>
|
||||
<string name="toggling">Schalte um</string>
|
||||
<string name="toggle">umzuschalten</string>
|
||||
<string name="overlapBetweenPois">Überschneidung mit Ort %1$s von %2$s Metern festgestellt. Reduzieren Sie den Radius um mindestens diesen Wert.</string>
|
||||
@ -337,7 +337,7 @@
|
||||
<string name="outgoingCallTo">Ausgehender Telefonanruf von %1$s.</string>
|
||||
<string name="actionSpeakText">Text sprechen</string>
|
||||
<string name="textToSpeak">Zu sprechender Text</string>
|
||||
<string name="toggleNotAllowed">Die Umschaltfunktion ist momentan nur für Regeln erlaubt, die NFC Tags als Auslöser haben. Für weitere Informationen lesen Sie die Hilfe.</string>
|
||||
<string name="toggleNotAllowed">Die Umkehrfunktion ist momentan nur für Regeln erlaubt, die NFC Tags als Auslöser haben. Für weitere Informationen lesen Sie die Hilfe.</string>
|
||||
<string name="errorReadingPoisAndRulesFromFile">Fehler beim Lesen von Orten und Regeln aus Datei.</string>
|
||||
<string name="noDataChangedReadingAnyway">Es scheint als wären keine Datenänderungen gespeichert worden. Allerdings könnten Änderungen im Speicher sein, die zurückgenommen werden müssen. Daher wird die Einstellungsdatei neu geladen.</string>
|
||||
<string name="bluetoothConnection">Bluetooth Verbindung</string>
|
||||
@ -356,7 +356,7 @@
|
||||
<string name="selectConnectionOption">Wählen Sie eine Verbindungsoption.</string>
|
||||
<string name="triggerHeadsetPlugged">Headset Verbindung</string>
|
||||
<string name="actionPlayMusic">Musikplayer öffnen</string>
|
||||
<string name="headsetConnected">Headset (type: %1$s) verbunden</string>
|
||||
<string name="headsetConnected">Headset (Art: %1$s) verbunden</string>
|
||||
<string name="headsetDisconnected">Headset (type: %1$s) getrennt</string>
|
||||
<string name="headphoneSimple">Kopfhörer</string>
|
||||
<string name="headphoneMicrophone">Mikrofon</string>
|
||||
@ -403,17 +403,17 @@
|
||||
<string name="startNewThreadForRuleExecution">Für Regelaktivierung neuen Thread starten.</string>
|
||||
<string name="newThreadRules">Neuer Thread</string>
|
||||
<string name="showIcon">Symbol</string>
|
||||
<string name="showIconWhenServiceIsRunning">Symbol anzeigen, wenn Dienst läuft (verstecken funktioniert nur unterhalb Android 7)</string>
|
||||
<string name="showIconWhenServiceIsRunning">Symbol anzeigen, wenn Dienst läuft (verstecken funktioniert nur unterhalb Android 7). Wenn Sie auf einer höheren Version sind, gehen Sie in die System Einstellungen, dann Automation und dann Benachrichtigungen. Deaktivieren Sie die \"Service notification\".</string>
|
||||
<string name="ruleHistory">Regel Historie (letzte zuerst):</string>
|
||||
<string name="someOptionsNotAvailableYet">Manche Optionen sind deaktiviert, da sie noch nicht funktionieren. Sie kommen in einer späteren Programmversion dazu.</string>
|
||||
<string name="lockSoundChanges">Tonänderungen sperren</string>
|
||||
<string name="noProfileChangeSoundLocked">Profil wird nicht aktiviert. Zuletzt aktiviertes Profil ist gesperrt worden.</string>
|
||||
<string name="currentVolume">Momentane Lautstärke</string>
|
||||
<string name="enterValidReferenceValue">Geben Sie einen gültigen Referenzwert ein.</string>
|
||||
<string name="volumeTest">Lautstärkentest</string>
|
||||
<string name="volumeTesterExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
|
||||
<string name="volumeTest">Lautstärkekalibrierung</string>
|
||||
<string name="volumeCalibrationExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
|
||||
<string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string>
|
||||
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string>
|
||||
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie die Regel manuell ausführen, um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken "immer erlauben" setzen. Ansonsten wird die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen.</string>
|
||||
<string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string>
|
||||
<string name="phoneNrReplacementError">Die letzte Telefonnummer konnte nicht in die Variable integriert werden. Sie liegt mir nicht vor.</string>
|
||||
<string name="username">Benutzername</string>
|
||||
@ -532,12 +532,12 @@
|
||||
<string name="fileDoesNotExist">Datei existiert nicht.</string>
|
||||
<string name="noFileManageInstalled">Kein Dateimanager installiert.</string>
|
||||
<string name="alwaysPlayExplanation">Wenn diese Einstellung aktiv ist, wird der Ton immer abgespielt. Wenn die Einstellung inaktiv ist, wird der Ton nur dann abgespielt, wenn das Telefon weder auf stumm noch auf Vibration steht, d.h. Klingeltöne aktiv sind. Allerdings hat es keinen Einfluß auf die Medien-Lautstärke. D.h., wenn diese stumm ist, werden Sie so oder so nichts zu hören bekommen.</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Konfigurations- und Logdatei mit Entwickler teilen (via email).</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Konfigurations- und Logdateien anhängen</string>
|
||||
<string name="shareConfigAndLogExplanation">Dies wird eine neue Email öffnen mit Konfigurations- und Logdateien als Zip-Anhang. Sie wird nicht automatisch versendet. D.h. Sie können so z.B. auch den Adressaten zu sich selbst ändern.</string>
|
||||
<string name="notificationTriggerExplanation">Dieser Auslöser reagiert auf Benachrichtigungen anderer Anwendung im Benachrichtigungsbereich von Android (oder wenn diese geschlossen werden). Sie können eine bestimmte Anwendung festlegen, von die Nachricht stammen muß. Wenn nicht, zählt jede Benachrichtigung. Sie können auch Zeichenketten für Titel oder Nachrichteninhalt festlegen, die enthalten sein müssen. Die Groß-/Kleinschreibung wird hierbei nicht berücksichtigt.</string>
|
||||
<string name="addParameters">Parameter hinzufügen</string>
|
||||
<string name="errorRunningRule">Fehler beim Ausführen einer Regel.</string>
|
||||
<string name="startAppChoiceNote">Hier haben Sie 2 grundsätzliche Optionen:\n\n1. Sie können ein Programm starten, indem Sie eine Activity auswählen.\nStellen Sie sich das so vor, daß Sie ein bestimmtes Fenster einer Anwendung vorauswählen, in das man direkt springt. Behalten Sie im Kopf, daß das nicht immer funktionieren wird. Das liegt daran, daß die Fenster einer Anwendung miteinander interagieren können, sich u.U. Parameter übergeben. Wenn man jetzt ganz kalt in ein bestimmtes Fenster springt, könnte dieses zum Start z.B. bestimmte Parameter erwarten - die fehlen. So könnte es passieren, daß das Fenster zwar versucht zu öffnen, das aber nicht klappt und es somit nie wirlich sichtbar wird. Versuchen Sie\'s trotzdem!\nSie können den Pfad manuell eingeben, sollten aber den Auswählen-Knopf benutzen. Wenn Sie es dennoch manuell eingeben, geben Sie den PackageName ins obere Feld ein und den vollen Pfad der Activity ins untere.\n\n2. Auswahl per Action\nIm Gegensatz zur Auswahl eines bestimmten Fensters, können Sie ein Programm auch über eine Action starten lassen. Stellen Sie sich das so vor als würden Sie in den Wald rufen \"Ich hätte gerne XYZ\" und falls eine Anwendung installiert ist, die das liefern kann, wird sie gestartet. Ein gutes Beispiel wäre zum Beispiel "Browser starten" - es könnten sogar mehrere installiert sein, die das können (aber normalerweise gibts eine, die als Standard eingestellt ist).\nDiese Action müssen Sie manuell eingeben. Der PackageName ist hier optional. Behalten Sie dabei im Auge, daß mögliche Variablen nicht aufgelöst werden. Beispielsweise werden Sie häufig im Internet finden, daß man die Kamera über die Action \"MediaStore.ACTION_IMAGE_CAPTURE\" starten kann. Das ist grundsätzlich nicht richtig, wird aber nicht direkt funktionieren, denn das ist nur eine Variable. Sie müssen dann einen Blick in die Android Dokumentation werfen, wo Sie sehen werden, daß sich hinter dieser Variable eigentlich der Wert \"android.media.action.IMAGE_CAPTURE\" verbirgt. Gibt man diesen in das Feld ein, wird\'s funktionieren.</string>
|
||||
<string name="startAppChoiceNote">Hier haben Sie 2 grundsätzliche Optionen:\n\n1. Sie können ein Programm starten, indem Sie eine Activity auswählen.\nStellen Sie sich das so vor, daß Sie ein bestimmtes Fenster einer Anwendung vorauswählen, in das man direkt springt. Behalten Sie im Kopf, daß das nicht immer funktionieren wird. Das liegt daran, daß die Fenster einer Anwendung miteinander interagieren können, sich u.U. Parameter übergeben. Wenn man jetzt ganz kalt in ein bestimmtes Fenster springt, könnte dieses zum Start z.B. bestimmte Parameter erwarten - die fehlen. So könnte es passieren, daß das Fenster zwar versucht zu öffnen, das aber nicht klappt und es somit nie wirlich sichtbar wird. Versuchen Sie\'s trotzdem!\nSie können den Pfad manuell eingeben, sollten aber den Auswählen-Knopf benutzen. Wenn Sie es dennoch manuell eingeben, geben Sie den PackageName ins obere Feld ein und den vollen Pfad der Activity ins untere.\n\n2. Auswahl per Action\nIm Gegensatz zur Auswahl eines bestimmten Fensters, können Sie ein Programm auch über eine Action starten lassen. Stellen Sie sich das so vor als würden Sie in den Wald rufen \"Ich hätte gerne XYZ\" und falls eine Anwendung installiert ist, die das liefern kann, wird sie gestartet. Ein gutes Beispiel wäre zum Beispiel "Browser starten" - es könnten sogar mehrere installiert sein, die das können (aber normalerweise gibts eine, die als Standard eingestellt ist).\nDiese Action müssen Sie manuell eingeben. Der PackageName ist hier optional. Behalten Sie dabei im Auge, daß mögliche Variablen nicht aufgelöst werden. Beispielsweise werden Sie häufig im Internet finden, daß man die Kamera über die Action \"MediaStore.ACTION_IMAGE_CAPTURE\" starten kann. Das ist grundsätzlich richtig, wird aber nicht direkt funktionieren, denn das ist nur eine Variable. Sie müssen dann einen Blick in die Android Dokumentation werfen, wo Sie sehen werden, daß sich hinter dieser Variable eigentlich der Wert \"android.media.action.IMAGE_CAPTURE\" verbirgt. Gibt man diesen in das Feld ein, wird\'s funktionieren.</string>
|
||||
<string name="cantFindSoundFile">Kann die Audiodatei %1$s nicht finden und daher auch nicht abspielen.</string>
|
||||
<string name="startAppByActivity">per Activity</string>
|
||||
<string name="startAppByAction">per Action</string>
|
||||
@ -557,7 +557,7 @@
|
||||
<string name="noFilesImported">Keine Dateien konnten importiert werden.</string>
|
||||
<string name="notAllFilesImported">Nicht alle passenden Dateien konnten importiert werden.</string>
|
||||
<string name="openExamplesPage">Webseite mit Beispielen öffnen</string>
|
||||
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben, aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
|
||||
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben (des Anrufpartners), aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
|
||||
<string name="prefsImportError">Fehler beim Importieren der Einstellungen.</string>
|
||||
<string name="rulesImportedSuccessfully">Regeln und Orte wurden erfolgreich importiert.</string>
|
||||
<string name="rulesImportError">Fehler beim Importieren der Regeln.</string>
|
||||
@ -595,4 +595,132 @@
|
||||
<string name="bottom">Unten</string>
|
||||
<string name="tabsPlacementSummary">Wol soll die Taskleiste angezeigt werden?</string>
|
||||
<string name="tones">Klingeltöne</string>
|
||||
<string name="miscellaneous">Verschiedenes</string>
|
||||
<string name="dnd">Nicht stören</string>
|
||||
<string name="dndOff">Nicht stören aus</string>
|
||||
<string name="dndAlarms">Alarme durchlassen</string>
|
||||
<string name="dndPriority">Prioritätsbenachrichtigungen durchlassen</string>
|
||||
<string name="dndNothing">Nichts durchlassen</string>
|
||||
<string name="repeatEveryXseconds">Alle x Sekunden wiederholen</string>
|
||||
<string name="repeatEveryXsecondsWithVariable">alle %1$s Sekunden wiederholen</string>
|
||||
<string name="donate">Spenden</string>
|
||||
<string name="notice">Hinweis</string>
|
||||
<string name="automationNotificationsIgnored">Wenn Sie keine bestimmte Anwendung auswählen, werden Benachrichtigungen von Automation selbst ignoriert, um Schleifen zu verhindern.</string>
|
||||
<string name="elementSkipped">Ein Element der Konfigurationsdatei konnte nicht gelesen werden. Die Datei könnte von einer neueren Programmversion erstellt worden sein.</string>
|
||||
<string name="permissionsRequiredNotAvailable">Ihre Regeln benötigen Berechtigungen, die die installierte Variante von Automation nicht unterstützt.</string>
|
||||
<string name="dndRemarks">Feineinstellungen (wie Telefonanrufe erlauben, Auswählen bestimmter Telefonnummern, etc.) können nur in den Systemeinstellungen gesetzt werden.</string>
|
||||
<string name="wifiApi30">Weil Google wieder einen weiteren Teil von Android kaputt gemacht hat, können ab API 30 nur noch jede WLANs angezeigt werden, die sich gegenwärtig in Reichweite befinden, nicht mehr alle, zu denen das Gerät einmal verbunden war.</string>
|
||||
<string name="smsDialogNotice">Wenn Sie in diesem Programm noch keine SMS-senden Aktion benutzt haben, zeigt Android wahrscheinlich beim ersten Ausführen einen Bestätigungsdialog an. Sie müssen das Häkchen bei \"Immer erlauben\" setzen und bestätigen, wenn Sie möchten, daß diese Aktion im Hintergrund ausgeführt werden kann. Es wird daher empfohlen, diese Regel einmalig manuell auszuführen, um diesen Dialog zu provozieren.</string>
|
||||
<string name="silentTriggersDnd">Hinweis: Der Stumm-Modus löst auf neuren Geräten häufig die Funktion \"Nicht stören\" aus. Wenn das auf Ihrem Gerät passiert, wird empfohlen stattdessen den Normalen Modus zu verwenden und alle Lautstärken auf 0 zu reduzieren.</string>
|
||||
<string name="deviceOrientation">Geräteausrichtung</string>
|
||||
<string name="tolerance">Toleranz (0-180)</string>
|
||||
<string name="orientationAzimuth">Azimut:</string>
|
||||
<string name="orientationPitch">Neigung:</string>
|
||||
<string name="enterValidNumbersIntoAllFields">Geben Sie gültige Nummern in allen Feldern ein.</string>
|
||||
<string name="orientationRoll">Rollen:</string>
|
||||
<string name="wouldCurrentlyApply">Würde gerade zutreffen?</string>
|
||||
<string name="deviceIsInCertainOrientation">Das Gerät hat eine bestimmte Ausrichtung</string>
|
||||
<string name="toleranceOf180OnlyAllowedIn2Fields">Eine Toleranz von 180 ist nur für zwei Toleranz-Felder erlaubt, nicht alle drei. Andernfalls würde der Auslöser immer zutreffen.</string>
|
||||
<string name="unknown">unbekannt</string>
|
||||
<string name="orientation">Ausrichtung</string>
|
||||
<string name="turnScreenOnOrOff">Bildschirm ein- oder ausschalten</string>
|
||||
<string name="turnScreenOn">Bildschirm einschalten</string>
|
||||
<string name="turnScreenOff">Bildschirm ausschalten</string>
|
||||
<string name="mustApply">Muß zutreffen</string>
|
||||
<string name="deviceOrientationTimeAcceptIntervalTitle">Signal Häufigkeit</string>
|
||||
<string name="deviceOrientationTimeAcceptIntervalSummary">Neue Signale nur alle x Millisekunden akzeptieren</string>
|
||||
<string name="deviceOrientationSettings">Geräteausrichtungseinstellungen</string>
|
||||
<string name="explanationDeviceOrientationDirection">Wenn das Häkchen gesetzt ist, bedeutet das, daß das Gerät in der angegebenen Ausrichtung sein muß. Wenn es nicht gesetzt ist, führt jede andere Ausrichtung zu einem positiven Ergebnis.</string>
|
||||
<string name="deviceOrientationExplanation">Wenn Sie Ihr Gerät bewegen, werden die Zahlen unten aktualisiert. Was Sie hier sehen können, ist die momentane Ausrichtung Ihres Geräts, gemessen in Grad. Wenn das Gerät in der gewünschten Ausrichtung ist, klicken Sie den \"übernehmen\" Knopf, um die Werte in die \"gewünscht\" Felder zu übertragen.\nWeil es sehr unwahrscheinlich ist, daß Sie diese exakte Ausrichtung jemals wieder erreichen, müssen Sie Toleranzen eingeben. Dies ist der Winkel in Grad, der in jede Richtung noch akzeptiert wird. 15° entsprechen somit einem Gesamtwinkel von 30°, 15 in jede Richtung.\nWenn Ihnen nur eine bestimmte Achse wichtig ist, können Sie eine Toleranz von 180° für die anderen beiden Richtungen angeben.</string>
|
||||
<string name="actionSetBluetoothTethering">Bluetooth Tethering</string>
|
||||
<string name="actionTurnBluetoothTetheringOn">Bluetooth Tethering einschalten</string>
|
||||
<string name="actionTurnBluetoothTetheringOff">Bluetooth Tethering ausschalten</string>
|
||||
<string name="enterRepetitionTime">Sie müssen eine positive Ganzzahl als Wiederholungszeit eingeben.</string>
|
||||
<string name="btTetheringNotice">Diese Funktion funktioniert bestätigt bis einschließlich Android 8.0. Ab einer höheren Version funktioniert sie nicht mehr, aber ich ich kann mangels physischer Geräte nicht sagen, aber welcher genau. Unter Android 11 funktioniert es definitiv nicht mehr. Wenn Sie eine Version dazwischen haben, lassen Sie mich bitte wissen, ob es funktioniert oder nicht.</string>
|
||||
<string name="triggerWrong">Mit diesem Auslöser stimmt etwas nicht. Er konnte nicht korrekt geladen werden.</string>
|
||||
<string name="android.permission.BIND_DEVICE_ADMIN">Geräte Administrator</string>
|
||||
<string name="deviceAdminNote">Geräte Administrator Rechte werden für mindestens 1 Regel benötigt, die Sie angelegt haben.</string>
|
||||
<string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Von der Akku-Optimierung ausschließen</string>
|
||||
<string name="recommendedForBetterReliability">Empfohlen für bessere Zuverlässigkeit</string>
|
||||
<string name="needsToBeActive">Muß aktiv sein</string>
|
||||
<string name="checkSettings">Einstellungen überprüfen</string>
|
||||
<string name="profileActive">Profil %1$s ist aktiv</string>
|
||||
<string name="profileNotActive">Profil %1$s ist nicht aktiv</string>
|
||||
<string name="profileTriggerCheckSettings">Wenn dieses Häkchen nicht gesetzt ist, wird nur geprüft, ob das ausgewählte Profil zuletzt aktiviert wurde. Es ist egal, ob Audio-Einstellungen von außerhalb verändert wurden.\nWenn das Häkchen aber gesetzt ist, müssen die aktuellen Audio-Einstellungen auch wirklich genau so gesetzt sein, wie im Profil definiert. ACHTUNG: Der Klingelton selbst kann derzeit noch nicht überprüft werden.</string>
|
||||
<string name="profileCouldNotBeDeleted">Profil konnte nicht gelöscht werden.</string>
|
||||
<string name="ruleXIsUsingProfileY">Dieses Profil kann nicht gelöscht werden. Regel %1$s verwendet noch Profil %2$s.</string>
|
||||
<string name="noRepetition">keine Wiederholung</string>
|
||||
<string name="usingAuthentication">mit Authentifizierung</string>
|
||||
<string name="toNumber">zu Nummer</string>
|
||||
<string name="message">Nachricht</string>
|
||||
<string name="onDays">an Tagen</string>
|
||||
<string name="notSet">nicht gesetzt</string>
|
||||
<string name="takeLauncherActivity">Automatisch auswählen</string>
|
||||
<string name="pickActivityManually">Manuell auswählen</string>
|
||||
<string name="launcherOrManualExplanation">Einfacher Modus: Automation kann versuchen, die Start-Activity des Zielprogramms automatisch zu finden.\nAlternativ können Sie die gewünschte Activity auch manuell auswählen.\nWelche Variante möchten Sie?</string>
|
||||
<string name="launcherNotFound">Eine Start-Activity dieser Anwendung konnte nicht gefunden werden. Sie müssen manuell eine auswählen.</string>
|
||||
<string name="enterTitle">Geben Sie einen Titel ein.</string>
|
||||
<string name="enterText">Geben Sie einen Text ein.</string>
|
||||
<string name="info">Info</string>
|
||||
<string name="createNotification">Benachrichtigung erstellen</string>
|
||||
<string name="profileWasNotFound">Das Profil, das in dieser Regel referenziert wird, existiert scheinbar nicht mehr. Das alphabetisch erste wurde stattdessen ausgewählt.</string>
|
||||
<string name="closeNotifications">Benachrichtigung(en) schließen</string>
|
||||
<string name="comparisonCaseInsensitive">Groß-/Kleinschreibung ist egal.</string>
|
||||
<string name="notificationCloseActionExplanation">Wenn Sie keine Kriterien angeben, werden ALLE Benachrichtigungen geschlossen. Es wird also empfohlen, zumindest eine Anwendung zu spezifizieren und/oder Titel oder Text anzugeben.</string>
|
||||
<string name="profileWarning">Die Einstellungen, die Sie hier vornehmen, können dazu führen, dass Sie bestimmte Dinge auf Ihrem Telefon nicht mehr mitbekommen. Sie können sogar Ihren Wecker zum Schweigen bringen. Was auch immer Sie hier einstellen - es wird empfohlen, es zu testen.</string>
|
||||
<string name="ifString">falls</string>
|
||||
<string name="pleaseSelectActionValue">Bitte wählen Sie eine Aktion!</string>
|
||||
<string name="android.permission.MEDIA_CONTENT_CONTROL">Medien steuern</string>
|
||||
<string name="play">abspielen</string>
|
||||
<string name="stop">stop</string>
|
||||
<string name="next">nächster</string>
|
||||
<string name="previous">vorheriger</string>
|
||||
<string name="pause">pausieren</string>
|
||||
<string name="playPause">abspielen/pause umschalten</string>
|
||||
<string name="selectCommand">Kommando auswählen</string>
|
||||
<string name="unlocked">entsperrt</string>
|
||||
<string name="on">an</string>
|
||||
<string name="off">aus</string>
|
||||
<string name="actionMediaControlNotice">Bedenken Sie, daß diese Aktion nicht notwendigerweise mit allen Playern funktioniert. Und selbst, wenn es mit einem grundsätzlich funktioniert, müssen auch nicht alle der u.g. Kommandos funktionieren.</string>
|
||||
<string name="screenState">Bildschirm Status</string>
|
||||
<string name="actionMediaControl">Medien steuern</string>
|
||||
<string name="selectDesiredState">Bitte gewünschten Zustand wählen</string>
|
||||
<string name="screenIs">Bildschirm ist %1$s</string>
|
||||
<string name="sendEmailToDev">Email an Entwickler schicken</string>
|
||||
<string name="controlCenter">Steuerungszentrale</string>
|
||||
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.</string>
|
||||
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Aufgrund Google\'s unendlicher Weisheit, ist die letzte Android Version, mit der diese Funktion noch funktioniert, die Version %1$s. Sie können es hier einrichten, aber vermutlich wird es keine Auswirkung haben.</string>
|
||||
<string name="musicPlaying">Musik läuft</string>
|
||||
<string name="selectParameters">Wählen Sie die Parameter</string>
|
||||
<string name="musicIsPlaying">Musik läuift</string>
|
||||
<string name="musicIsNotPlaying">Musik läuft nicht</string>
|
||||
<string name="musicCheckFrequencyTitle">Prüffrequenz</string>
|
||||
<string name="musicCheckFrequencySummary">Millisekunden zwischen Prüfungen</string>
|
||||
<string name="musicPlayingDetection">Musik-läuft Erkennung</string>
|
||||
<string name="locationNotWorkingOn12">Das Abrufen des Standorts scheint unter Android 12 derzeit nicht zu funktionieren. Wenn es bei Ihnen nicht klappt, tut mir das leid. Ich werde versuchen die Ursache zu beheben, sobald mir die Ursache bekannt ist. Wenn der Donut bei Ihnen also nicht aufhört sich zu drehen, wissen Sie warum.</string>
|
||||
<string name="profileXrequiresThis">Profil \"%1$s\" benötigt dies.</string>
|
||||
<string name="lastProfile">Letztes Profil:</string>
|
||||
<string name="queryAllPackages">Liste von installierten Anwendungen auslesen</string>
|
||||
<string name="timeFrameDaysHint">Wenn Sie ein Zeitfenster verwenden, das sich über Mitternacht erstreckt, müssen Sie auch den Folgetag auswählen, wenn der Auslöser auch nach Mitternacht noch auslösen soll.</string>
|
||||
<string name="featureNotInGooglePlayVersion">Diese Funktion ist in der Google Play-Version nicht mehr verfügbar.\n\nHin und wieder schikaniert Google Entwickler. Wenn Sie bestimmte Funktionen weiterhin verwenden möchten, müssen Sie Unterlagen einreichen. Leider besteht eine 99% ige Chance, dass der Papierkram abgelehnt wird. Es ist so ziemlich wie im Asterix-Comic/Film.\n\nIch habe in der Vergangenheit Wochen damit verbracht, mit ihnen über solche Fälle zu streiten, aber ich bekam immer wieder Ablehnungen - entweder von Bots oder von Leuten, die ungefähr so intelligent sind wie Bots. Ich kann mich dann nur entscheiden, ob die App vollständig aus dem Play Store fliegen soll oder die Funktion aus der Play Store Version entfernen.\n\nBitte erwägen Sie, die APK-Version von meiner Website oder die von F-Droid zu verwenden, wenn Sie diese Funktionen benötigen.</string>
|
||||
<string name="startActivityInsertManually">Diese Einschränkung betrifft nur die Auswahl einer App, nicht den eigentlichen Start. So können Sie den Namen einer Anwendung immer noch manuell eingeben, falls Sie ihn kennen.</string>
|
||||
<string name="serviceStarts">Dienst startet</string>
|
||||
<string name="deviceStarts">Gerät startet</string>
|
||||
<string name="deviceHasJustStarted">Gerät ist gerade gestartet</string>
|
||||
<string name="serviceHasJustStarted">Dienst ist gerade gestartet</string>
|
||||
<string name="broadcastReceived">Broadcast empfangen</string>
|
||||
<string name="broadcastNotReceived">Broadcast nicht empfangen</string>
|
||||
<string name="broadcastReceivedTitle">Broadcast empfangen</string>
|
||||
<string name="broadcastsShowSuggestions">Vorschläge anzeigen</string>
|
||||
<string name="selectBroadcast">Broadcast auswählen</string>
|
||||
<string name="lockedWithoutSecurity">gesperrt (nur wischen, keine PIN, etc.)</string>
|
||||
<string name="lockedWithSecurity">gesperrt (mit PIN, etc.)</string>
|
||||
<string name="lockedCommentScreenMustBeOff">Jeglicher Sperrzustand wird nur erkannt werden, wenn gleichzeitig der Bildschirm aus ist.</string>
|
||||
<string name="emailPretext">Wenn Sie ein Problem, einen Vorschlag oder eine Frage haben, schreiben Sie bitte auch etwas in die Email. Senden Sie mir nicht einfach die Dateien mit dem Standard-Mailtext. Ich werde solche Nachrichten ignorieren, sollten wir nicht bereits in einer Konversation sein.</string>
|
||||
<string name="sendBroadcast">Broadcast verschicken</string>
|
||||
<string name="enterBroadcast">Geben Sie eine Aktion für den Broadcast ein.</string>
|
||||
<string name="broadcastExplanation">Diese Aktion erlaubt es, einen Broadcast über das Nachrichtensystem von Android zu verschicken. Das ist für den Benutzer nicht sichtbar, aber Anwendungen, die sich für bestimmte Broadcasts registriert haben, können darauf reagieren.</string>
|
||||
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
|
||||
<string name="logsExplanation">Um eine unnötige Abnutzung Ihres Speichers zu vermeiden, werden Protokolle standardmäßig nicht gespeichert. Wenn Sie also ein Problem haben, aktivieren Sie bitte zuerst die Anmeldeeinstellungen und setzen Sie den Protokollpegel auf 5. Reproduzieren Sie dann das Problem. Erst dann können Protokolle angehängt werden.</string>
|
||||
<string name="directionStringDoesNotContain">enthält nicht</string>
|
||||
</resources>
|
@ -127,10 +127,10 @@
|
||||
<string name="actionTurnWifiTetheringOff">desactivar enrutador wifi</string>
|
||||
<string name="actionTurnAirplaneModeOn">encender modo de vuelo</string>
|
||||
<string name="actionTurnAirplaneModeOff">desactivar modo de vuelo</string>
|
||||
<string name="activePoi">sitio activo</string>
|
||||
<string name="activePoi">Sitio activo:</string>
|
||||
<string name="closestPoi">sitio mas cerca</string>
|
||||
<string name="poi">Posición</string>
|
||||
<string name="pois">posiciónes</string>
|
||||
<string name="pois">Posiciones</string>
|
||||
<string name="serviceNotRunning">Servicio no está activo</string>
|
||||
<string name="general">General</string>
|
||||
<string name="startServiceAfterAppUpdate">Encender servicio después de un update si estuvo activado.</string>
|
||||
@ -294,7 +294,7 @@
|
||||
<string name="parameterValue">Valor del parámetro</string>
|
||||
<string name="addIntentValue">Añadir pareja intento</string>
|
||||
<string name="parameterType">Tipo del parámetro</string>
|
||||
<string name="phoneNumberExplanation">Puedes introducir un número, pero es opciónal. Si quieres usar uno puedes elegir uno de su directorio o introducir uno manualmente. Adiciónalmente puedes usar expresiónes regulares. Para probar esos me gusta la pagina:</string>
|
||||
<string name="phoneNumberExplanation">Puedes introducir un número remoto, pero es opciónal. Si quieres usar uno puedes elegir uno de su directorio o introducir uno manualmente. Adiciónalmente puedes usar expresiónes regulares. Para probar esos me gusta la pagina:</string>
|
||||
<string name="screenRotationEnabled">Rotación del monitor activado.</string>
|
||||
<string name="screenRotationDisabled">Rotación del monitor desactivado.</string>
|
||||
<string name="noPoisDefinedShort">No hay sitios.</string>
|
||||
@ -333,7 +333,7 @@
|
||||
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leer notificaciónes del sistema</string>
|
||||
<string name="bluetoothFailed">No pude activar o desactivar Bluetooth. Tiene el dispositvo Bluetooth?</string>
|
||||
<string name="urlTooShort">El url tiene que tener mínimo 10 caracteres.</string>
|
||||
<string name="textTooShort">El texto tiene que tener mínimo 10 caracteres.</string>
|
||||
<string name="enterPhoneNumberAndText">Introduce un número de teléfono y un mensaje de texto.</string>
|
||||
<string name="onOff">On/Off</string>
|
||||
<string name="useTextToSpeechOnNormalSummary">Usar TextToSpeech en un perfil normal</string>
|
||||
<string name="useTextToSpeechOnVibrateSummary">Usar TextToSpeech en un perfil vibración</string>
|
||||
@ -358,12 +358,12 @@
|
||||
<string name="networkAccuracy">Red exactitud [m]</string>
|
||||
<string name="minimumTimeForLocationUpdates">Tiempo mínimo para cambio en milisegundos para actualizar posición</string>
|
||||
<string name="timeForUpdate">Tiempo para actualizar [milisegundos]</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto. [uniqueid] - el número único de su dispositivo [serialnr] - el número de serie de su dispositivo [latitude] - su latitud [longitude] - su longitud [phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante [d] - Dia del mes, 2 digitos con cero al comienzo [m] - número del mes, 2 digitos con cero al comienzo [Y] - Número del año, 4 digitos [h] - Hora, formato 12 horas con cero al comienzo [H] - Hora, formato 24 horas con cero al comienzo [i] - Minutos con cero al comienzo [s] - Segundos con cero al comienzo [ms] - milisegundos [notificationTitle] - Título de la última notificación [notificationText] - Texto de la última notificación</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (< Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación</string>
|
||||
<string name="screenRotationAlreadyEnabled">Rotación del monitor todavia esta activado.</string>
|
||||
<string name="screenRotationAlreadyDisabled">Rotación del monitor todavia esta desactivado.</string>
|
||||
<string name="needLocationPermForWifiList">Se puede usar la lista de wifis conocidos para determinar los sitios en los cuales estuvo. Por eso el permiso de localización es necesario para cargar la lista de wifis. Si quiere elegir uno de la lista tiene que conceder el permiso. En caso contrario todavia puede introducir un nombre wifi manualmente.</string>
|
||||
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlar conexiones de la app Wireguard</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Enviar configuración y procotolo al desarollador (vía email).</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Adjuntar configuración y procotolo.</string>
|
||||
<string name="rootExplanation">Necesita permiso root para esta función. Después encienda la función \"ejecutar regla manualmente\" para presentar el permiso superuser dialogo. Es necesario elegir \"siempre permitir root para esta app\". En caso contrario la regla no puede funcionar en segundo plano.</string>
|
||||
<string name="helpTextRules">Todas las condiciones están \"Y\"-conectadas. La regla solo va a aplicarse cuando todas las condiciones se aplican. Si quiere \"O\", cree otra regla.</string>
|
||||
<string name="timeBetweenNoiseLevelMeasurementsSummary">Segundos entre dos ensayos de nivel de ruido</string>
|
||||
@ -470,9 +470,9 @@
|
||||
<string name="noMapsApplicationFound">Parece que no hay una aplicación de mapa en su dispositivo.</string>
|
||||
<string name="soundMode">Modo de sonido de llamada.</string>
|
||||
<string name="showIcon">Monstrar icono</string>
|
||||
<string name="showIconWhenServiceIsRunning">Monstrar icono cuando el servicio esta activo (ocultando solo funciona antes Android 7)</string>
|
||||
<string name="showIconWhenServiceIsRunning">Monstrar icono cuando el servicio esta activo (ocultando solo funciona antes Android 7). Si está en una versión superior, vaya a configuración del sistema, luego Automatización, luego notificaciones y deshabilite \"Service notification\".</string>
|
||||
<string name="currentVolume">Volumen actual</string>
|
||||
<string name="volumeTest">Prueba de volumen</string>
|
||||
<string name="volumeTest">Calibrado de volumen</string>
|
||||
<string name="permissionsTitle">Permisos necesarios</string>
|
||||
<string name="disabledFeatures">Funciones desactivadas</string>
|
||||
<string name="invalidDevice">Dispositivo no valido.</string>
|
||||
@ -547,7 +547,7 @@
|
||||
<string name="permissionsExplanationSmall">Para activar la función que será usada, mas permisos son necesarios. Cliquee continuar para los requisitos.</string>
|
||||
<string name="storeSettings">Leer y guardar configuración.</string>
|
||||
<string name="featuresDisabled">CUIDADO: Funciones estan desactivadas, Automation esta en modo limitado. Cliquee aqui para mas informacion.</string>
|
||||
<string name="volumeTesterExplanation">Para calcular un valor dB para determinar el nivel del ruido de fondo tiene que especificar un valor de referencia fisico. Por favor lea el articulo en Wikipedia para mas información. Este valor será probablemente diferente para todos los dispositivos. Mueva el regulador para cambiar el valor. Cuanto mas alto el valor de referencia menos será el valor dB. Las mediciónes se harán cada %1$s segundos y el resultado aparecerá abajo. Presione atrás cuando encuentre un valor indicado.</string>
|
||||
<string name="volumeCalibrationExplanation">Para calcular un valor dB para determinar el nivel del ruido de fondo tiene que especificar un valor de referencia fisico. Por favor lea el articulo en Wikipedia para mas información. Este valor será probablemente diferente para todos los dispositivos. Mueva el regulador para cambiar el valor. Cuanto mas alto el valor de referencia menos será el valor dB. Las mediciónes se harán cada %1$s segundos y el resultado aparecerá abajo. Presione atrás cuando encuentre un valor indicado.</string>
|
||||
<string name="systemSettingsNote1">El permiso para cambiar ajustes del OS es necesario (incluso cosas simples como activar bluetooth o wifi). Despues de cliquear continuar una ventana aparecerá en la cual tiene que activar eso para Automation. Entonces cliquee el boton atrás.</string>
|
||||
<string name="systemSettingsNote2">Mas permisos serán requeridos en un segundo dialogo luego.</string>
|
||||
<string name="appRequiresPermissiontoAccessExternalStorage">Automation necesita acceso al almacenamiento externo para leer su configuración y reglas.</string>
|
||||
@ -578,7 +578,7 @@
|
||||
<string name="settingsReferringToRestrictedFeatures">Su configuración y/o reglas actualmente referencian caracteristicas no-libres no seran proveidas en la versión F-Droid. Esto incluye determinar su actual actividad fisica.</string>
|
||||
<string name="filesHaveBeenMovedTo">Automation ahora usa otra ruta para guardar sus archivos. Todos sus archivos de Automation fueron desplazados aqui: \"%s\". El permiso del almacenamiento externo todavia no es necesario; puede revocarlo. Sera eliminado en una futura versión.</string>
|
||||
<string name="newsOptIn">Quiere recibir noticias (solo importantes) en la pantalla principal? Estas serán descargadas de la pagina del desarollador. No habrán notificaciones inoportunas, solo un texto en la pantalla principal cuando abra la app.</string>
|
||||
<string name="filesStoredAt">Config y archivos de log seran guardados en el directorio %1$s. Cliquee en este texto para abrir un administrador de archivos. Desafortunadamente solo funciona en un dispositivo rooted. PARA OTROS DISP.: Simplemente use el boton para crear un backup.</string>
|
||||
<string name="filesStoredAt">Config y archivos de log seran guardados en el directorio %1$s. Cliquee en este texto para abrir un administrador de archivos. Desafortunadamente solo funciona en un dispositivo rooted.\n\nPARA OTROS DISP.: Simplemente use el boton para crear un backup.</string>
|
||||
<string name="notificationTriggerExplanation">Esta condición responde a todas las aplicaciones que abren o cierran notificaciones en el areal notificaciones. Puedes especificar otra aplicación de que la notificación tiene que venir. Si no la notificación puede originarse de cualquier app. Tambien puedes especificar strings que (/no) tienen que estar en en titulo o el texto de la notificación. La comparación es insensible a minúsculas y mayúsculas.</string>
|
||||
<string name="alwaysPlayExplanation">Si este ajuste esta activo el sonido será reproducido siempre. Si esta inactivo el sonido solo será reproducido si su dispositivo ni esta en mute ni en vibración. Pero si esta activo cambiará el volumen. Tambien si su dispositivo esta en el modo timbre el volumen multimedia no será cambiado por ejemplo. En resumen si el volumen multimedia esta en mute no escuchará nada.</string>
|
||||
<string name="shareConfigAndLogExplanation">Esto comenzará un nuevo email con su config y los archivos de log adjunto como archivo zip. No será enviado automaticamente. Todavia tiene que cliquear \"enviar\". Tambien puede cambiar el receptor a si mismo por ejemplo.</string>
|
||||
@ -588,10 +588,138 @@
|
||||
<string name="vibrate">Vibrar</string>
|
||||
<string name="test">Probar</string>
|
||||
<string name="VibrateExplanation">Elija la duración de la vibración, seguido de un coma y una duración de una pausa. Puedes concatenar tantos como quiere. Separelos con comas tambien. Por ejemplo el patrón 100,500,500,1000,100 va a vibrar 100, esperar 500, vibrar 500, esperar 1000, vibrar 100 ms. Si cree que una vibración está perdida, pruebe incrementar la pausa antes de esta vibración.</string>
|
||||
<string name="pleaseEnterValidVibrationPattern">Por favor introduzca un patrón de vibración válido.</string>
|
||||
<string name="pleaseEnterValidVibrationPattern">Por favor inserte un patrón de vibración válido.</string>
|
||||
<string name="tabsPlacementSummary">Elija done la barra de tabs está puesto.</string>
|
||||
<string name="intentDataComment">Si su parametro es de tipo Uri y especifica \"IntentData\" como nombre (minúscula/mayáscula no es importante), el parametro no está añadido como un parametro normal con puExtra(), pero estará añadido al intent con setData().</string>
|
||||
<string name="locationEngineDisabledLong">Desafortunadamente su posición todavia no puede ser determinada. Gratitud va para Google por su sabiduria y amabilidad infinita.\n\nDejenme explicarselo mas. Comenzando con Android 10 un nuevo permiso se introdujo que es necesario para determinar la posición en el fondo (que es necesario para una app como esta). Aunque lo considero una buena idea, conlleva a una chicana para desarolladores.\n\nCuando se esta desarrollando una app se puede intentar calificar para este permiso mientras se sigue un catalogo de condiciones. Desafortunadamente nuevas versiones de mi app fueron rechazadas por un periodo de trés meses. Cumplé todas las condiciones, pero Google\'s mierda servicio para desarolladores afirmó que no. Despues de presentar pruebas, que cumplí con todo, recibí una respuesta de \"No puedo ayudarte mas.\". En algun momento me rendí.\n\nComo consecuencia la version Google Play todavia no sabe usar la locación como una condición. Mi única alternativa fue remover la applicación de Google Play.\n\nLo siento mucho, pero hicé todo lo posible para discutir con un support que no sabe aprobar la prueba de Turing repetidamente.\n\nLa noticia positiva: Usted todavia puede tener todo!\n\nAutomation ahora es open source y se puede encontrar en F-Droid. Es un app store que se preocupa por su privacidad - en vez de solo simular eso. Simplemente guarde su configuración, desinstale la app, instale la de F-Droid, restaure su configuración - terminado.\n\nCliquee aqui para averiguar más:</string>
|
||||
<string name="startAppChoiceNote">Aqui tiene 2 opciones generales:\\n\\n1. Puede encender un programa seleccionando un activity. Imagine eso como preseleccionar una pantalla/ventana especifica de una aplicación. Tenga en cuenta que no siempre funcionará. Eso es porque las ventanas de una app pueden interactuar entre ellas, por ejemplo dar parametros. Si se abre una ventana especifica directamente esta interacción todavia no ha ocurrido y la ventana se podría cerrar al instante (por lo tanto nunca será presentada). Pruebe esto sin embargo! Puede introducir una trayectoria de una activity manualmente, pero es recomendable usar el boton \"Elegir\". Si decide introducir la trayectoria de la app manualmente en la casilla de arriba y la trayectoria completa de una activity en la de abajo.\\n\\n2.Elección con action\\nContrariamente a elegir una ventana especifica, tambien puede encender una app con un action. Es similar a llamar \"Queria xyz\" y si hay una app que le puede ayudar a usted sera encendida. Un ejemplo bueno seria \"abrir browser\" - podria tener multiples (una normalemente es el valor predeterminado). Usted necesita introducirlo manualmente, PackageName es opcional aqui. Tenga en cuenta las variables no seran resueltas. Si por ejemplo quiere encender la camara usando \"MediaStore.ACTION_IMAGE_CAPTURE\" no va a funcionar. Tiene que mirar en la documentación de Android y usar el valor real de esta variable que - en este ejemplo - seria \"android.media.action.IMAGE_CAPTURE\".</string>
|
||||
<string name="tones">Sonidos</string>
|
||||
<string name="dnd">No interrumpir</string>
|
||||
<string name="donate">Donar</string>
|
||||
<string name="notice">Nota</string>
|
||||
<string name="deviceOrientation">Orientación</string>
|
||||
<string name="tolerance">Tolerancia</string>
|
||||
<string name="orientationAzimuth">" Acimut:"</string>
|
||||
<string name="turnScreenOff">apagar pantalla</string>
|
||||
<string name="turnScreenOn">encender pantalla</string>
|
||||
<string name="actionSetBluetoothTethering">Enrutador Bluetooth</string>
|
||||
<string name="actionTurnBluetoothTetheringOn">activar enrutador Bluetooth</string>
|
||||
<string name="actionTurnBluetoothTetheringOff">desactivar enrutador Bluetooth</string>
|
||||
<string name="miscellaneous">Misceláneo</string>
|
||||
<string name="dndOff">No interrumpir apagado</string>
|
||||
<string name="dndPriority">Permitir notificaciones prioritarias</string>
|
||||
<string name="dndAlarms">Permitir alarmas</string>
|
||||
<string name="dndNothing">Permitir nada</string>
|
||||
<string name="unknown">desconocido</string>
|
||||
<string name="orientation">Orientación</string>
|
||||
<string name="turnScreenOnOrOff">Activar o desactivar pantalla</string>
|
||||
<string name="mustApply">Debe aplicar</string>
|
||||
<string name="deviceOrientationTimeAcceptIntervalTitle">Frecuencia de señal</string>
|
||||
<string name="deviceOrientationSettings">Configuración del orientación del dispositivo</string>
|
||||
<string name="android.permission.BIND_DEVICE_ADMIN">Administrador del dispositivo</string>
|
||||
<string name="orientationRoll">Rotación:</string>
|
||||
<string name="orientationPitch">Inclinación:</string>
|
||||
<string name="wouldCurrentlyApply">¿Se aplicaría actualmente?</string>
|
||||
<string name="repeatEveryXseconds">Repetir cada x segundos</string>
|
||||
<string name="repeatEveryXsecondsWithVariable">repetir cada %1$s segundos</string>
|
||||
<string name="permissionsRequiredNotAvailable">Sus reglas requerían permisos que no se pueden solicitar a este tipo instalado de Automation.</string>
|
||||
<string name="automationNotificationsIgnored">Si no elige una aplicación específica, sino que elige \"Cualquier aplicación\", las notificaciones de Automatización se ignorarán para evitar bucles.</string>
|
||||
<string name="enterRepetitionTime">Debe insertar un valor positivo no decimal para el tiempo de repetición.</string>
|
||||
<string name="elementSkipped">No se pudo leer un elemento del archivo de configuración. El archivoo puede haber sido creado por una versión más reciente del programa.</string>
|
||||
<string name="enterValidNumbersIntoAllFields">Inserte números válidos en todos los campos.</string>
|
||||
<string name="toleranceOf180OnlyAllowedIn2Fields">Se permite una tolerancia de 180 solo para 2 campos de tolerancia, no para todos los 3. De lo contrario, el disparador SIEMPRE se aplicaría.</string>
|
||||
<string name="triggerWrong">Hay algo mal con este condición. No se pudo cargar correctamente.</string>
|
||||
<string name="deviceOrientationTimeAcceptIntervalSummary">Aceptar nuevas señales de movimiento cada x milisegundos</string>
|
||||
<string name="deviceAdminNote">Se requieren permisos de administrador de dispositivo para al mens 1 reglas que haya creado.</string>
|
||||
<string name="dndRemarks">El ajuste fino (como permitir llamadas telefónicas, elegir números específicos, etc.) solo se puede hacer desde la configuración del sistema.</string>
|
||||
<string name="btTetheringNotice">Se confirma que esta función funcionará hasta Android 8.0. A partir de alguna versión superior deja de funcionar, pero debido a la falta de dispositivos físicos no puedo decir cuál es. En Android 11 definitivamente ya no funciona. Si tiene una versión intermedia, hágamelo saber si está funcionando o no.</string>
|
||||
<string name="deviceIsInCertainOrientation">el dispositivo esta en una orientación determinada</string>
|
||||
<string name="explanationDeviceOrientationDirection">Si la casilla de verificación está marcada, significa que el dispositivo debe estar en la orientación que especifique. Si no está marcado, cualquier orientación que NO coincida con sus criterios servirá.</string>
|
||||
<string name="silentTriggersDnd">OBSERVACIÓN: El modo silencioso a menudo activa No-Interrumpir en dispositivos más nuevos. Si eso sucede en su dispositivo, le recomiendo usar el modo normal en su lugar y reducir todos los volúmenes a cero.</string>
|
||||
<string name="wifiApi30">Porque Google arruinó otra parte de Android, a partir de API 30 solo se puede mostrar los wifi actualmente visibles, ya no todos que su positivo tiene conectados.</string>
|
||||
<string name="smsDialogNotice">Si no ha utilizado una acción de envío de sms en este programa antes, Android puede mostrar un diálogo de confirmación adicional, pidiéndole que permita el envío de mensajes. Debe seleccionar la casilla de verificación \"permitir siempre\" y confirmar si desea que esta acción funcione en segundo plano. Se recomienda ejecutar esta regla manualmente una vez para provocar este diálogo de confirmación.</string>
|
||||
<string name="deviceOrientationExplanation">Cuando mueva su dispositivo, los siguientes números se actualizarán. Lo que puede ver allí, es la orientación actual de su dispositivo medida en grados. Si está en la orientación deseada, haga clic en el botón Aplicar para copiar los valores actuales en los campos deseados. Debido a que alcanzar esta orientación exacta nunca más es muy poco probable, también deba ingresar a una tolerancia. Esta es la cantidad de grados a los que la orientación puede desviarse en cualquier dirección. 15° resultará en un ángulo total de 30°, 15° en todas las direcciones. Si solo le importa un eje específico, especifique una tolerancia de 180° para los otros dos.</string>
|
||||
<string name="profileNotActive">el perfil %1$s no está activo</string>
|
||||
<string name="profileActive">el perfil %1$s está activo</string>
|
||||
<string name="checkSettings">Comprobar la configuración</string>
|
||||
<string name="needsToBeActive">Necesita estar activo</string>
|
||||
<string name="recommendedForBetterReliability">Recomendado para una mejor fiabilidad</string>
|
||||
<string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Excluir de la optimización de la batería</string>
|
||||
<string name="profileTriggerCheckSettings">Si esta casilla de verificación no está desactivada, solo se marcará si el perfil seleccionado ha sido el último en activarse. No importa si alguna configuración relacionada con el audio se ha cambiado externamente.\nSin embargo, si la casilla de verificación está habilitada, la configuración de audio actual realmente debe ser como se define en el perfil. CUIDADO: La comprobación del archivo de tono de llamada no es compatible actualmente, todavía.</string>
|
||||
<string name="ruleXIsUsingProfileY">No se puede eliminar este perfil. La regla %1$s hace referencia al perfil %2$s.</string>
|
||||
<string name="profileCouldNotBeDeleted">No se pudo eliminar el perfil.</string>
|
||||
<string name="noRepetition">sin repetición</string>
|
||||
<string name="usingAuthentication">uso de la autenticación</string>
|
||||
<string name="toNumber">a número</string>
|
||||
<string name="message">mensaje</string>
|
||||
<string name="onDays">en días</string>
|
||||
<string name="notSet">no configurado</string>
|
||||
<string name="takeLauncherActivity">Buscar automaticamente</string>
|
||||
<string name="pickActivityManually">Eligir manualmente</string>
|
||||
<string name="launcherOrManualExplanation">Modo facil: Automation puede probar identifcar el launcher activity del programa automaticamente.\nAlternativamente puede eligir una de las activities del programa manualmente.\nCual variante queria?</string>
|
||||
<string name="launcherNotFound">No se puede encontrar una launcher activity. Tiene que elegir una manualmente.</string>
|
||||
<string name="info">Info</string>
|
||||
<string name="createNotification">Crear notificación</string>
|
||||
<string name="enterTitle">Inserte un título.</string>
|
||||
<string name="enterText">Inserte un texto.</string>
|
||||
<string name="profileWasNotFound">El perfil utilizado en esta regla ya no parece existir. Se ha seleccionado el primero alfabéticamente.</string>
|
||||
<string name="notificationCloseActionExplanation">Si no especifica ningún criterio, esta acción cerrará TODAS las notificaciones. Por lo tanto, se recomienda al menos especificar criterios para al menos 1 de la aplicación, título o texto.</string>
|
||||
<string name="closeNotifications">Cerrar notificación(es)</string>
|
||||
<string name="comparisonCaseInsensitive">Las comparaciones se realizan sin distinción de mayúsculas y minúsculas</string>
|
||||
<string name="profileWarning">La configuración que realice aquí puede hacer que ya no note ciertas cosas de su teléfono. Incluso puede silenciar su alarma de despertar. Así que hagas lo que hagas, se recomienda que lo pruebes.</string>
|
||||
<string name="ifString">si</string>
|
||||
<string name="on">encendido</string>
|
||||
<string name="off">apagado</string>
|
||||
<string name="unlocked">desbloqueado</string>
|
||||
<string name="play">reproducir</string>
|
||||
<string name="pause">pausar</string>
|
||||
<string name="previous">ultimo</string>
|
||||
<string name="next">proximo</string>
|
||||
<string name="stop">parar</string>
|
||||
<string name="android.permission.MEDIA_CONTENT_CONTROL">Controlar la reproducción de medios</string>
|
||||
<string name="actionMediaControl">Controlar la reproducción de medios</string>
|
||||
<string name="pleaseSelectActionValue">Por favor elije una acción!</string>
|
||||
<string name="playPause">alternar reproducir/pausar</string>
|
||||
<string name="selectCommand">Elije el comando</string>
|
||||
<string name="screenState">Estado de la pantalla</string>
|
||||
<string name="selectDesiredState">Elije el estado deseado</string>
|
||||
<string name="controlCenter">Centro de control</string>
|
||||
<string name="screenIs">pantalla esta %1$s</string>
|
||||
<string name="sendEmailToDev">Enviar email al desrollador</string>
|
||||
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Debido a la infinita sabiduría de Google, la última versión de Android en la que se sabe que funciona esta función es %1$s. Puede configurarlo, pero probablemente no tendrá ningún efecto.</string>
|
||||
<string name="emailContactNotice">El correo electrónico es mi método preferido de contacto para informar errores, hacer preguntas o hacer propuestas. Vaya al centro de control para obtener más información.</string>
|
||||
<string name="actionMediaControlNotice">Ten en cuenta que esta acción puede no funcionar con TODOS los jugadores. E incluso si lo hace, no todos los botones funcionan necesariamente.</string>
|
||||
<string name="musicPlaying">Musica esta reproduciendo</string>
|
||||
<string name="selectParameters">Elije parametros</string>
|
||||
<string name="musicIsPlaying">musica esta reproduciendo</string>
|
||||
<string name="musicIsNotPlaying">musica no esta reproduciendo</string>
|
||||
<string name="musicCheckFrequencyTitle">Frecuencia de los controles</string>
|
||||
<string name="musicCheckFrequencySummary">Millisegundos entre controles</string>
|
||||
<string name="musicPlayingDetection">Musica tocando deteción</string>
|
||||
<string name="locationNotWorkingOn12">Obtener la locación no parece estar funcionando en dispositivos Android 12 actualmente. Si no está funcionando para ti, lo siento. Intentaré arreglar esto tan pronto como conozca la causa. Así que si la rosquilla no deja de girar, ya sabes por qué.</string>
|
||||
<string name="profileXrequiresThis">El perfil \"%1$s\" requiere esto.</string>
|
||||
<string name="lastProfile">Último perfil:</string>
|
||||
<string name="queryAllPackages">Obtener una lista de las aplicaciones instaladas</string>
|
||||
<string name="timeFrameDaysHint">Si utiliza un marco de tiempo que se extiende más allá de la medianoche, también debe seleccionar el día siguiente si desea que la condición se aplique después de la medianoche.</string>
|
||||
<string name="featureNotInGooglePlayVersion">Esta función ya no está disponible en la versión de Google Play.\n\nTodo de vez en cuando Google intimida a los desarrolladores. Si desea seguir utilizando ciertas funciones, debe presentar documentos. Desafortunadamente, hay un 99% de posibilidades de que el papeleo sea rechazado. Es más o menos como en el cómic/la película de Astérix.\n\nHe pasado semanas discutiendo con ellos sobre casos como ese en el pasado, pero seguí recibiendo rechazos, ya sea por bots o personas que son tan inteligentes como los bots. En el puedo decidir entre que la aplicación se elimine de Play Store por completo o eliminar la función.\n\nPor favor, considere usar la versión APK de mi sitio web o la de F-Droid si necesita esas características.</string>
|
||||
<string name="startActivityInsertManually">Esta limitación se refiere solo a la selección de una aplicación, no al inicio real. Por lo tanto, aún puede ingresar el nombre de una aplicación manualmente si lo conoce.</string>
|
||||
<string name="deviceStarts">Dispositivo esta enciendo</string>
|
||||
<string name="serviceStarts">Servicio esta enciendo</string>
|
||||
<string name="deviceHasJustStarted">el dispositivo justamente ha encendido</string>
|
||||
<string name="serviceHasJustStarted">el servicio justamente ha encendido</string>
|
||||
<string name="emailPretext">Si tiene un problema, sugerencia o pregunta, escriba algo en el correo electrónico. No solo envíeme los archivos con el cuerpo de correo predeterminado. Ignoraré todo eso a menos que ya estemos en una conversación.</string>
|
||||
<string name="lockedCommentScreenMustBeOff">Cualquier estado de bloqueo solo se detectará si la pantalla está apagada.</string>
|
||||
<string name="lockedWithSecurity">bloqueado (con PIN, etc.)</string>
|
||||
<string name="lockedWithoutSecurity">bloqueado (solo deslizar, sin PIN)</string>
|
||||
<string name="selectBroadcast">Seleccionar broadcast</string>
|
||||
<string name="broadcastsShowSuggestions">Mostrar sugerencias</string>
|
||||
<string name="broadcastReceivedTitle">Broadcast recibido</string>
|
||||
<string name="broadcastReceived">broadcast recibido</string>
|
||||
<string name="broadcastNotReceived">broadcast no recibido</string>
|
||||
<string name="broadcastExplanation">Esta acción permite enviar una transmisión a través del sistema de mensajes de Android. Esto no es visible para el usuario, pero las aplicaciones que se han registrado para ciertas transmisiones pueden responder a ello.</string>
|
||||
<string name="sendBroadcast">Enviar broadcast</string>
|
||||
<string name="enterBroadcast">Introduzca una acción de broadcast.</string>
|
||||
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
|
||||
<string name="logsExplanation">Para evitar el uso innecesario del almacenamiento, los registros no se guardan de forma predeterminada. Entonces, si tiene un problema, active primero la configuración de inicio de sesión y establezca el nivel de registro en 5. A continuación, reproduzca el problema. Solo entonces se pueden adjuntar registros.</string>
|
||||
<string name="directionStringDoesNotContain">no contiene</string>
|
||||
</resources>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user