Compare commits
534 Commits
v1.6.31
...
3e29054f82
Author | SHA1 | Date | |
---|---|---|---|
3e29054f82 | |||
9d5f0a3cef | |||
695b1f2481 | |||
d7357b0b0f | |||
e272338cc6 | |||
3dd84220a3 | |||
4bc2781ee7 | |||
62bfbbb064 | |||
31d167a93f | |||
500610fb98 | |||
5ca7295c30 | |||
e2027a457a | |||
6c31b67b14 | |||
04fe674cf6 | |||
17b3b8fafc | |||
0d38c8bbe0 | |||
f7ff8a38e1 | |||
b7677bdcce | |||
1ff4a15818 | |||
bd42507521 | |||
fe924f6fe9 | |||
dfe8594f06 | |||
553d14b05f | |||
b38ca31df5 | |||
6e566c664d | |||
8c4b75232e | |||
4521bc7d4e | |||
eaecf63724 | |||
ec62b91449 | |||
223cca442d | |||
f3613f8eb0 | |||
8b193aa89c | |||
58ec35aae5 | |||
c61c5ba14c | |||
d75cf137ba | |||
5e3d268815 | |||
3bcf90277f | |||
81a205a8db | |||
97a3344e81 | |||
cd47b33449 | |||
2ba25a9e65 | |||
d2606b72cd | |||
584495ef61 | |||
9b28aeef8b | |||
b6bf31589a | |||
67238bd2f0 | |||
5f278a6ba0 | |||
a21f90acb5 | |||
5f8ed5765a | |||
605f85d215 | |||
21f4a7fd5c | |||
2219164869 | |||
a8646ef61d | |||
f641de9893 | |||
bca8b44ad6 | |||
c34dfa4af4 | |||
38644cee28 | |||
47898e84ea | |||
ac74b52aed | |||
3f76813e80 | |||
1b8dc5de5f | |||
3c8c0f14f2 | |||
6e73c74b60 | |||
9ead47bdf7 | |||
e4828a9720 | |||
4f971e8a1b | |||
34fbc1d005 | |||
b72049defc | |||
54f3cc84c4 | |||
7884358564 | |||
f24c9f99dc | |||
64b97c650d | |||
9daf4c4747 | |||
94f7936c4a | |||
02f7b642cf | |||
8d10bf05af | |||
8c0cee9589 | |||
6b23bd6733 | |||
1a60c88f35 | |||
3312d99177 | |||
ea01806915 | |||
36173f2fcb | |||
4c66fe906e | |||
60cfa150b5 | |||
bd2231b075 | |||
158f5f2e04 | |||
f1315dc742 | |||
28aa0c3e4b | |||
6b9dbca7ab | |||
291e0c41af | |||
c9eedd5d87 | |||
2470321e15 | |||
d85a199117 | |||
b047cde4ea | |||
9a1796f2eb | |||
7e8a6b121e | |||
810c7488c4 | |||
8af24695fd | |||
533a9bf54d | |||
8653e4853b | |||
c464a9d71f | |||
26e4851c0d | |||
11f0ee25bf | |||
a76cafc6e2 | |||
bd2920e6d9 | |||
5caf33b45d | |||
6a74d070eb | |||
eba02ade08 | |||
394effea36 | |||
4d51f1890a | |||
a8b2c3bf7d | |||
d1c6abaa91 | |||
587ed5803e | |||
49d272be1e | |||
d9e54c7780 | |||
170dbbc7e8 | |||
3fc1dd1a26 | |||
0acb52099c | |||
b6015a3f2e | |||
ae1e767fa6 | |||
6e12e71133 | |||
e4e3faea06 | |||
7c42250e13 | |||
ebb0724b28 | |||
a7ae0c6588 | |||
e5433bf2ec | |||
fd8ffd4f7d | |||
f49455712a | |||
132f64114e | |||
27e9b3e0d1 | |||
a6c6dfc6ba | |||
6a7875cc61 | |||
6f80caa1c6 | |||
a9646cbf28 | |||
52edfa32df | |||
ca81e6a7bd | |||
49e4c20ab6 | |||
ab98b4d1db | |||
6b32301894 | |||
d9cdfab828 | |||
62a8723344 | |||
2b69938ad5 | |||
c42f65bd3a | |||
ad0d9962b5 | |||
58f24953f3 | |||
3d212456e6 | |||
fff0a28310 | |||
48da91cb40 | |||
98df050f42 | |||
93cb72ac2f | |||
713228c06e | |||
c868d45896 | |||
4abce042eb | |||
62034e1b10 | |||
135f4594be | |||
900aaf3c8c | |||
5baa40ed59 | |||
759e8076c3 | |||
17b9f19dc2 | |||
374a5c4263 | |||
2fd79140cb | |||
a0910e620f | |||
475c1719d7 | |||
baa39c7a77 | |||
e11cc09da2 | |||
eff04037a1 | |||
b73a45f4cd | |||
fad6050c7a | |||
8a00529991 | |||
1d7cf00b94 | |||
d74e2eae68 | |||
4f7c36c4f7 | |||
b0df3efa27 | |||
f99418fda3 | |||
e05a42f5d6 | |||
83a27dcfdb | |||
bdc89a855b | |||
7ce203a679 | |||
57bc666453 | |||
c966981eae | |||
7a05b9a95b | |||
7fdbf74906 | |||
d17e8b70fe | |||
f97bfbb732 | |||
937c6ffe1d | |||
1ecc61452f | |||
19fd2d098b | |||
d07c1a05e4 | |||
f9f9b30116 | |||
d154a3d64f | |||
eeb4f4a39e | |||
53e62068a5 | |||
922807d903 | |||
a7d294c115 | |||
2d2fd901a1 | |||
536a5e22f9 | |||
99faa2f7ef | |||
f3fac2f4e8 | |||
b3b713e454 | |||
b0d509aafe | |||
efb4919a1e | |||
7bc858fee3 | |||
647d5bd511 | |||
f1f3be56cb | |||
5856c93fc8 | |||
8201b1d4e4 | |||
ce9480d188 | |||
a69bbb1e05 | |||
16817e6f53 | |||
26ed906521 | |||
d1ca9ab56b | |||
9c76340f24 | |||
aca5572f40 | |||
944e165dd0 | |||
7f2fc4b5de | |||
cd163afc47 | |||
6179f0e9ae | |||
581cdafb87 | |||
9162bcb451 | |||
5272b56032 | |||
2361c758c9 | |||
f738e02b72 | |||
f5a3636222 | |||
bb1b3b0149 | |||
b35208b7aa | |||
b3ad72cc50 | |||
92e58149a7 | |||
c1809bd23c | |||
88a3ab8241 | |||
00f296d2d1 | |||
e84842361c | |||
efaf0ed270 | |||
7167f0c03d | |||
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 | |||
074f75ed20 | |||
d988e1f43d | |||
23502f52bb | |||
9a6083247f | |||
ba2a340bdf | |||
9e2f7c16f6 | |||
d042b3f35a | |||
220d2d316e | |||
4aa095e801 | |||
b5bd332ff5 | |||
969937f8a0 | |||
e3598cc475 | |||
e63d97be0c | |||
e60fb1535a | |||
8563234db3 | |||
448942e4e8 | |||
dcdb770d9f | |||
b5040cedb3 | |||
423839fa43 | |||
a6edab75ce | |||
cb430b957f | |||
b6a0f6dd91 | |||
bc32cbc179 | |||
d9cc604bdd | |||
db21011b7f | |||
dc35c8b7fb | |||
5a7cbfcdc9 | |||
913a37a320 | |||
14655fe55d | |||
cfc145c6c4 | |||
325bff305c | |||
4371fb56f7 | |||
6593f6c923 | |||
7fbac92360 | |||
7415830dd7 | |||
dce68d79bd | |||
397dadd8c7 | |||
c51c46707b | |||
d699285b5a | |||
cf3db22ffb | |||
f53abe2b23 | |||
ba2f96713d | |||
21d9351b2b | |||
a8bfc6f7ec | |||
71d9791603 | |||
d71177f3da | |||
eef6c3234a | |||
192142c76b | |||
9a2a0aa6a4 | |||
c18a880ad7 | |||
a845ea7c63 | |||
2d9695344b | |||
24d05e6d87 | |||
07b0513eae | |||
e445b787a9 | |||
82156059fa | |||
b976ff95b6 | |||
a4b2745b7b | |||
844be6a4a7 | |||
49a48fc371 | |||
722750b724 | |||
ab51eb3655 | |||
7b88e7a612 | |||
bb2f5c9842 | |||
883a7e8341 | |||
bfc0e3ac4f | |||
23ded3a851 | |||
6d363fd02d | |||
3c0f889db7 | |||
d018c27f0e | |||
7e36f0f32e | |||
666129de16 | |||
becdbd6546 | |||
d292988737 | |||
21ee06e9b1 | |||
f22e4854ee | |||
7182698b8a | |||
7fd8d1cfd0 | |||
943928089b | |||
f70e45701f | |||
9b33f13f66 | |||
2f3a33b1b8 | |||
6c8ca59e3f | |||
5ffb36a87f | |||
1560fd3343 | |||
a0ff8c80f0 | |||
1ea3bdaea3 | |||
f325b30917 | |||
8ce2a09b3b | |||
4a18a6ed19 | |||
9a8519d3e3 | |||
0a0399c2b0 | |||
3844079781 | |||
191ad904a3 | |||
e988cedf7c | |||
9a7f66fa22 | |||
c926c85dd0 | |||
cddd8cfac5 | |||
e57b888393 | |||
c922f8c7fc | |||
357c7f894f | |||
34091a7b73 | |||
8d26abdede | |||
8d42bb48d2 | |||
f79efa7739 | |||
d257c4ccb0 | |||
e39f0c2497 | |||
327a992cac | |||
9021b03732 | |||
514a9ae0e4 | |||
09298bce55 | |||
74f50d3e13 | |||
1946fb6b9f | |||
acc0f592d1 | |||
2e09ea1c90 | |||
769f227689 | |||
22533fcfee | |||
004ca6993a | |||
0bea81a630 | |||
88decce426 | |||
2341d714c0 | |||
34c0067736 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -145,6 +145,8 @@ fabric.properties
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/androidstudio
|
||||
|
||||
|
||||
output-metadata.json
|
||||
/app/app-release.apk
|
||||
Automation_settings.xml
|
||||
/app/googlePlayFlavor/
|
||||
/.idea/deploymentTargetDropDown.xml
|
||||
|
117
.idea/codeStyles/Project.xml
generated
Normal file
117
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,117 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
@ -8,11 +8,11 @@ android {
|
||||
defaultConfig {
|
||||
applicationId "com.jens.automation2"
|
||||
minSdkVersion 16
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 102
|
||||
versionName "1.6.30"
|
||||
versionCode 139
|
||||
versionName "1.8"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -28,11 +28,6 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
flavorDimensions "version"
|
||||
|
||||
productFlavors
|
||||
@ -40,39 +35,52 @@ android {
|
||||
googlePlayFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".googlePlay"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 33
|
||||
}
|
||||
|
||||
/*
|
||||
targetSdkVersion is kept at 28 for as long as possible.
|
||||
If raised wifi cannot be switched on or off anymore without root permissions.
|
||||
In the Google version I'm forced to raise the value regularly.
|
||||
*/
|
||||
|
||||
fdroidFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".fdroid"
|
||||
// versionNameSuffix "-fdroid"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
|
||||
apkFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".apk"
|
||||
versionNameSuffix "-apk"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
}
|
||||
lint {
|
||||
abortOnError false
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
namespace 'com.jens.automation2'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||
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'
|
||||
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
|
||||
implementation 'org.apache.commons:commons-lang3:3.0'
|
||||
|
||||
//implementation "androidx.security:security-crypto:1.0.0"
|
||||
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
|
||||
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
testImplementation 'junit:junit:4'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.jens.automation2",
|
||||
"variantName": "processGooglePlayFlavorReleaseResources",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 102,
|
||||
"versionName": "1.6.30-googlePlay",
|
||||
"outputFile": "app-googlePlayFlavor-release.apk"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -63,8 +64,21 @@
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<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-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -72,12 +86,18 @@
|
||||
<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"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@ -96,15 +116,15 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
@ -119,33 +139,64 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:exported="true"
|
||||
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=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
android:exported="true"
|
||||
android:description="@string/app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
|
||||
<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=".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=".ActivityManageActionRunExecutable" />
|
||||
<activity android:name=".ActivityManageActionWifi" />
|
||||
<activity android:name=".ActivityManageTriggerTethering" />
|
||||
<activity android:name=".ActivityManageActionWakeLock" />
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageActionMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
<activity android:name=".ActivityManageTriggerCharging" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -183,10 +234,32 @@
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
|
||||
</service>
|
||||
|
||||
<activity android:name=".ActivityPermissions" />
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
@ -196,34 +269,26 @@
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
|
||||
</service>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
android:authorities="com.jens.automation2"
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -18,7 +18,7 @@ public class MyGoogleApiClient
|
||||
public com.google.android.gms.appindexing.Action getIndexApiAction()
|
||||
{
|
||||
Thing object = new Thing.Builder()
|
||||
.setName("ActivityMainScreen Page") // TODO: Define a title for the content shown.
|
||||
.setName("ActivityMainScreen Page")
|
||||
// TODO: Make sure this auto-generated URL is correct.
|
||||
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
|
||||
.build();
|
||||
|
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,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -60,6 +61,21 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<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-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -67,12 +83,18 @@
|
||||
<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"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@ -91,15 +113,15 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
@ -114,32 +136,64 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:exported="true"
|
||||
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=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
android:exported="true"
|
||||
android:description="@string/app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
|
||||
<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=".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=".ActivityManageActionRunExecutable" />
|
||||
<activity android:name=".ActivityManageActionWifi" />
|
||||
<activity android:name=".ActivityManageTriggerTethering" />
|
||||
<activity android:name=".ActivityManageActionWakeLock" />
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageActionMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
<activity android:name=".ActivityManageTriggerCharging" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -164,6 +218,7 @@
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
@ -180,12 +235,15 @@
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
@ -194,6 +252,9 @@
|
||||
|
||||
</service>
|
||||
|
||||
<activity android:name=".ActivityPermissions" />
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
@ -202,6 +263,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -61,12 +62,24 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<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.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:icon="@drawable/crane"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@ -85,17 +98,19 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<receiver android:name=".receivers.StartupIntentReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
@ -108,33 +123,63 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:exported="true"
|
||||
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=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
android:exported="true"
|
||||
android:description="@string/app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
|
||||
<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=".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=".ActivityManageActionRunExecutable" />
|
||||
<activity android:name=".ActivityManageActionWifi" />
|
||||
<activity android:name=".ActivityManageTriggerTethering" />
|
||||
<activity android:name=".ActivityManageActionWakeLock" />
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
<activity android:name=".ActivityManageTriggerCharging" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -175,12 +220,15 @@
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
@ -189,6 +237,10 @@
|
||||
|
||||
</service>
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
android:exported="false"
|
||||
@ -197,12 +249,8 @@
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
|
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,6 +1,3 @@
|
||||
<?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">
|
||||
</manifest>
|
@ -2,25 +2,36 @@ package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.style.TabStopSpan;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Action
|
||||
{
|
||||
public static final String actionParameter2Split = "ap2split";
|
||||
Rule parentRule = null;
|
||||
|
||||
public enum Action_Enum {
|
||||
public static final String actionParameter2Split = "ap2split";
|
||||
public static final String intentPairSeparator = "intPairSplit";
|
||||
public static final String actionParameters2SeparatorInner = "a2splitInner";
|
||||
public static final String actionParameters2SeparatorOuter = "a2splitOuter";
|
||||
public static final String vibrateSeparator = ",";
|
||||
public static final String httpErrorDefaultText = "HTTP_ERROR";
|
||||
|
||||
public enum Action_Enum
|
||||
{
|
||||
setWifi,
|
||||
setBluetooth,
|
||||
setUsbTethering,
|
||||
setWifiTethering,
|
||||
setBluetoothTethering,
|
||||
setDisplayRotation,
|
||||
turnWifiOn,turnWifiOff,
|
||||
turnBluetoothOn,turnBluetoothOff,
|
||||
@ -31,13 +42,26 @@ public class Action
|
||||
enableScreenRotation,disableScreenRotation,
|
||||
startOtherActivity,
|
||||
waitBeforeNextAction,
|
||||
wakeupDevice,
|
||||
turnScreenOnOrOff,
|
||||
setAirplaneMode,
|
||||
setDataConnection,
|
||||
speakText,
|
||||
playMusic,
|
||||
controlMediaPlayback,
|
||||
setScreenBrightness,
|
||||
playSound,
|
||||
vibrate,
|
||||
createNotification,
|
||||
closeNotification,
|
||||
sendBroadcast,
|
||||
runExecutable,
|
||||
wakelock,
|
||||
setVariable,
|
||||
startPhoneCall,
|
||||
stopPhoneCall,
|
||||
copyToClipboard,
|
||||
takeScreenshot,
|
||||
setLocationService,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -50,6 +74,8 @@ public class Action
|
||||
return context.getResources().getString(R.string.actionSetBluetooth);
|
||||
case setWifiTethering:
|
||||
return context.getResources().getString(R.string.actionSetWifiTethering);
|
||||
case setBluetoothTethering:
|
||||
return context.getResources().getString(R.string.actionSetBluetoothTethering);
|
||||
case setUsbTethering:
|
||||
return context.getResources().getString(R.string.actionSetUsbTethering);
|
||||
case setDisplayRotation:
|
||||
@ -82,8 +108,10 @@ public class Action
|
||||
return context.getResources().getString(R.string.startOtherActivity);
|
||||
case waitBeforeNextAction:
|
||||
return context.getResources().getString(R.string.waitBeforeNextAction);
|
||||
case wakeupDevice:
|
||||
return context.getResources().getString(R.string.wakeupDevice);
|
||||
case turnScreenOnOrOff:
|
||||
return context.getResources().getString(R.string.turnScreenOnOrOff);
|
||||
case vibrate:
|
||||
return context.getResources().getString(R.string.vibrate);
|
||||
case setAirplaneMode:
|
||||
return context.getResources().getString(R.string.airplaneMode);
|
||||
case setDataConnection:
|
||||
@ -92,12 +120,36 @@ public class Action
|
||||
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);
|
||||
case runExecutable:
|
||||
return context.getResources().getString(R.string.runExecutable);
|
||||
case wakelock:
|
||||
return context.getResources().getString(R.string.keepDeviceAwake);
|
||||
case setVariable:
|
||||
return context.getResources().getString(R.string.setVariable);
|
||||
case startPhoneCall:
|
||||
return context.getResources().getString(R.string.startPhoneCall);
|
||||
case stopPhoneCall:
|
||||
return context.getResources().getString(R.string.endPhoneCall);
|
||||
case copyToClipboard:
|
||||
return context.getResources().getString(R.string.copyTextToClipboard);
|
||||
case takeScreenshot:
|
||||
return context.getResources().getString(R.string.takeScreenshot);
|
||||
case setLocationService:
|
||||
return context.getResources().getString(R.string.setLocationServiceCapital);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -144,112 +196,200 @@ public class Action
|
||||
{
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
if(this.getAction().equals(Action_Enum.setWifi))
|
||||
try
|
||||
{
|
||||
switch (getAction())
|
||||
{
|
||||
case 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))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setUsbTethering))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setWifiTethering))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setDisplayRotation))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setAirplaneMode))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setDataConnection))
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
break;
|
||||
case startOtherActivity:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.triggerUrl))
|
||||
{
|
||||
break;
|
||||
case triggerUrl:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.speakText))
|
||||
{
|
||||
break;
|
||||
case speakText:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.playMusic))
|
||||
{
|
||||
break;
|
||||
case playMusic:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
break;
|
||||
case controlMediaPlayback:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionMediaControl));
|
||||
break;
|
||||
case 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));
|
||||
}
|
||||
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;
|
||||
case runExecutable:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.runExecutable));
|
||||
break;
|
||||
case wakelock:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.keepDeviceAwake) + " (" + String.valueOf(getParameter1()) + ")");
|
||||
break;
|
||||
case setVariable:
|
||||
String[] variableParams = getParameter2().split(actionParameter2Split);
|
||||
String addition;
|
||||
if (variableParams.length >= 2)
|
||||
addition = " (key: " + variableParams[0] + ", value: " + variableParams[1] + ")";
|
||||
else
|
||||
addition = " (delete key: " + variableParams[0] + ")";
|
||||
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setVariable) + addition);
|
||||
break;
|
||||
case startPhoneCall:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startPhoneCall));
|
||||
break;
|
||||
case stopPhoneCall:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.endPhoneCall));
|
||||
break;
|
||||
case copyToClipboard:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.copyTextToClipboard));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.takeScreenshot));
|
||||
break;
|
||||
case setLocationService:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setLocationService) + ": " );
|
||||
switch(Integer.parseInt(getParameter2()))
|
||||
{
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_OFF:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.off));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_SENSOR_ONLY));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_BATTERY_SAVING));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_HIGH_ACCURACY));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
returnString.append(action.toString());
|
||||
}
|
||||
|
||||
if (this.getAction().equals(Action_Enum.triggerUrl))
|
||||
{
|
||||
String[] components = parameter2.split(";");
|
||||
String[] components;
|
||||
if(parameter2.contains(Action.actionParameter2Split))
|
||||
components = parameter2.split(Action.actionParameter2Split);
|
||||
else
|
||||
components = parameter2.split(";");
|
||||
|
||||
if (components.length >= 3)
|
||||
{
|
||||
returnString.append(" (");
|
||||
if(components.length >= 4)
|
||||
returnString.append(components[3]);
|
||||
else
|
||||
returnString.append(ActivityManageActionTriggerUrl.methodGet);
|
||||
returnString.append(")");
|
||||
|
||||
returnString.append(": " + components[2]);
|
||||
|
||||
if (parameter1)
|
||||
returnString.append(" using authentication.");
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingAuthentication) + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
returnString.append(" (");
|
||||
returnString.append(ActivityManageActionTriggerUrl.methodGet);;
|
||||
returnString.append(")");
|
||||
returnString.append(": " + components[0]);
|
||||
}
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.intentPairSeparator, "/"));
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
String[] components = parameter2.split(Actions.smsSeparator);
|
||||
if (components.length >= 2)
|
||||
{
|
||||
returnString.append(" to number " + components[0]);
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.toNumber) + " " + components[0]);
|
||||
|
||||
returnString.append(". Message: " + components[1]);
|
||||
returnString.append(". " + Miscellaneous.getAnyContext().getResources().getString(R.string.message) + ": " + components[1]);
|
||||
}
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.setScreenBrightness))
|
||||
{
|
||||
returnString.append(" to ");
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.to) + " ");
|
||||
|
||||
if (parameter1)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
|
||||
@ -258,13 +398,94 @@ public class Action
|
||||
|
||||
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
|
||||
if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2);
|
||||
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]);
|
||||
|
||||
if (parts.length >= 6)
|
||||
{
|
||||
if (!parts[5].equals(ActivityManageActionCloseNotification.dismissRegularString))
|
||||
{
|
||||
returnString.append(" " + String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.withButton), parts[5]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.setWifi))
|
||||
{
|
||||
if (!StringUtils.isEmpty(this.parameter2))
|
||||
{
|
||||
boolean useRoot = Boolean.parseBoolean(this.parameter2);
|
||||
if (useRoot)
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingRoot));
|
||||
}
|
||||
}
|
||||
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 (this.getAction().equals(Action_Enum.sendBroadcast))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; ").replace(Action.intentPairSeparator, "/"));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard) || this.getAction().equals(Action_Enum.setLocationService))
|
||||
; // it's completed further above already
|
||||
else if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
returnString.append(": " + Miscellaneous.getAnyContext().getResources().getString(R.string.error));
|
||||
}
|
||||
|
||||
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>();
|
||||
@ -341,18 +562,11 @@ public class Action
|
||||
* Old version. Those checks should not be necessary anymore. Also they didn't work
|
||||
* because profiles were created with names like silent, vibrate and normal.
|
||||
*/
|
||||
// if(this.getParameter2().equals("silent"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_SILENT);
|
||||
// else if(this.getParameter2().equals("vibrate"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_VIBRATE);
|
||||
// else if(this.getParameter2().equals("normal"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_NORMAL);
|
||||
// else
|
||||
// {
|
||||
|
||||
Profile p = Profile.getByName(this.getParameter2());
|
||||
if (p != null)
|
||||
p.activate(context);
|
||||
// }
|
||||
|
||||
break;
|
||||
case triggerUrl:
|
||||
triggerUrl(context);
|
||||
@ -364,23 +578,31 @@ public class Action
|
||||
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setWifi:
|
||||
Actions.setWifi(context, getParameter1(), toggleActionIfPossible);
|
||||
Actions.WifiStuff.setWifi(context, getParameter1(), getParameter2(), toggleActionIfPossible);
|
||||
break;
|
||||
case setWifiTethering:
|
||||
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setBluetoothTethering:
|
||||
Actions.BluetoothTetheringClass.setBluetoothTethering(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setDisplayRotation:
|
||||
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case startOtherActivity:
|
||||
Actions.startOtherActivity(getParameter2());
|
||||
Actions.startOtherActivity(getParameter1(), getParameter2());
|
||||
break;
|
||||
case waitBeforeNextAction:
|
||||
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
|
||||
break;
|
||||
case wakeupDevice:
|
||||
case turnScreenOnOrOff:
|
||||
if(getParameter1())
|
||||
{
|
||||
if(StringUtils.isNumeric(this.getParameter2()))
|
||||
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
|
||||
// wakeupDevice() will create a seperate thread. That'll take some time, we wait 100ms.
|
||||
else
|
||||
Actions.wakeupDevice((long)1000);
|
||||
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
@ -389,6 +611,11 @@ public class Action
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Actions.turnOffScreen();
|
||||
}
|
||||
break;
|
||||
case setAirplaneMode:
|
||||
Actions.setAirplaneMode(this.getParameter1(), toggleActionIfPossible);
|
||||
@ -402,15 +629,64 @@ 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;
|
||||
case setScreenBrightness:
|
||||
Actions.setScreenBrightness(getParameter1(), Integer.parseInt(getParameter2()));
|
||||
break;
|
||||
case vibrate:
|
||||
Actions.vibrate(getParameter1(), getParameter2());
|
||||
break;
|
||||
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;
|
||||
case runExecutable:
|
||||
String[] execParts = this.getParameter2().split(Action.actionParameter2Split);
|
||||
if(execParts.length == 1)
|
||||
Actions.runExecutable(context, this.getParameter1(), execParts[0], null);
|
||||
else if(execParts.length == 2)
|
||||
Actions.runExecutable(context, this.getParameter1(), execParts[0], execParts[1]);
|
||||
break;
|
||||
case wakelock:
|
||||
if(this.getParameter1())
|
||||
Actions.wakeLockStart(context, Long.parseLong(this.getParameter2()));
|
||||
else
|
||||
Actions.wakeLockStop();
|
||||
break;
|
||||
case setVariable:
|
||||
Actions.setVariable(this.getParameter2());
|
||||
break;
|
||||
case startPhoneCall:
|
||||
Actions.startPhoneCall(context, this.getParameter2());
|
||||
break;
|
||||
case stopPhoneCall:
|
||||
Actions.endPhoneCall(context);
|
||||
break;
|
||||
case copyToClipboard:
|
||||
Actions.copyToClipboard(context, Miscellaneous.replaceVariablesInText(this.getParameter2(), context));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
Actions.takeScreenshot();
|
||||
break;
|
||||
case setLocationService:
|
||||
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
@ -425,37 +701,58 @@ public class Action
|
||||
|
||||
private void triggerUrl(Context context)
|
||||
{
|
||||
//TODO: Check if data needs to be escaped
|
||||
String username = null;
|
||||
String password = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
String url;
|
||||
String params = null;
|
||||
|
||||
String[] components = getParameter2().split(";");
|
||||
String[] components;
|
||||
if(getParameter2().contains(Action.actionParameter2Split))
|
||||
components = getParameter2().split(Action.actionParameter2Split, -1);
|
||||
else
|
||||
components = getParameter2().split(";", -1);
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
username = components[0];
|
||||
password = components[1];
|
||||
url = components[2];
|
||||
|
||||
if(components.length >= 4)
|
||||
method = components[3];
|
||||
|
||||
if(components.length >= 5)
|
||||
{
|
||||
params = components[4];
|
||||
}
|
||||
else
|
||||
}
|
||||
else // compatibility for very old versions which haven't upgraded, yet.
|
||||
url = components[0];
|
||||
|
||||
try
|
||||
{
|
||||
url = Miscellaneous.replaceVariablesInText(url, context);
|
||||
if(!StringUtils.isEmpty(params))
|
||||
params = Miscellaneous.replaceVariablesInText(params, context);
|
||||
|
||||
Actions myAction = new Actions();
|
||||
|
||||
Miscellaneous.logEvent("i", "HTTP", "Attempting download of " + url, 4); //getResources().getString("attemptingDownloadOf");
|
||||
|
||||
/*
|
||||
Theoretically credentials could be saved, but authentication has been turned off afterwards.
|
||||
The following if clause is there to force username and password to be null.
|
||||
*/
|
||||
if(this.getParameter1()) // use authentication
|
||||
new DownloadTask().execute(url, username, password);
|
||||
new DownloadTask().execute(url, username, password, method, params);
|
||||
else
|
||||
new DownloadTask().execute(url, null, null);
|
||||
new DownloadTask().execute(url, null, null, method, params);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.errorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
|
||||
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.logErrorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,65 +768,45 @@ public class Action
|
||||
|
||||
String urlUsername = null;
|
||||
String urlPassword = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
Map<String,String> httpParams = new HashMap<>();
|
||||
|
||||
if(parameters.length >= 3)
|
||||
{
|
||||
urlUsername = parameters[1];
|
||||
urlPassword = parameters[2];
|
||||
|
||||
if(parameters.length >= 4)
|
||||
method = parameters[3];
|
||||
|
||||
if(parameters.length >= 5 && parameters[4] != null)
|
||||
{
|
||||
// has params
|
||||
String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter);
|
||||
for(String pair : paramPairs)
|
||||
{
|
||||
String[] pieces = pair.split(Action.actionParameters2SeparatorInner);
|
||||
httpParams.put(pieces[0], pieces[1]);
|
||||
}
|
||||
}
|
||||
|
||||
String response = "httpError";
|
||||
HttpGet post;
|
||||
}
|
||||
|
||||
String response = httpErrorDefaultText;
|
||||
|
||||
if(Settings.httpAttempts < 1)
|
||||
Miscellaneous.logEvent("w", "HTTP Request", Miscellaneous.getAnyContext().getResources().getString(R.string.cantDownloadTooFewRequestsInSettings), 3);
|
||||
|
||||
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
|
||||
while(attempts <= Settings.httpAttempts && response.equals(httpErrorDefaultText))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
|
||||
|
||||
// try
|
||||
// {
|
||||
// Either thorough checking or no encryption
|
||||
if(!Settings.httpAcceptAllCertificates | !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
// {
|
||||
// URL url = new URL(urlString);
|
||||
// URLConnection urlConnection = url.openConnection();
|
||||
// urlConnection.setReadTimeout(Settings.httpAttemptsTimeout * 1000);
|
||||
// InputStream in = urlConnection.getInputStream();
|
||||
// response = Miscellaneous.convertStreamToString(in);
|
||||
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
|
||||
// }
|
||||
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
|
||||
else
|
||||
// {
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
|
||||
// post = new HttpGet(new URI(urlString));
|
||||
// final HttpParams httpParams = new BasicHttpParams();
|
||||
// HttpConnectionParams.setConnectionTimeout(httpParams, Settings.httpAttemptsTimeout * 1000);
|
||||
// HttpClient client = new DefaultHttpClient(httpParams);
|
||||
//
|
||||
// client = sslClient(client);
|
||||
//
|
||||
// // Execute HTTP Post Request
|
||||
// HttpResponse result = client.execute(post);
|
||||
// response = EntityUtils.toString(result.getEntity());
|
||||
// }
|
||||
// }
|
||||
// catch (URISyntaxException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// }
|
||||
// catch (ClientProtocolException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// }
|
||||
// catch (IOException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(Settings.httpAttemptGap * 1000);
|
||||
@ -538,10 +815,9 @@ public class Action
|
||||
{
|
||||
Miscellaneous.logEvent("w", "HTTP RESULT", "Failed to pause between HTTP requests.", 5);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "HTTPS RESULT", response, 3);
|
||||
Miscellaneous.logEvent("i", "HTTPS RESULT", response, 5);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,419 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
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;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ActivityControlCenter extends Activity
|
||||
{
|
||||
final static int requestCodeImport = 1001;
|
||||
final static int requestCodeExport = 1002;
|
||||
final static int requestCodeMoreSettings = 6000;
|
||||
|
||||
final static String prefsFileName = "com.jens.automation2_preferences.xml";
|
||||
|
||||
TextView tvFileStoreLocation, tvAppVersion;
|
||||
Button bVolumeTest, bMoreSettings, bSettingsSetToDefault, bSendEmailToDev, bImportConfiguration, bExportConfiguration;
|
||||
CheckBox chkShareConfigAndLog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_control_center);
|
||||
|
||||
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityControlCenter.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
chkShareConfigAndLog = (CheckBox)findViewById(R.id.chkShareConfigAndLog);
|
||||
bSendEmailToDev = (Button) findViewById(R.id.bSendEmailToDev);
|
||||
bSendEmailToDev.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(chkShareConfigAndLog.isChecked())
|
||||
getShareConfigAndLogDialogue(ActivityControlCenter.this).show();
|
||||
else
|
||||
{
|
||||
String subject = "Automation";
|
||||
Miscellaneous.sendEmail(ActivityControlCenter.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bSettingsSetToDefault.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityControlCenter.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
bMoreSettings = (Button) findViewById(R.id.bMoreSettings);
|
||||
bMoreSettings.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityControlCenter.this, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, requestCodeMoreSettings);
|
||||
}
|
||||
});
|
||||
|
||||
bImportConfiguration = (Button) findViewById(R.id.bImportConfiguration);
|
||||
bImportConfiguration.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, requestCodeImport);
|
||||
}
|
||||
});
|
||||
|
||||
bExportConfiguration = (Button) findViewById(R.id.bExportConfiguration);
|
||||
bExportConfiguration.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, requestCodeExport);
|
||||
}
|
||||
});
|
||||
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tvAppVersion = (TextView)findViewById(R.id.tvAppVersion);
|
||||
|
||||
tvAppVersion.setText(
|
||||
"Version: " + BuildConfig.VERSION_NAME + Miscellaneous.lineSeparator +
|
||||
"Version code: " + String.valueOf(BuildConfig.VERSION_CODE) + Miscellaneous.lineSeparator +
|
||||
"Flavor: " + BuildConfig.FLAVOR
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
switch(requestCode)
|
||||
{
|
||||
case requestCodeMoreSettings: //settings
|
||||
Settings.readFromPersistentStorage(this);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
AutomationService.getInstance().serviceInterface(AutomationService.serviceCommands.reloadSettings);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(ActivityControlCenter.this))
|
||||
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
case requestCodeImport:
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Uri uriTree = data.getData();
|
||||
importFiles(uriTree);
|
||||
}
|
||||
break;
|
||||
case requestCodeExport:
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Uri uriTree = data.getData();
|
||||
exportFiles(uriTree);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void importFiles(Uri uriTree)
|
||||
{
|
||||
// https://stackoverflow.com/questions/46237558/android-strange-behavior-of-documentfile-inputstream
|
||||
|
||||
File dstRules = new File(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
File dstPrefs = new File(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
DocumentFile directory = DocumentFile.fromTreeUri(this, uriTree);
|
||||
|
||||
int applicableFilesFound = 0;
|
||||
int filesImported = 0;
|
||||
|
||||
if(directory.listFiles().length > 0)
|
||||
{
|
||||
for (DocumentFile file : directory.listFiles())
|
||||
{
|
||||
if (file.getName().equals(XmlFileInterface.settingsFileName))
|
||||
{
|
||||
applicableFilesFound++;
|
||||
|
||||
if(file.canRead())
|
||||
{
|
||||
// import rules, locations, etc.
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstRules))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.rulesImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
else if (file.getName().equals(prefsFileName))
|
||||
{
|
||||
applicableFilesFound++;
|
||||
|
||||
if(file.canRead())
|
||||
{
|
||||
// import rules, locations, etc.
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstPrefs))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.prefsImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(applicableFilesFound > 0)
|
||||
{
|
||||
if(filesImported == 0)
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if(filesImported < applicableFilesFound)
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.notAllFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if (filesImported == applicableFilesFound)
|
||||
{
|
||||
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(ActivityControlCenter.this, getResources().getString(R.string.errorReadingPoisAndRulesFromFile), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
Settings.readFromPersistentStorage(ActivityControlCenter.this);
|
||||
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if(service != null && service.isRunning)
|
||||
service.applySettingsAndRules();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
void exportFiles(Uri uriTree)
|
||||
{
|
||||
DocumentFile directory = DocumentFile.fromTreeUri(this, uriTree);
|
||||
|
||||
File srcRules = new File(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
File srcPrefs = new File(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
// Clean up
|
||||
for(DocumentFile file : directory.listFiles())
|
||||
{
|
||||
/*
|
||||
On some few users' devices it seems this caused a crash because file.getName() was null.
|
||||
The reason for that remains unknown, but we don't want the export to crash because of it.
|
||||
*/
|
||||
if(!StringUtils.isEmpty(file.getName()))
|
||||
{
|
||||
if (file.getName().equals(XmlFileInterface.settingsFileName) && file.canWrite())
|
||||
file.delete();
|
||||
else if (file.getName().equals(prefsFileName) && file.canWrite())
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
DocumentFile dstRules = directory.createFile("text/xml", XmlFileInterface.settingsFileName);
|
||||
DocumentFile dstPrefs = directory.createFile("text/xml", prefsFileName);
|
||||
|
||||
if(dstRules.canWrite() && dstPrefs.canWrite())
|
||||
{
|
||||
if(Miscellaneous.copyFileToDocumentFile(srcRules, dstRules) && Miscellaneous.copyFileToDocumentFile(srcPrefs, dstPrefs))
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.configurationExportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
if (Settings.initializeSettings(context, true))
|
||||
Toast.makeText(context, context.getResources().getString(R.string.settingsSetToDefault), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
AlertDialog getShareConfigAndLogDialogue(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.shareConfigAndLogFilesWithDev));
|
||||
alertDialogBuilder.setMessage(context.getResources().getString(R.string.shareConfigAndLogExplanation));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
File dstZipFile = new File(Miscellaneous.getAnyContext().getCacheDir() + "/" + Settings.zipFileName);
|
||||
|
||||
ArrayList<String> srcFilesList = new ArrayList<>();
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if ((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if ((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
String subject = "Automation logs";
|
||||
|
||||
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
|
||||
|
||||
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()) + Miscellaneous.lineSeparator);
|
||||
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()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if (folder != null && folder.length() > 0)
|
||||
{
|
||||
tvFileStoreLocation.setText(String.format(getResources().getString(R.string.filesStoredAt), folder));
|
||||
tvFileStoreLocation.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Uri selectedUri = Uri.parse(folder);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
|
||||
if (intent.resolveActivityInfo(getPackageManager(), 0) != null)
|
||||
{
|
||||
startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(ActivityControlCenter.this, getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ public class ActivityDisplayLongMessage extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_display_long_message);
|
||||
|
||||
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
|
||||
|
@ -9,15 +9,14 @@ import com.jens.automation2.R.layout;
|
||||
|
||||
public class ActivityHelp extends Activity
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(layout.help_text);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(layout.activity_help_text);
|
||||
|
||||
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
|
||||
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@ -43,6 +44,7 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_poi_layout);
|
||||
|
||||
instance = this;
|
||||
@ -60,11 +62,11 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
|
||||
if (!ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, ActivityMainPoi.this) || !ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityMainPoi.this))
|
||||
{
|
||||
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
|
||||
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine});
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION});
|
||||
|
||||
startActivityForResult(permissionIntent, requestCodeForPermission);
|
||||
}
|
||||
@ -106,6 +108,13 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private void buttonAddPoi()
|
||||
{
|
||||
poiToEdit = null;
|
||||
@ -189,8 +198,27 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
startActivityForResult(manageSpecificPoiIntent, 2000);
|
||||
break;
|
||||
case 1:
|
||||
AlertDialog.Builder deleteDialog = new AlertDialog.Builder(ActivityMainPoi.this);
|
||||
deleteDialog.setMessage(getResources().getString(R.string.areYouSure));
|
||||
deleteDialog.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
if(pointOfInterest.delete(Miscellaneous.getAnyContext()))
|
||||
updateListView();
|
||||
}
|
||||
});
|
||||
deleteDialog.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
deleteDialog.show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_profile_layout);
|
||||
|
||||
instance = this;
|
||||
@ -154,6 +155,13 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private AlertDialog getProfileDialog(final Profile profile)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
@ -184,8 +192,35 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
startActivityForResult(manageSpecificProfileIntent, 2000);
|
||||
break;
|
||||
case 2:
|
||||
if(profile.delete(myAutomationService))
|
||||
Rule user = profile.isInUseByRules();
|
||||
if(user == null)
|
||||
{
|
||||
AlertDialog.Builder deleteDialog = new AlertDialog.Builder(ActivityMainProfiles.this);
|
||||
deleteDialog.setMessage(getResources().getString(R.string.areYouSure));
|
||||
deleteDialog.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
if (profile.delete(ActivityMainProfiles.this))
|
||||
updateListView();
|
||||
else
|
||||
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.profileCouldNotBeDeleted), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
deleteDialog.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
deleteDialog.show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMainProfiles.this, String.format(getResources().getString(R.string.ruleXIsUsingProfileY), user.getName(), profile.getName()), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,18 +18,24 @@ import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
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;
|
||||
public static Rule ruleToEdit;
|
||||
protected static ActivityMainRules instance = null;
|
||||
|
||||
public static final int requestCodeCreateRule = 3000;
|
||||
public static final int requestCodeChangeRule = 4000;
|
||||
|
||||
public static ActivityMainRules getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
@ -42,6 +48,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_rule_layout);
|
||||
|
||||
instance = this;
|
||||
@ -52,21 +59,14 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainRules.this))
|
||||
// {
|
||||
// Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
// return;
|
||||
// }
|
||||
|
||||
ruleToEdit = null;
|
||||
Intent startAddRuleIntent = new Intent(ActivityMainRules.this, ActivityManageRule.class);
|
||||
startActivityForResult(startAddRuleIntent, 3000);
|
||||
startActivityForResult(startAddRuleIntent, requestCodeCreateRule);
|
||||
}
|
||||
});
|
||||
|
||||
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, ruleList);
|
||||
ruleListView = (ListView)findViewById(R.id.lvRuleList);
|
||||
|
||||
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, Rule.getRuleCollection());
|
||||
ruleListView.setClickable(true);
|
||||
|
||||
ruleListView.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
@ -112,7 +112,6 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
|
||||
private static class RuleArrayAdapter extends ArrayAdapter<Rule>
|
||||
{
|
||||
|
||||
public RuleArrayAdapter(Context context, int resource, ArrayList<Rule> objects)
|
||||
{
|
||||
super(context, resource, objects);
|
||||
@ -139,7 +138,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())
|
||||
@ -156,6 +155,13 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
@ -163,13 +169,13 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
if(requestCode == 3000) //add Rule
|
||||
if(requestCode == requestCodeCreateRule) //add Rule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
if(requestCode == 4000) //editRule
|
||||
if(requestCode == requestCodeChangeRule) //editRule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
@ -190,7 +196,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithRule));
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital) }, new DialogInterface.OnClickListener()
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital), getResources().getString(R.string.clone) }, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
@ -203,6 +209,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;
|
||||
}
|
||||
@ -210,13 +217,43 @@ 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);
|
||||
startActivityForResult(manageSpecificRuleIntent, 4000);
|
||||
manageSpecificRuleIntent.putExtra(intentNameRuleName, ruleThisIsAbout.getName());
|
||||
startActivityForResult(manageSpecificRuleIntent, requestCodeChangeRule);
|
||||
break;
|
||||
case 2:
|
||||
AlertDialog.Builder deleteDialog = new AlertDialog.Builder(ActivityMainRules.this);
|
||||
deleteDialog.setMessage(getResources().getString(R.string.areYouSure));
|
||||
deleteDialog.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
if(ruleThisIsAbout.delete())
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
}
|
||||
});
|
||||
deleteDialog.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
deleteDialog.show();
|
||||
break;
|
||||
case 3:
|
||||
ruleToEdit = ruleThisIsAbout;
|
||||
if(ruleToEdit.cloneRule(ActivityMainRules.this))
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -229,6 +266,11 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
public void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update RuleListView", 4);
|
||||
|
||||
ruleList.clear();
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
ruleList.add(r);
|
||||
|
||||
try
|
||||
{
|
||||
if(ruleListView.getAdapter() == null)
|
||||
@ -238,15 +280,5 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
AlarmListener.reloadAlarms();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
// AlarmManager instance not prepared, yet.
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,18 @@
|
||||
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;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -30,30 +32,30 @@ import com.jens.automation2.AutomationService.serviceCommands;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
@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, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme, bShareConfigAndLog;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration, tvFileStoreLocation;
|
||||
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)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_overview_layout);
|
||||
|
||||
activityMainScreenInstance = this;
|
||||
@ -71,18 +73,20 @@ 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);
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tvLockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bShareConfigAndLog = (Button) findViewById(R.id.bShareConfigAndLog);
|
||||
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||
bDonate = (Button)findViewById(R.id.bDonate);
|
||||
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
||||
bDonate.setVisibility(View.VISIBLE);
|
||||
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@ -94,7 +98,8 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
if (toggleService.isChecked())
|
||||
{
|
||||
startAutomationService(getBaseContext(), false);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
stopAutomationService();
|
||||
}
|
||||
@ -112,6 +117,18 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
bDonate.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
String privacyPolicyUrl = "https://server47.de/donate";
|
||||
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
@ -130,24 +147,14 @@ 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, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, 6000);
|
||||
}
|
||||
});
|
||||
|
||||
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMainScreen.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivityControlCenter.class);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
});
|
||||
|
||||
@ -184,24 +191,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
bShareConfigAndLog.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getShareConfigAndLogDialogue(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
@ -264,81 +253,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
if (Settings.initializeSettings(context, true))
|
||||
Toast.makeText(context, context.getResources().getString(R.string.settingsSetToDefault), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
AlertDialog getShareConfigAndLogDialogue(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.shareConfigAndLogFilesWithDev));
|
||||
alertDialogBuilder.setMessage(context.getResources().getString(R.string.shareConfigAndLogExplanation));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
File dstZipFile = new File(Miscellaneous.getAnyContext().getCacheDir() + "/" + Settings.zipFileName);
|
||||
|
||||
ArrayList<String> srcFilesList = new ArrayList<>();
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
String subject = "Automation logs";
|
||||
|
||||
StringBuilder emailBody = new StringBuilder();
|
||||
emailBody.append("Device details" + Miscellaneous.lineSeparator);
|
||||
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
|
||||
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Product: " + android.os.Build.PRODUCT);
|
||||
|
||||
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
|
||||
|
||||
Miscellaneous.sendEmail(ActivityMainScreen.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||
{
|
||||
return activityMainScreenInstance;
|
||||
@ -361,9 +275,14 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
activityMainScreenInstance.tvMainScreenNotePermissions.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(Miscellaneous.restrictedFeaturesConfigured())
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_fdroid) && Miscellaneous.restrictedFeaturesConfiguredFdroid())
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setText(R.string.settingsReferringToRestrictedFeatures);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setText(R.string.settingsReferringToRestrictedFeaturesInFdroid);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay) && Miscellaneous.restrictedFeaturesConfiguredGoogle())
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setText(R.string.settingsReferringToRestrictedFeaturesInGoogle);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
@ -374,14 +293,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
|
||||
if(Miscellaneous.googleToBlameForLocation(true))
|
||||
{
|
||||
// Intent intent = new Intent(AutomationService.this, ActivityDisplayLongMessage.class);
|
||||
// intent.putExtra("longMessage", getResources().getString(R.string.locationEngineDisabledLong));
|
||||
// PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
// Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
// else
|
||||
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setText(R.string.locationEngineDisabledShort);
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setVisibility(View.VISIBLE);
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setOnClickListener(new OnClickListener()
|
||||
@ -406,8 +317,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
uiUpdateRunning = true;
|
||||
activityMainScreenInstance.toggleService.setChecked(true);
|
||||
uiUpdateRunning = false;
|
||||
// if(activityMainScreenInstance.hasWindowFocus())
|
||||
// {
|
||||
|
||||
try
|
||||
{
|
||||
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
||||
@ -430,9 +340,9 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, Miscellaneous.getAnyContext())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, Miscellaneous.getAnyContext())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, Miscellaneous.getAnyContext())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, Miscellaneous.getAnyContext())
|
||||
)
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||
else
|
||||
@ -456,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
|
||||
{
|
||||
@ -464,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;
|
||||
@ -481,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;
|
||||
@ -513,36 +434,17 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
else
|
||||
activityMainScreenInstance.checkForNews();
|
||||
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk) && Settings.automaticUpdateCheck)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (Settings.lastUpdateCheck == Settings.default_lastUpdateCheck || now.getTimeInMillis() >= Settings.lastUpdateCheck + (long)(Settings.updateCheckFrequencyDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
activityMainScreenInstance.checkForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Settings.considerDone(Settings.constNewsOptInDone);
|
||||
Settings.writeSettings(Miscellaneous.getAnyContext());
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if(folder != null && folder.length() > 0)
|
||||
{
|
||||
activityMainScreenInstance.tvFileStoreLocation.setText(String.format(activityMainScreenInstance.getResources().getString(R.string.filesStoredAt), folder));
|
||||
activityMainScreenInstance.tvFileStoreLocation.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Uri selectedUri = Uri.parse(folder);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
|
||||
if (intent.resolveActivityInfo(activityMainScreenInstance.getPackageManager(), 0) != null)
|
||||
{
|
||||
activityMainScreenInstance.startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(activityMainScreenInstance, activityMainScreenInstance.getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,16 +500,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
case ActivityPermissions.requestCodeForPermissions:
|
||||
updateMainScreen();
|
||||
break;
|
||||
case 6000: //settings
|
||||
Settings.readFromPersistentStorage(this);
|
||||
|
||||
if (boundToService && AutomationService.isMyServiceRunning(this))
|
||||
myAutomationService.serviceInterface(serviceCommands.reloadSettings);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
@ -634,15 +526,23 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
{
|
||||
if (Rule.getRuleCollection().size() > 0)
|
||||
{
|
||||
if(Rule.getAmountOfActivatedRules() == 0)
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStartNoActivatedRules), Toast.LENGTH_LONG).show();
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AutomationService.isMyServiceRunning(context))
|
||||
{
|
||||
// if(myServiceIntent == null) //do we need that line?????
|
||||
myServiceIntent = new Intent(context, AutomationService.class);
|
||||
myServiceIntent.putExtra("startAtBoot", startAtBoot);
|
||||
context.startService(myServiceIntent);
|
||||
} else
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Service", context.getResources().getString(R.string.logServiceAlreadyRunning), 3);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
@ -679,6 +579,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
@ -732,6 +633,15 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
|
||||
}
|
||||
|
||||
synchronized void checkForUpdate()
|
||||
{
|
||||
if(Settings.automaticUpdateCheck)
|
||||
{
|
||||
AsyncTasks.AsyncTaskUpdateCheck updateCheckTask = new AsyncTasks.AsyncTaskUpdateCheck();
|
||||
updateCheckTask.execute(ActivityMainScreen.this);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void checkForNews()
|
||||
{
|
||||
if(Settings.displayNewsOnMainScreen)
|
||||
@ -761,4 +671,38 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
Miscellaneous.logEvent("e", "Error displaying news", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public void processUpdateCheckResult(Boolean result)
|
||||
{
|
||||
if(result && !updateNoteDisplayed)
|
||||
{
|
||||
updateNoteDisplayed = true;
|
||||
|
||||
AlertDialog.Builder updateNoteBuilder = new AlertDialog.Builder(ActivityMainScreen.this);
|
||||
updateNoteBuilder.setMessage(getResources().getString(R.string.updateAvailable));
|
||||
updateNoteBuilder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
String url = "https://server47.de/automation/";
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
startActivity(browserIntent);
|
||||
|
||||
updateNoteDisplayed = false;
|
||||
}
|
||||
});
|
||||
updateNoteBuilder.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
updateNoteDisplayed = false;
|
||||
}
|
||||
});
|
||||
updateNoteBuilder.show();
|
||||
}
|
||||
|
||||
AsyncTasks.AsyncTaskUpdateCheck.checkRunning = false;
|
||||
}
|
||||
}
|
@ -3,22 +3,32 @@ package com.jens.automation2;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.TabActivity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabHost.TabSpec;
|
||||
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainTabLayout extends TabActivity
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_tab_layout);
|
||||
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
if(Settings.tabsPlacement == 1)
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
|
||||
else
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_top);
|
||||
|
||||
TabHost tabHost = getTabHost();
|
||||
|
||||
@ -55,6 +65,7 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
|
||||
NfcReceiver.checkIntentForNFC(this, getIntent());
|
||||
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass()));
|
||||
|
@ -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,8 @@ 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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
|
||||
@ -32,11 +36,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 +48,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,431 @@
|
||||
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.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
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, etNotificationDismissalButtonText;
|
||||
Button bSelectApp, bSaveActionCloseNotification;
|
||||
Spinner spinnerTitleDirection, spinnerTextDirection;
|
||||
TextView tvSelectedApplication;
|
||||
RadioButton rbNotificationDismissSimple, rbNotificationDismissButton;
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
|
||||
final static String dismissRegularString = "p0815DismissString";
|
||||
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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);
|
||||
etNotificationDismissalButtonText = (EditText)findViewById(R.id.etNotificationDismissalButtonText);
|
||||
rbNotificationDismissSimple = (RadioButton)findViewById(R.id.rbNotificationDismissSimple);
|
||||
rbNotificationDismissButton = (RadioButton)findViewById(R.id.rbNotificationDismissButton);
|
||||
|
||||
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();
|
||||
|
||||
String dismissMethod;
|
||||
if (rbNotificationDismissSimple.isChecked())
|
||||
dismissMethod = dismissRegularString;
|
||||
else
|
||||
{
|
||||
if(StringUtils.isEmpty(etNotificationDismissalButtonText.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionCloseNotification.this, getResources().getString(R.string.enterText), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
dismissMethod = etNotificationDismissalButtonText.getText().toString();
|
||||
}
|
||||
|
||||
responseData.putExtra(ActivityManageRule.intentNameActionParameter2,
|
||||
app + Action.actionParameter2Split +
|
||||
titleDir + Action.actionParameter2Split +
|
||||
title + Action.actionParameter2Split +
|
||||
textDir + Action.actionParameter2Split +
|
||||
text + Action.actionParameter2Split +
|
||||
dismissMethod
|
||||
);
|
||||
|
||||
ActivityManageActionCloseNotification.this.setResult(RESULT_OK, responseData);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
rbNotificationDismissSimple.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||
{
|
||||
etNotificationDismissalButtonText.setEnabled(!b);
|
||||
}
|
||||
});
|
||||
|
||||
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 = "";
|
||||
|
||||
/*
|
||||
That's not reliable, yet. Last parameter may be empty, hence the method might
|
||||
be incorrectly interpreted as a text notification text.
|
||||
*/
|
||||
|
||||
if (params.length >= 6 && !params[5].equals(dismissRegularString))
|
||||
{
|
||||
rbNotificationDismissButton.setChecked(true);
|
||||
etNotificationDismissalButtonText.setText(params[5]);
|
||||
etNotificationDismissalButtonText.setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
rbNotificationDismissSimple.setChecked(true);
|
||||
etNotificationDismissalButtonText.setText("");
|
||||
etNotificationDismissalButtonText.setEnabled(false);
|
||||
}
|
||||
|
||||
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,113 @@
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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,53 @@
|
||||
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 org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionCopyToClipboard extends Activity
|
||||
{
|
||||
private Button bSaveCopyToClipboard;
|
||||
private EditText etCopyToClipboard;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_copy_to_clipboard);
|
||||
|
||||
bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard);
|
||||
etCopyToClipboard = (EditText)findViewById(R.id.etCopyToClipboard);
|
||||
|
||||
bSaveCopyToClipboard.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(StringUtils.isEmpty(etCopyToClipboard.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionCopyToClipboard.this, getResources().getString(R.string.enterText), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etCopyToClipboard.getText().toString());
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String text = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
etCopyToClipboard.setText(text);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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,75 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageActionLocationService extends Activity
|
||||
{
|
||||
RadioButton rbActionLocationServiceOff, rbActionLocationServiceSensorsOnly, rbActionLocationServiceBatterySaving, rbActionLocationServiceHighAccuracy;
|
||||
Button bActionSetLocationServiceSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_location_service);
|
||||
|
||||
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
|
||||
rbActionLocationServiceSensorsOnly = (RadioButton)findViewById(R.id.rbActionLocationServiceSensorsOnly);
|
||||
rbActionLocationServiceBatterySaving = (RadioButton)findViewById(R.id.rbActionLocationServiceBatterySaving);
|
||||
rbActionLocationServiceHighAccuracy = (RadioButton)findViewById(R.id.rbActionLocationServiceHighAccuracy);
|
||||
bActionSetLocationServiceSave = (Button) findViewById(R.id.bActionSetLocationServiceSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
int desiredState = Integer.parseInt(params[0]);
|
||||
|
||||
switch(desiredState)
|
||||
{
|
||||
case Settings.Secure.LOCATION_MODE_OFF:
|
||||
rbActionLocationServiceOff.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
rbActionLocationServiceSensorsOnly.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
rbActionLocationServiceBatterySaving.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
rbActionLocationServiceHighAccuracy.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bActionSetLocationServiceSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
if(rbActionLocationServiceOff.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_OFF));
|
||||
else if(rbActionLocationServiceSensorsOnly.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_SENSORS_ONLY));
|
||||
else if(rbActionLocationServiceBatterySaving.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_BATTERY_SAVING));
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
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 ActivityManageActionMakePhoneCall extends Activity
|
||||
{
|
||||
EditText etTargetPhoneNumber;
|
||||
Button bActionMakePhoneCallSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_make_phone_call);
|
||||
|
||||
etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber);
|
||||
bActionMakePhoneCallSave = (Button) findViewById(R.id.bActionMakePhoneCallSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
/*if(input.hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
|
||||
*/
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
etTargetPhoneNumber.setText(input.getStringExtra(ActivityManageRule.intentNameActionParameter2));
|
||||
|
||||
bActionMakePhoneCallSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(!StringUtils.isEmpty(etTargetPhoneNumber.getText()))
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter1, false);
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etTargetPhoneNumber.getText().toString());
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityManageActionMakePhoneCall.this, getResources().getText(R.string.enterPhoneNumber), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@ -27,7 +26,8 @@ public class ActivityManageActionPlaySound extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_play_sound);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_play_sound);
|
||||
|
||||
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
|
||||
etSelectedSoundFile = (EditText)findViewById(R.id.etSelectedSoundFile);
|
||||
|
@ -0,0 +1,124 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ActivityManageActionRunExecutable extends Activity
|
||||
{
|
||||
final static int PICKFILE_RESULT_CODE = 4711;
|
||||
|
||||
CheckBox chkRunExecAsRoot;
|
||||
EditText etRunExecutablePath, etRunExecutableParameters;
|
||||
Button bChooseExecutable, bSaveActionRunExec;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_run_executable);
|
||||
|
||||
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
|
||||
etRunExecutablePath = (EditText) findViewById(R.id.etRunExecutablePath);
|
||||
etRunExecutableParameters = (EditText) findViewById(R.id.etRunExecutableParameters);
|
||||
bChooseExecutable = (Button) findViewById(R.id.bChooseExecutable);
|
||||
bSaveActionRunExec = (Button) findViewById(R.id.bSaveActionRunExec);
|
||||
|
||||
bChooseExecutable.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
//Need to check for storage permissions
|
||||
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
chooseFile.setType("*/*");
|
||||
chooseFile = Intent.createChooser(chooseFile, getResources().getString(R.string.selectSoundFile));
|
||||
startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
bSaveActionRunExec.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
saveExecSettings();
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] parts = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
etRunExecutablePath.setText(parts[0]);
|
||||
|
||||
if(parts.length > 1)
|
||||
etRunExecutableParameters.setText(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void saveExecSettings()
|
||||
{
|
||||
if(etRunExecutablePath.getText().toString() == null || etRunExecutablePath.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.selectValidExecutable), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File executableFile = new File(etRunExecutablePath.getText().toString());
|
||||
if(!executableFile.exists())
|
||||
{
|
||||
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.fileDoesNotExist), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!chkRunExecAsRoot.isChecked() && !executableFile.canExecute())
|
||||
{
|
||||
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.fileNotExecutable), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Intent returnData = new Intent();
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter1, chkRunExecAsRoot.isChecked());
|
||||
|
||||
if(etRunExecutableParameters.getText() != null && !StringUtils.isEmpty(etRunExecutableParameters.getText().toString()))
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, etRunExecutablePath.getText().toString() + Action.actionParameter2Split + etRunExecutableParameters.getText().toString());
|
||||
else
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, etRunExecutablePath.getText().toString());
|
||||
|
||||
setResult(RESULT_OK, returnData);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
if(requestCode == PICKFILE_RESULT_CODE)
|
||||
{
|
||||
Uri fileUri = data.getData();
|
||||
String filePath = CompensateCrappyAndroidPaths.getPath(ActivityManageActionRunExecutable.this, fileUri);
|
||||
etRunExecutablePath.setText(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
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.text.InputType;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageActionSendBroadcast extends Activity
|
||||
{
|
||||
EditText etBroadcastToSend;
|
||||
Button bBroadcastSendShowSuggestions, bSaveSendBroadcast, bAddIntentPair;
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue;
|
||||
Spinner spinnerParameterType;
|
||||
ArrayAdapter<String> intentTypeSpinnerAdapter, intentPairAdapter;
|
||||
private static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String", "Uri" };
|
||||
private ArrayList<String> intentPairList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_send_broadcast);
|
||||
|
||||
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
|
||||
bBroadcastSendShowSuggestions = (Button)findViewById(R.id.bBroadcastSendShowSuggestions);
|
||||
bSaveSendBroadcast = (Button)findViewById(R.id.bSaveSendBroadcast);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
lvIntentPairs = (ListView) findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText) findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText) findViewById(R.id.etParameterValue);
|
||||
spinnerParameterType = (Spinner) findViewById(R.id.spinnerParameterType);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionSendBroadcast.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
|
||||
bSaveSendBroadcast.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
|
||||
String param2 = etBroadcastToSend.getText().toString();
|
||||
|
||||
if(intentPairList.size() > 0)
|
||||
{
|
||||
param2 += Action.actionParameter2Split;
|
||||
|
||||
for (String s : intentPairList)
|
||||
param2 += s + ";";
|
||||
|
||||
param2 = param2.substring(0, param2.length() - 1);
|
||||
}
|
||||
|
||||
answer.putExtra(ActivityManageRule.intentNameActionParameter2, param2);
|
||||
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))
|
||||
{
|
||||
String param2 = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
if(!param2.contains(Action.actionParameter2Split))
|
||||
etBroadcastToSend.setText(input.getStringExtra(ActivityManageRule.intentNameActionParameter2));
|
||||
else
|
||||
{
|
||||
String[] param2Parts = param2.split(Action.actionParameter2Split);
|
||||
etBroadcastToSend.setText(param2Parts[0]);
|
||||
|
||||
String[] params = param2Parts[1].split(";");
|
||||
|
||||
intentPairList.clear();
|
||||
|
||||
for(int i = 0; i < params.length; i++)
|
||||
{
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
|
||||
intentPairList.add(params[i]);
|
||||
}
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
}
|
||||
|
||||
bAddIntentPair.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// type;name;value
|
||||
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()])
|
||||
{
|
||||
case "int":
|
||||
case "long":
|
||||
case "short":
|
||||
if(!Miscellaneous.isNumeric(etParameterValue.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "double":
|
||||
case "float":
|
||||
if(!Miscellaneous.isNumericDecimal(etParameterValue.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
updateIntentPairList();
|
||||
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getIntentPairDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
spinnerParameterType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
else
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private void updateIntentPairList()
|
||||
{
|
||||
if(lvIntentPairs.getAdapter() == null)
|
||||
lvIntentPairs.setAdapter(intentPairAdapter);
|
||||
|
||||
intentPairAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private AlertDialog getIntentPairDialog(final int itemPosition)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageActionSendBroadcast.this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
|
||||
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// Only 1 choice at the moment, no need to check
|
||||
ActivityManageActionSendBroadcast.this.intentPairList.remove(itemPosition);
|
||||
updateIntentPairList();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
return alertDialog;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@ -8,25 +9,37 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
public class ActivityManageActionSendTextMessage extends Activity
|
||||
{
|
||||
Button bSaveSendTextMessage, bImportNumberFromContacts;
|
||||
Button bSaveSendTextMessage, bImportNumberFromContacts, bMmsAttachment;
|
||||
EditText etPhoneNumber, etSendTextMessage;
|
||||
RadioButton rbMessageTypeSms, rbMessageTypeMms;
|
||||
TextView tvSendMmsFileAttachment;
|
||||
|
||||
protected final static int requestCodeForContactsPermissions = 9876;
|
||||
protected final static int requestCodeGetContact = 3235;
|
||||
protected final static int requestCodeGetMMSattachment = 3236;
|
||||
|
||||
// private String existingUrl = "";
|
||||
public static final String messageTypeSms = "sms";
|
||||
public static final String messageTypeMms = "mms";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
@ -35,12 +48,17 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.send_textmessage_editor);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_send_textmessage);
|
||||
|
||||
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
|
||||
etPhoneNumber = (EditText)findViewById(R.id.etPhoneNumber);
|
||||
bSaveSendTextMessage = (Button)findViewById(R.id.bSaveSendTextMessage);
|
||||
bImportNumberFromContacts = (Button)findViewById(R.id.bImportNumberFromContacts);
|
||||
rbMessageTypeSms = (RadioButton)findViewById(R.id.rbMessageTypeSms);
|
||||
rbMessageTypeMms = (RadioButton) findViewById(R.id.rbMessageTypeMms);
|
||||
bMmsAttachment = (Button)findViewById(R.id.bMmsAttachment);
|
||||
tvSendMmsFileAttachment = (TextView)findViewById(R.id.tvSendMmsFileAttachment);
|
||||
|
||||
bSaveSendTextMessage.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@ -48,17 +66,33 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(etSendTextMessage.getText().toString().length() > 0 && etPhoneNumber.getText().toString().length() > 0)
|
||||
{
|
||||
if(rbMessageTypeMms.isChecked() && StringUtils.isEmpty(tvSendMmsFileAttachment.getText().toString()))
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.chooseFile), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
{
|
||||
if (resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.sendTextMessage);
|
||||
resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
String messageType = null;
|
||||
String path = "";
|
||||
|
||||
if(rbMessageTypeSms.isChecked())
|
||||
messageType = messageTypeSms;
|
||||
else
|
||||
{
|
||||
messageType = messageTypeMms;
|
||||
path = Actions.smsSeparator + tvSendMmsFileAttachment.getText().toString();
|
||||
}
|
||||
|
||||
resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString() + Actions.smsSeparator + messageType + path);
|
||||
}
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
@ -76,6 +110,28 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
RadioButton.OnCheckedChangeListener checkedChangedListener = new RadioButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||
{
|
||||
bMmsAttachment.setEnabled(rbMessageTypeMms.isChecked());
|
||||
}
|
||||
};
|
||||
rbMessageTypeSms.setOnCheckedChangeListener(checkedChangedListener);
|
||||
rbMessageTypeMms.setOnCheckedChangeListener(checkedChangedListener);
|
||||
|
||||
bMmsAttachment.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
chooseFileIntent.setType("*/*");
|
||||
chooseFileIntent = Intent.createChooser(chooseFileIntent, getResources().getString(R.string.chooseFile));
|
||||
startActivityForResult(chooseFileIntent, requestCodeGetMMSattachment);
|
||||
}
|
||||
});
|
||||
|
||||
ActivityManageActionSendTextMessage.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
{
|
||||
@ -83,20 +139,10 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
etPhoneNumber.setText(parameters[0]);
|
||||
etSendTextMessage.setText(parameters[1]);
|
||||
}
|
||||
|
||||
|
||||
// String url = getIntent().getStringExtra("urlToTrigger");
|
||||
// if(url != null)
|
||||
// existingUrl = url;
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
// Intent returnIntent = new Intent();
|
||||
// returnIntent.putExtra("urlToTrigger", existingUrl);
|
||||
|
||||
// setResult(RESULT_OK, returnIntent);
|
||||
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
ActivityManageActionSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
@ -132,7 +178,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)
|
||||
{
|
||||
@ -145,18 +191,16 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
|
||||
private void openContactsDialogue()
|
||||
{
|
||||
// Toast.makeText(ActivityEditSendTextMessage.this, "Opening contacts dialogue", Toast.LENGTH_LONG).show();
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
|
||||
startActivityForResult(intent, 1000);
|
||||
startActivityForResult(intent, requestCodeGetContact);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(requestCode == 1000)
|
||||
{
|
||||
if(resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
if(requestCode == requestCodeGetContact)
|
||||
{
|
||||
String phoneNo = null;
|
||||
String name = null;
|
||||
@ -175,6 +219,12 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
etPhoneNumber.setText(phoneNo);
|
||||
}
|
||||
}
|
||||
else if (requestCode == requestCodeGetMMSattachment)
|
||||
{
|
||||
Uri fileUri = data.getData();
|
||||
String filePath = fileUri.getPath();
|
||||
tvSendMmsFileAttachment.setText(filePath);
|
||||
}
|
||||
}
|
||||
//super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
//import static com.jens.automation2.ActivityManageActionTriggerUrl.edit;
|
||||
|
||||
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.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionSetVariable extends Activity
|
||||
{
|
||||
private Button bSaveVariable;
|
||||
private EditText etVariableSetKey, etVariableSetValue;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_set_variable);
|
||||
|
||||
etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey);
|
||||
etVariableSetValue = (EditText)findViewById(R.id.etVariableSetValue);
|
||||
bSaveVariable = (Button)findViewById(R.id.bSaveVariable);
|
||||
bSaveVariable.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(StringUtils.isEmpty(etVariableSetKey.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionSetVariable.this, getResources().getString(R.string.enterVariableKey), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent response = new Intent();
|
||||
|
||||
if(StringUtils.isEmpty(etVariableSetValue.getText().toString()))
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etVariableSetKey.getText().toString());
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etVariableSetKey.getText().toString() + Action.actionParameter2Split + etVariableSetValue.getText().toString());
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] input = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
etVariableSetKey.setText(input[0]);
|
||||
if(input.length > 1)
|
||||
etVariableSetValue.setText(input[1]);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,8 +15,6 @@ public class ActivityManageActionSpeakText extends Activity
|
||||
private Button bSaveSpeakText;
|
||||
private EditText etSpeakText;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
|
||||
@ -24,10 +22,11 @@ public class ActivityManageActionSpeakText extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.speak_text_editor);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_speak_text);
|
||||
|
||||
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
|
||||
bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl);
|
||||
bSaveSpeakText = (Button)findViewById(R.id.bSaveSpeakText);
|
||||
bSaveSpeakText.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -44,7 +43,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;
|
||||
@ -10,7 +11,9 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
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;
|
||||
@ -22,12 +25,16 @@ import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -37,12 +44,299 @@ import java.util.List;
|
||||
|
||||
public class ActivityManageActionStartActivity extends Activity
|
||||
{
|
||||
/*
|
||||
This page might qualify as a help page: https://stackoverflow.com/questions/55323947/open-url-in-firefox-for-android-using-intent
|
||||
*/
|
||||
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue, etSelectedActivity;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath, etClassName;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
|
||||
Spinner spinnerParameterType;
|
||||
RadioGroup rgAppStartupType;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService;
|
||||
|
||||
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
|
||||
public final static String startByActivityString = "0";
|
||||
public final static String startByBroadcastString = "1";
|
||||
public final static String startByServiceString = "2";
|
||||
public final static String startByForegroundServiceString = "3";
|
||||
|
||||
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
etClassName = (EditText)findViewById(R.id.etClassName);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
|
||||
etPackageName = (EditText) findViewById(R.id.etPackageName);
|
||||
etActivityOrActionPath = (EditText) findViewById(R.id.etActivityOrActionPath);
|
||||
rbStartAppSelectByActivity = (RadioButton)findViewById(R.id.rbStartAppSelectByActivity);
|
||||
rbStartAppSelectByAction = (RadioButton)findViewById(R.id.rbStartAppSelectByAction);
|
||||
showStartProgramExamples = (Button)findViewById(R.id.showStartProgramExamples);
|
||||
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
|
||||
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
|
||||
rbStartAppByService = (RadioButton)findViewById(R.id.rbStartAppByService);
|
||||
rbStartAppByForegroundService = (RadioButton)findViewById(R.id.rbStartAppByForegroundService);
|
||||
rgAppStartupType = (RadioGroup)findViewById(R.id.rgAppStartupType);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
etClassName.setEnabled(false);
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
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(AutomationService.flavor_name_googleplay))
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
});
|
||||
|
||||
bAddIntentPair.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// type;name;value
|
||||
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()])
|
||||
{
|
||||
case "int":
|
||||
case "long":
|
||||
case "short":
|
||||
if(!Miscellaneous.isNumeric(etParameterValue.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "double":
|
||||
case "float":
|
||||
if(!Miscellaneous.isNumericDecimal(etParameterValue.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
updateIntentPairList();
|
||||
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
showStartProgramExamples.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlShowExamples));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getIntentPairDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
bSaveActionStartOtherActivity.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent returnData = new Intent();
|
||||
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter1, rbStartAppSelectByAction.isChecked());
|
||||
|
||||
String parameter2 = "";
|
||||
|
||||
if (rbStartAppSelectByActivity.isChecked())
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
{
|
||||
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 += Actions.dummyPackageString + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
|
||||
parameter2 += Action.actionParameter2Split + etClassName.getText().toString();
|
||||
}
|
||||
|
||||
if (rbStartAppByActivity.isChecked())
|
||||
parameter2 += Action.actionParameter2Split + startByActivityString;
|
||||
else if(rbStartAppByService.isChecked())
|
||||
parameter2 += Action.actionParameter2Split + startByServiceString;
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
parameter2 += Action.actionParameter2Split + startByForegroundServiceString;
|
||||
else
|
||||
parameter2 += Action.actionParameter2Split + startByBroadcastString;
|
||||
|
||||
for (String s : intentPairList)
|
||||
parameter2 += Action.actionParameter2Split + s;
|
||||
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, parameter2);
|
||||
|
||||
setResult(RESULT_OK, returnData);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
spinnerParameterType.setOnItemSelectedListener(new OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
else
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
}
|
||||
});
|
||||
|
||||
rbStartAppSelectByActivity.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
bSelectApp.setEnabled(isChecked);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rbStartAppSelectByAction.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
bSelectApp.setEnabled(!isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
rgAppStartupType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int i)
|
||||
{
|
||||
if(rbStartAppByActivity.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if (rbStartAppByBroadcast.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if(rbStartAppByService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
loadValuesIntoGui(i);
|
||||
}
|
||||
|
||||
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
|
||||
{
|
||||
@ -65,13 +359,11 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
public static Action resultingAction;
|
||||
|
||||
private static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String" };
|
||||
private static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String", "Uri" };
|
||||
private ArrayList<String> intentPairList = new ArrayList<String>();
|
||||
|
||||
ArrayAdapter<String> intentTypeSpinnerAdapter, intentPairAdapter;
|
||||
@ -219,7 +511,7 @@ 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));
|
||||
@ -230,33 +522,78 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
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);
|
||||
if(packageArray.length > 1)
|
||||
{
|
||||
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), ActivityManageActionStartActivity.this).show();
|
||||
|
||||
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)
|
||||
{
|
||||
// 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));
|
||||
@ -267,161 +604,83 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageActionStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
etSelectedActivity.setText(ai.packageName + ";" + ai.name);
|
||||
etPackageName.setText(ai.packageName);
|
||||
etActivityOrActionPath.setText(ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
|
||||
etSelectedActivity = (EditText) findViewById(R.id.etSelectedApplication);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
void getAppList()
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
});
|
||||
|
||||
bAddIntentPair.setOnClickListener(new OnClickListener()
|
||||
private void loadValuesIntoGui(Intent input)
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// type;name;value
|
||||
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
boolean selectionByAction = input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true);
|
||||
rbStartAppSelectByActivity.setChecked(!selectionByAction);
|
||||
rbStartAppSelectByAction.setChecked(selectionByAction);
|
||||
|
||||
if(etParameterName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
String[] params;
|
||||
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + "/" + etParameterName.getText().toString() + "/" + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getIntentPairDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
bSaveActionStartOtherActivity.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(saveAction())
|
||||
{
|
||||
ActivityManageActionStartActivity.this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
spinnerParameterType.setOnItemSelectedListener(new OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
if(partsString.contains(Action.actionParameter2Split))
|
||||
params = partsString.split(Action.actionParameter2Split);
|
||||
else
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
params = partsString.split(";");
|
||||
|
||||
if(Miscellaneous.isNumeric(params[2])) // old configuration file
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[2].equals(startByServiceString));
|
||||
}
|
||||
else
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[3].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[3].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[3].equals(startByServiceString));
|
||||
rbStartAppByForegroundService.setChecked(params[3].equals(startByForegroundServiceString));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
int startIndex = -1;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
if(!selectionByAction)
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui();
|
||||
etPackageName.setText(params[0]);
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!params[0].contains(Actions.dummyPackageString))
|
||||
etPackageName.setText(params[0]);
|
||||
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
etClassName.setText(params[2]);
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
String[] params = resultingAction.getParameter2().split(";");
|
||||
if(params.length >= 2)
|
||||
{
|
||||
etSelectedActivity.setText(params[0] + ";" + params[1]);
|
||||
if (params.length >= 4)
|
||||
startIndex = 4;
|
||||
|
||||
if(params.length > 2)
|
||||
if(startIndex > -1 && params.length > startIndex)
|
||||
{
|
||||
intentPairList.clear();
|
||||
|
||||
for(int i=2; i<params.length; i++)
|
||||
for(int i=startIndex; i<params.length; i++)
|
||||
{
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
|
||||
intentPairList.add(params[i]);
|
||||
}
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIntentPairList()
|
||||
{
|
||||
@ -431,46 +690,29 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
intentPairAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private boolean saveAction()
|
||||
boolean checkInput()
|
||||
{
|
||||
if(etSelectedActivity.getText().toString().length() == 0)
|
||||
if(rbStartAppSelectByActivity.isChecked())
|
||||
{
|
||||
if (etPackageName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterPackageName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else if (etActivityOrActionPath.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Intent testIntent = new Intent(ActivityManageActionStartActivity.this, etSelectedActivity);
|
||||
// Intent externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
// externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
// externalActivityIntent.setClassName(packageName, className);
|
||||
//
|
||||
// boolean activityExists = externalActivityIntent.resolveActivityInfo(getPackageManager(), 0) != null;
|
||||
// }
|
||||
|
||||
if(etSelectedActivity.getText().toString().equals(getResources().getString(R.string.selectApplication)))
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
if(etActivityOrActionPath.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.enterValidAction), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(resultingAction == null)
|
||||
resultingAction = new Action();
|
||||
|
||||
resultingAction.setAction(Action_Enum.startOtherActivity);
|
||||
|
||||
String parameter2;
|
||||
|
||||
if(etSelectedActivity.getText().toString().contains(";"))
|
||||
parameter2 = etSelectedActivity.getText().toString();
|
||||
else
|
||||
parameter2 = "dummyPkg;" + etSelectedActivity.getText().toString();
|
||||
|
||||
for(String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
|
||||
resultingAction.setParameter2(parameter2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -490,7 +732,6 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@ -507,9 +748,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -13,33 +17,44 @@ import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
public class ActivityManageActionTriggerUrl extends Activity
|
||||
{
|
||||
Button bSaveTriggerUrl;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
|
||||
Button bSaveTriggerUrl, bAddHttpParam;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword, etParameterName, etParameterValue;
|
||||
ListView lvTriggerUrlPostParameters;
|
||||
CheckBox chkTriggerUrlUseAuthentication;
|
||||
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
|
||||
TableLayout tlTriggerUrlAuthentication;
|
||||
ArrayAdapter<String> httpParametersAdapter;
|
||||
|
||||
private ArrayList<String> httpParamsList = new ArrayList<>();
|
||||
ArrayAdapter<Map<String,String>> lvTriggerUrlPostParametersAdapter;
|
||||
|
||||
// private String existingUrl = "";
|
||||
public static final String methodGet = "GET";
|
||||
public static final String methodPost = "POST";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
// public static boolean edit = false;
|
||||
// public static Action resultingAction = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.trigger_url_editor);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_trigger_url);
|
||||
|
||||
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
|
||||
etTriggerUrlUsername = (EditText)findViewById(R.id.etTriggerUrlUsername);
|
||||
@ -47,7 +62,33 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
chkTriggerUrlUseAuthentication = (CheckBox)findViewById(R.id.chkTriggerUrlUseAuthentication);
|
||||
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
|
||||
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
|
||||
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveTriggerUrl);
|
||||
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveSpeakText);
|
||||
rbTriggerUrlMethodGet = (RadioButton) findViewById(R.id.rbTriggerUrlMethodGet);
|
||||
rbTriggerUrlMethodPost = (RadioButton) findViewById(R.id.rbTriggerUrlMethodPost);
|
||||
etTriggerUrl = (EditText) findViewById(R.id.etTriggerUrl);
|
||||
etParameterName = (EditText) findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam);
|
||||
|
||||
etParameterName.setEnabled(false);
|
||||
etParameterValue.setEnabled(false);
|
||||
bAddHttpParam.setEnabled(false);
|
||||
|
||||
rbTriggerUrlMethodPost.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
etParameterName.setEnabled(checked);
|
||||
etParameterValue.setEnabled(checked);
|
||||
bAddHttpParam.setEnabled(checked);
|
||||
if(checked)
|
||||
lvTriggerUrlPostParameters.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList);
|
||||
|
||||
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -55,11 +96,9 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
{
|
||||
if(etTriggerUrl.getText().toString().length() > 0)
|
||||
{
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.triggerUrl);
|
||||
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
Intent returnIntent = new Intent();
|
||||
|
||||
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter1, chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
@ -70,29 +109,51 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString().trim()
|
||||
String method = methodGet;
|
||||
if(rbTriggerUrlMethodPost.isChecked())
|
||||
method = methodPost;
|
||||
|
||||
String httpParams = "";
|
||||
for (String s : httpParamsList)
|
||||
httpParams += Action.actionParameters2SeparatorOuter + s;
|
||||
if(httpParams.length() > 0)
|
||||
httpParams = httpParams.substring(Action.actionParameters2SeparatorOuter.length());
|
||||
|
||||
returnIntent.putExtra(ActivityManageRule.intentNameActionParameter2,
|
||||
username + Action.actionParameter2Split +
|
||||
password + Action.actionParameter2Split +
|
||||
etTriggerUrl.getText().toString().trim() + Action.actionParameter2Split +
|
||||
method + Action.actionParameter2Split +
|
||||
httpParams
|
||||
);
|
||||
}
|
||||
backToRuleManager();
|
||||
|
||||
setResult(RESULT_OK, returnIntent);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.urlTooShort), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chkTriggerUrlUseAuthentication.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.VISIBLE);
|
||||
rbTriggerUrlMethodGet.setChecked(false);
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
rbTriggerUrlMethodGet.setEnabled(false);
|
||||
rbTriggerUrlMethodPost.setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.GONE);
|
||||
rbTriggerUrlMethodGet.setEnabled(true);
|
||||
rbTriggerUrlMethodPost.setEnabled(true);
|
||||
}
|
||||
|
||||
etTriggerUrlUsername.setEnabled(isChecked);
|
||||
etTriggerUrlPassword.setEnabled(isChecked);
|
||||
@ -109,50 +170,84 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
});
|
||||
updateListView();
|
||||
|
||||
|
||||
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
// username,password,URL
|
||||
String[] components = ActivityManageActionTriggerUrl.resultingAction.getParameter2().split(";");
|
||||
// username,password,URL,etc.
|
||||
String[] components;
|
||||
|
||||
if(getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).contains(Action.actionParameter2Split))
|
||||
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split, -1);
|
||||
else
|
||||
components = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";", -1);
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
etTriggerUrl.setText(components[2]);
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
|
||||
chkTriggerUrlUseAuthentication.setChecked(getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, false));
|
||||
etTriggerUrlUsername.setText(components[0]);
|
||||
etTriggerUrlPassword.setText(components[1]);
|
||||
|
||||
if(components.length >= 4)
|
||||
{
|
||||
switch(components[3])
|
||||
{
|
||||
case methodPost:
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
break;
|
||||
case methodGet:
|
||||
default:
|
||||
rbTriggerUrlMethodGet.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(components.length >= 5)
|
||||
{
|
||||
if(!StringUtils.isEmpty(components[4]) && components[4].contains(Action.actionParameters2SeparatorInner))
|
||||
{
|
||||
String httpParams[] = components[4].split(Action.actionParameters2SeparatorOuter);
|
||||
for (String paramPair : httpParams)
|
||||
httpParamsList.add(paramPair);
|
||||
|
||||
updateHttpParamsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
etTriggerUrl.setText(components[0]);
|
||||
}
|
||||
|
||||
bAddHttpParam.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(StringUtils.isEmpty(etParameterName.getText()) || StringUtils.isEmpty(etParameterValue.getText()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionTriggerUrl.this, getResources().getString(R.string.enterValidDataIntoParametersFields), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
httpParamsList.add(etParameterName.getText() + Action.actionParameters2SeparatorInner + etParameterValue.getText());
|
||||
|
||||
if(username == null)
|
||||
username = "";
|
||||
updateHttpParamsList();
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString()
|
||||
);
|
||||
if(lvTriggerUrlPostParameters.getVisibility() != View.VISIBLE)
|
||||
lvTriggerUrlPostParameters.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
||||
this.finish();
|
||||
lvTriggerUrlPostParameters.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getHttpParamsDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateListView()
|
||||
@ -168,4 +263,30 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
}
|
||||
|
||||
private void updateHttpParamsList()
|
||||
{
|
||||
if(lvTriggerUrlPostParameters.getAdapter() == null)
|
||||
lvTriggerUrlPostParameters.setAdapter(httpParametersAdapter);
|
||||
|
||||
httpParametersAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private AlertDialog getHttpParamsDialog(final int itemPosition)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageActionTriggerUrl.this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
|
||||
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// Only 1 choice at the moment, no need to check
|
||||
ActivityManageActionTriggerUrl.this.httpParamsList.remove(itemPosition);
|
||||
updateHttpParamsList();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
return alertDialog;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionVibrate extends Activity
|
||||
{
|
||||
TextView etVibratePattern;
|
||||
Button bTestVibratePattern, bSaveVibratePattern;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_vibrate);
|
||||
|
||||
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
|
||||
bTestVibratePattern = (Button)findViewById(R.id.bTestVibratePattern);
|
||||
bSaveVibratePattern = (Button)findViewById(R.id.bSaveVibratePattern);
|
||||
|
||||
bSaveVibratePattern.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra("vibratePattern", etVibratePattern.getText().toString());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bTestVibratePattern.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this))
|
||||
{
|
||||
String pattern = etVibratePattern.getText().toString();
|
||||
Actions.vibrate(false, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra("vibratePattern"))
|
||||
etVibratePattern.setText(input.getStringExtra("vibratePattern"));
|
||||
}
|
||||
|
||||
boolean checkInput()
|
||||
{
|
||||
String vibratePattern = etVibratePattern.getText().toString();
|
||||
String regex = "^[0-9,]+$";
|
||||
if(StringUtils.isEmpty(vibratePattern) || !vibratePattern.matches(regex) || vibratePattern.substring(0, 1).equals(",") || vibratePattern.substring(vibratePattern.length()-1).equals(","))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionVibrate.this, getResources().getString(R.string.pleaseEnterValidVibrationPattern), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionWakeLock extends Activity
|
||||
{
|
||||
RadioButton rbWakeLockActivate, rbWakeLockDeactivate;
|
||||
CheckBox chkWakeLockTimeout;
|
||||
EditText etWakeLockDuration;
|
||||
Button bSaveWakelock;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wakelock);
|
||||
|
||||
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
|
||||
rbWakeLockDeactivate = (RadioButton)findViewById(R.id.rbWakeLockDeactivate);
|
||||
chkWakeLockTimeout = (CheckBox)findViewById(R.id.chkWakeLockTimeout);
|
||||
etWakeLockDuration = (EditText)findViewById(R.id.etWakeLockDuration);
|
||||
bSaveWakelock = (Button)findViewById(R.id.bSaveWakelock);
|
||||
|
||||
etWakeLockDuration.setEnabled(chkWakeLockTimeout.isChecked());
|
||||
|
||||
chkWakeLockTimeout.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean wakeLockTimeoutSet)
|
||||
{
|
||||
etWakeLockDuration.setEnabled(wakeLockTimeoutSet);
|
||||
|
||||
if(wakeLockTimeoutSet)
|
||||
etWakeLockDuration.setText(String.valueOf(Actions.wakeLockTimeoutDisabled));
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
{
|
||||
rbWakeLockActivate.setChecked(getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
|
||||
rbWakeLockDeactivate.setChecked(!getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, false));
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
if(Miscellaneous.isNumeric(getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2)))
|
||||
{
|
||||
long timeout = Long.parseLong((getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2)));
|
||||
chkWakeLockTimeout.setChecked(timeout != Actions.wakeLockTimeoutDisabled);
|
||||
etWakeLockDuration.setText(String.valueOf(timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
chkWakeLockTimeout.setChecked(false);
|
||||
etWakeLockDuration.setText(String.valueOf(Actions.wakeLockTimeoutDisabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bSaveWakelock.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(chkWakeLockTimeout.isChecked())
|
||||
{
|
||||
if((StringUtils.isEmpty(etWakeLockDuration.getText().toString()) || Integer.parseInt(etWakeLockDuration.getText().toString()) <= 0))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionWakeLock.this, getResources().getString(R.string.enterAPositiveValidNonDecimalNumber), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter1, rbWakeLockActivate.isChecked());
|
||||
if(chkWakeLockTimeout.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etWakeLockDuration.getText().toString());
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Actions.wakeLockTimeoutDisabled));
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageActionWifi extends Activity
|
||||
{
|
||||
CheckBox chkWifiRunAsRoot;
|
||||
RadioButton rbActionWifiOn, rbActionWifiOff;
|
||||
Button bActionWifiSave;
|
||||
TextView tvWifiExplanation1, tvWifiExplanation2;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wifi);
|
||||
|
||||
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
|
||||
rbActionWifiOn = (RadioButton) findViewById(R.id.rbActionWifiOn);
|
||||
rbActionWifiOff = (RadioButton)findViewById(R.id.rbActionWifiOff);
|
||||
bActionWifiSave = (Button) findViewById(R.id.bActionWifiSave);
|
||||
tvWifiExplanation1 = (TextView)findViewById(R.id.tvWifiExplanation1);
|
||||
tvWifiExplanation2 = (TextView)findViewById(R.id.tvWifiExplanation2);
|
||||
|
||||
Intent input = getIntent();
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
chkWifiRunAsRoot.setChecked(Boolean.parseBoolean(input.getStringExtra(ActivityManageRule.intentNameActionParameter2)));
|
||||
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
// Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice), ActivityManageActionWifi.this).show();
|
||||
|
||||
if(getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
|
||||
tvWifiExplanation1.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiExplanation1.setVisibility(View.GONE);
|
||||
|
||||
bActionWifiSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter1, rbActionWifiOn.isChecked());
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(chkWifiRunAsRoot.isChecked()));
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -12,7 +12,9 @@ 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;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@ -21,16 +23,26 @@ import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ActivityManagePoi extends Activity
|
||||
{
|
||||
public LocationManager myLocationManager;
|
||||
MyLocationListenerGps myLocationListenerGps = new MyLocationListenerGps();
|
||||
Location locationGps = null, locationNetwork = null;
|
||||
// Location locationWifi = null;
|
||||
MyLocationListenerNetwork myLocationListenerNetwork = new MyLocationListenerNetwork();
|
||||
Button bGetPosition, bSavePoi;
|
||||
ImageButton ibShowOnMap;
|
||||
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
|
||||
Calendar locationSearchStart = null;
|
||||
Timer timer = null;
|
||||
|
||||
final static int defaultRadius = 250;
|
||||
final static int searchTimeout = 120;
|
||||
|
||||
private static ProgressDialog progressDialog;
|
||||
|
||||
@ -47,7 +59,8 @@ public class ActivityManagePoi extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_poi);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_poi);
|
||||
|
||||
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
bGetPosition = (Button)findViewById(R.id.bGetPosition);
|
||||
@ -104,7 +117,7 @@ public class ActivityManagePoi extends Activity
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
if(loadFormValuesToVariable())
|
||||
if(loadFormValuesToVariable(false))
|
||||
if(ActivityMainPoi.poiToEdit.create(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
@ -114,7 +127,7 @@ public class ActivityManagePoi extends Activity
|
||||
private void changePoi()
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
if(loadFormValuesToVariable())
|
||||
if(loadFormValuesToVariable(false))
|
||||
if(ActivityMainPoi.poiToEdit.change(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
@ -124,73 +137,171 @@ 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 critGps = new Criteria();
|
||||
critGps.setAltitudeRequired(false);
|
||||
critGps.setSpeedRequired(false);
|
||||
critGps.setBearingRequired(false);
|
||||
critGps.setCostAllowed(true);
|
||||
critGps.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
Criteria criteriaGps = new Criteria();
|
||||
criteriaGps.setAltitudeRequired(false);
|
||||
criteriaGps.setSpeedRequired(false);
|
||||
criteriaGps.setBearingRequired(false);
|
||||
criteriaGps.setCostAllowed(true);
|
||||
criteriaGps.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(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.", 4);
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider2, 3);
|
||||
myLocationManager.requestLocationUpdates(provider2, 500, Settings.satisfactoryAccuracyGps, myLocationListenerGps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void compareLocations()
|
||||
private void startTimeout()
|
||||
{
|
||||
if(timer != null)
|
||||
stopTimeout();
|
||||
|
||||
timer = new Timer();
|
||||
|
||||
class TimeoutTask extends TimerTask
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
evaluateLocationResults();
|
||||
}
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Starting timeout for location search: " + String.valueOf(searchTimeout) + " seconds", 5);
|
||||
|
||||
TimerTask timeoutTask = new TimeoutTask();
|
||||
timer.schedule(timeoutTask, searchTimeout * 1000);
|
||||
}
|
||||
|
||||
private void stopTimeout()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Stopping timeout for location search.", 5);
|
||||
|
||||
if(timer != null)
|
||||
{
|
||||
timer.purge();
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void evaluateLocationResults()
|
||||
{
|
||||
/*
|
||||
Procedure:
|
||||
If we get a GPS result we take it and suggest a default minimum radius.
|
||||
If private locationing is active that's the only possible outcome other than a timeout.
|
||||
|
||||
If private locationing is not active
|
||||
If we get a network
|
||||
*/
|
||||
|
||||
// We have GPS
|
||||
if(locationGps != null)
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationGps.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationGps.getLongitude()));
|
||||
|
||||
String text;
|
||||
if(locationNetwork != null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.comparing), 4);
|
||||
|
||||
double variance = locationGps.distanceTo(locationNetwork);
|
||||
|
||||
String text = getResources().getString(R.string.distanceBetween) + " " + String.valueOf(Math.round(variance)) + " " + getResources().getString(R.string.radiusSuggestion);
|
||||
// Toast.makeText(getBaseContext(), text, Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
// if(variance > 50 && guiPoiRadius.getText().toString().length()>0 && Integer.parseInt(guiPoiRadius.getText().toString())<variance)
|
||||
// {
|
||||
// String text = "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.";
|
||||
getDialog(text, Math.round(variance) + 1).show();
|
||||
// Toast.makeText(getBaseContext(), "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.", Toast.LENGTH_LONG).show();
|
||||
// }
|
||||
text = String.format(getResources().getString(R.string.distanceBetween), Math.round(variance));
|
||||
getRadiusConfirmationDialog(text, Math.round(variance) + 1).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
guiPoiRadius.setText("250");
|
||||
text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
}
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
} // we have a great network signal:
|
||||
else if(locationNetwork != null && locationNetwork.getAccuracy() <= Settings.satisfactoryAccuracyGps && locationNetwork.getAccuracy() <= defaultRadius)
|
||||
{
|
||||
/*
|
||||
We do not yet have a GPS result. But we have a network result that is good enough
|
||||
to accept it a sole result. In that case we suggest a default radius, no variance.
|
||||
*/
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
|
||||
|
||||
String text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
}
|
||||
else if( // we have a bad network signal and nothing else, GPS result may still come in
|
||||
locationNetwork != null
|
||||
&&
|
||||
Calendar.getInstance().getTimeInMillis()
|
||||
<
|
||||
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
|
||||
)
|
||||
{
|
||||
// Only a network location was found and it is also not very accurate.
|
||||
}
|
||||
else if( // we have a bad network signal and nothing else, timeout has expired, nothing else can possibly come in
|
||||
locationNetwork != null
|
||||
&&
|
||||
Calendar.getInstance().getTimeInMillis()
|
||||
>
|
||||
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
|
||||
)
|
||||
{
|
||||
// Only a network location was found and it is also not very accurate.
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
|
||||
|
||||
String text = String.format(getResources().getString(R.string.locationFoundInaccurate), defaultRadius);
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logNotAllMeasurings), 4);
|
||||
{
|
||||
String text = String.format(getResources().getString(R.string.noLocationCouldBeFound), String.valueOf(searchTimeout));
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 2);
|
||||
|
||||
if(myLocationListenerNetwork != null)
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
progressDialog.dismiss();
|
||||
getErrorDialog(text).show();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog getNotificationDialog(String text)
|
||||
@ -202,16 +313,21 @@ public class ActivityManagePoi extends Activity
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// switch(which)
|
||||
// {
|
||||
// case DialogInterface.BUTTON_POSITIVE:
|
||||
// guiPoiRadius.setText(String.valueOf(value));
|
||||
// break;
|
||||
// case DialogInterface.BUTTON_NEGATIVE:
|
||||
// break;
|
||||
// }
|
||||
|
||||
progressDialog = ProgressDialog.show(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
|
||||
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();
|
||||
}
|
||||
};
|
||||
@ -221,8 +337,11 @@ public class ActivityManagePoi extends Activity
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getDialog(String text, final double value)
|
||||
|
||||
private AlertDialog getRadiusConfirmationDialog(String text, final double value)
|
||||
{
|
||||
stopTimeout();
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
@ -248,9 +367,30 @@ public class ActivityManagePoi extends Activity
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
private AlertDialog getErrorDialog(String text)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
};
|
||||
alertDialogBuilder.setMessage(text);
|
||||
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.ok), null);
|
||||
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public class MyLocationListenerGps implements LocationListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
@ -260,116 +400,65 @@ public class ActivityManagePoi extends Activity
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from GPS location updates.", 5);
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationGps = location;
|
||||
|
||||
compareLocations();
|
||||
evaluateLocationResults();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// public class MyLocationListenerWifi implements LocationListener
|
||||
// {
|
||||
//
|
||||
// @Override
|
||||
// public void onLocationChanged(Location location)
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.gotGpsUpdate) + " " + String.valueOf(location.getAccuracy()));
|
||||
// // Deactivate when accuracy reached
|
||||
//// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
|
||||
//// {
|
||||
//// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
|
||||
//
|
||||
// myLocationManager.removeUpdates(this);
|
||||
// locationGps = location;
|
||||
//
|
||||
// compareLocations();
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderDisabled(String provider)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderEnabled(String provider)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
public class MyLocationListenerNetwork implements LocationListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGotNetworkUpdate) + " " + String.valueOf(location.getAccuracy()), 3);
|
||||
// Deactivate when accuracy reached
|
||||
// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
|
||||
// {
|
||||
// String text = "Network position found. satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_NETWORK) + "m reached. Removing location updates...";
|
||||
// Miscellaneous.logEvent("i", "POI Manager", text);
|
||||
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationNetwork = location;
|
||||
|
||||
compareLocations();
|
||||
// }
|
||||
// Deactivate when accuracy reached
|
||||
if(location.getAccuracy() <= Settings.satisfactoryAccuracyGps)
|
||||
{
|
||||
// Accuracy is so good that we don't need to wait for GPS result
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from network location updates.", 5);
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
}
|
||||
|
||||
evaluateLocationResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void editPoi(PointOfInterest poi)
|
||||
@ -380,11 +469,13 @@ public class ActivityManagePoi extends Activity
|
||||
guiPoiRadius.setText(String.valueOf(poi.getRadius()));
|
||||
}
|
||||
|
||||
public boolean loadFormValuesToVariable()
|
||||
public boolean loadFormValuesToVariable(boolean checkOnlyCoordinates)
|
||||
{
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
|
||||
if(!checkOnlyCoordinates)
|
||||
{
|
||||
if (guiPoiName.getText().length() == 0)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
@ -392,6 +483,7 @@ public class ActivityManagePoi extends Activity
|
||||
}
|
||||
else
|
||||
ActivityMainPoi.poiToEdit.setName(guiPoiName.getText().toString());
|
||||
}
|
||||
|
||||
if(ActivityMainPoi.poiToEdit.getLocation() == null)
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
@ -416,6 +508,8 @@ public class ActivityManagePoi extends Activity
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!checkOnlyCoordinates)
|
||||
{
|
||||
try
|
||||
{
|
||||
ActivityMainPoi.poiToEdit.setRadius(Double.parseDouble(guiPoiRadius.getText().toString()), this);
|
||||
@ -430,13 +524,14 @@ public class ActivityManagePoi extends Activity
|
||||
Toast.makeText(this, getResources().getString(R.string.unknownError), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showOnMap()
|
||||
{
|
||||
if(loadFormValuesToVariable())
|
||||
if(loadFormValuesToVariable(true))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
@ -37,43 +38,46 @@ public class ActivityManageProfile extends Activity
|
||||
final static int intentCodeRingtonePickerNotificationsFile = 9020;
|
||||
final static int intentCodeRingtonePickerNotificationsRingtone = 9021;
|
||||
|
||||
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback;
|
||||
Spinner spinnerSoundMode;
|
||||
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback, checkBoxChangeDnd;
|
||||
Spinner spinnerSoundMode, spinnerDndMode;
|
||||
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms;
|
||||
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
|
||||
TextView tvIncomingCallsRingtone, tvNotificationsRingtone;
|
||||
EditText etName;
|
||||
|
||||
File incomingCallsRingtone = null, notificationsRingtone = null;
|
||||
boolean guiUpdate = false;
|
||||
|
||||
String incomingCallsRingtone = null, notificationsRingtone = null;
|
||||
|
||||
ArrayAdapter<String> soundModeAdapter;
|
||||
ArrayAdapter<String> dndModeAdapter;
|
||||
|
||||
public void setIncomingCallsRingtone(File incomingCallsRingtone)
|
||||
public void setIncomingCallsRingtone(String incomingCallsRingtone)
|
||||
{
|
||||
this.incomingCallsRingtone = incomingCallsRingtone;
|
||||
|
||||
if(incomingCallsRingtone != null)
|
||||
tvIncomingCallsRingtone.setText(this.incomingCallsRingtone.getAbsolutePath());
|
||||
tvIncomingCallsRingtone.setText(this.incomingCallsRingtone);
|
||||
else
|
||||
tvIncomingCallsRingtone.setText(getResources().getString(R.string.none));
|
||||
}
|
||||
|
||||
public File getIncomingCallsRingtone()
|
||||
public String getIncomingCallsRingtone()
|
||||
{
|
||||
return incomingCallsRingtone;
|
||||
}
|
||||
|
||||
public void setNotificationsRingtone(File notificationsRingtone)
|
||||
public void setNotificationsRingtone(String notificationsRingtone)
|
||||
{
|
||||
this.notificationsRingtone = notificationsRingtone;
|
||||
|
||||
if(this.notificationsRingtone != null)
|
||||
tvNotificationsRingtone.setText(this.notificationsRingtone.getAbsolutePath());
|
||||
tvNotificationsRingtone.setText(this.notificationsRingtone);
|
||||
else
|
||||
tvNotificationsRingtone.setText(getResources().getString(R.string.none));
|
||||
}
|
||||
|
||||
public File getNotificationsRingtone()
|
||||
public String getNotificationsRingtone()
|
||||
{
|
||||
return notificationsRingtone;
|
||||
}
|
||||
@ -82,9 +86,11 @@ public class ActivityManageProfile extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_profile);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_profile);
|
||||
|
||||
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
|
||||
checkBoxChangeDnd = (CheckBox)findViewById(R.id.checkBoxChangeDnd);
|
||||
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
|
||||
checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications);
|
||||
checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms);
|
||||
@ -99,6 +105,7 @@ public class ActivityManageProfile extends Activity
|
||||
checkBoxHapticFeedback = (CheckBox)findViewById(R.id.checkBoxHapticFeedback);
|
||||
checkBoxVibrateWhenRinging = (CheckBox)findViewById(R.id.checkBoxVibrateWhenRinging);
|
||||
spinnerSoundMode = (Spinner)findViewById(R.id.spinnerSoundMode);
|
||||
spinnerDndMode = (Spinner)findViewById(R.id.spinnerDndMode);
|
||||
seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic);
|
||||
seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications);
|
||||
seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms);
|
||||
@ -114,6 +121,7 @@ public class ActivityManageProfile extends Activity
|
||||
checkBoxScreenLockUnlockSound.setEnabled(false);
|
||||
checkBoxHapticFeedback.setEnabled(false);
|
||||
spinnerSoundMode.setEnabled(false);
|
||||
spinnerDndMode.setEnabled(false);
|
||||
seekBarVolumeMusic.setEnabled(false);
|
||||
seekBarVolumeNotifications.setEnabled(false);
|
||||
seekBarVolumeAlarms.setEnabled(false);
|
||||
@ -121,6 +129,14 @@ public class ActivityManageProfile extends Activity
|
||||
bChangeSoundNotifications.setEnabled(false);
|
||||
|
||||
spinnerSoundMode.setSelection(0);
|
||||
spinnerDndMode.setSelection(0);
|
||||
|
||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
|
||||
{
|
||||
// Disable DND controls
|
||||
checkBoxChangeDnd.setEnabled(false);
|
||||
spinnerDndMode.setEnabled(false);
|
||||
}
|
||||
|
||||
// Scale SeekBars to the system's maximum volume values
|
||||
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
@ -128,9 +144,31 @@ public class ActivityManageProfile extends Activity
|
||||
seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
|
||||
seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM));
|
||||
|
||||
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[] { getResources().getString(R.string.soundModeSilent), getResources().getString(R.string.soundModeVibrate), getResources().getString(R.string.soundModeNormal) });
|
||||
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[]
|
||||
{
|
||||
getResources().getString(R.string.soundModeSilent),
|
||||
getResources().getString(R.string.soundModeVibrate),
|
||||
getResources().getString(R.string.soundModeNormal)
|
||||
});
|
||||
spinnerSoundMode.setAdapter(soundModeAdapter);
|
||||
|
||||
dndModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[]
|
||||
{
|
||||
getResources().getString(R.string.dndOff),
|
||||
getResources().getString(R.string.dndPriority),
|
||||
getResources().getString(R.string.dndNothing),
|
||||
getResources().getString(R.string.dndAlarms)
|
||||
});
|
||||
spinnerDndMode.setAdapter(dndModeAdapter);
|
||||
/*
|
||||
Order in spinner: 1, 2, 4, 3
|
||||
NotificationManager.INTERRUPTION_FILTER_UNKNOWN -> Returned when the value is unavailable for any reason.
|
||||
NotificationManager.INTERRUPTION_FILTER_ALL -> 1 -> Normal interruption filter - no notifications are suppressed. -> essentially turn off DND
|
||||
NotificationManager.INTERRUPTION_FILTER_PRIORITY -> 2 -> Priority interruption filter - all notifications are suppressed except those that match the priority criteria.
|
||||
NotificationManager.INTERRUPTION_FILTER_ALARMS -> 4 -> Alarms only interruption filter - all notifications except those of category
|
||||
NotificationManager.INTERRUPTION_FILTER_NONE -> 3 -> No interruptions filter - all notifications are suppressed and all audio streams (except those used for phone calls) and vibrations are muted.
|
||||
*/
|
||||
|
||||
checkBoxChangeSoundMode.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
@ -139,6 +177,14 @@ public class ActivityManageProfile extends Activity
|
||||
spinnerSoundMode.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeDnd.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
spinnerDndMode.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeVolumeMusicVideoGameMedia.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
@ -239,26 +285,26 @@ public class ActivityManageProfile extends Activity
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
try
|
||||
{
|
||||
Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
fileIntent.setType("audio/*");
|
||||
startActivityForResult(Intent.createChooser(fileIntent, "Select a ringtone"), intentCodeRingtonePickerCallsFile);
|
||||
}
|
||||
catch(ActivityNotFoundException e)
|
||||
{
|
||||
// try
|
||||
// {
|
||||
// Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
// fileIntent.setType("audio/*");
|
||||
// startActivityForResult(Intent.createChooser(fileIntent, "Select a ringtone"), intentCodeRingtonePickerCallsFile);
|
||||
// }
|
||||
// catch(ActivityNotFoundException e)
|
||||
// {
|
||||
// Use media browser instead
|
||||
Intent fileSelectionIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit != null)
|
||||
{
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.incomingCallsRingtone.getAbsolutePath());
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.incomingCallsRingtone);
|
||||
if(ActivityMainProfiles.profileToEdit.changeIncomingCallsRingtone)
|
||||
fileSelectionIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currenturi);
|
||||
}
|
||||
|
||||
startActivityForResult(fileSelectionIntent, intentCodeRingtonePickerCallsRingtone);
|
||||
}
|
||||
// }
|
||||
}
|
||||
});
|
||||
bChangeSoundNotifications.setOnClickListener(new OnClickListener()
|
||||
@ -279,7 +325,7 @@ public class ActivityManageProfile extends Activity
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit != null)
|
||||
{
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.notificationRingtone.getAbsolutePath());
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.notificationRingtone);
|
||||
if(ActivityMainProfiles.profileToEdit.changeNotificationRingtone)
|
||||
fileSelectionIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currenturi);
|
||||
}
|
||||
@ -325,8 +371,11 @@ 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());
|
||||
checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia());
|
||||
checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications());
|
||||
checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms());
|
||||
@ -338,6 +387,7 @@ public class ActivityManageProfile extends Activity
|
||||
checkBoxChangeVibrateWhenRinging.setChecked(ActivityMainProfiles.profileToEdit.getChangeVibrateWhenRinging());
|
||||
|
||||
spinnerSoundMode.setSelection(ActivityMainProfiles.profileToEdit.getSoundMode());
|
||||
spinnerDndMode.setSelection(ActivityMainProfiles.profileToEdit.getDndMode()-1);
|
||||
seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic());
|
||||
seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications());
|
||||
seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms());
|
||||
@ -348,6 +398,8 @@ public class ActivityManageProfile extends Activity
|
||||
|
||||
setIncomingCallsRingtone(ActivityMainProfiles.profileToEdit.getIncomingCallsRingtone());
|
||||
setNotificationsRingtone(ActivityMainProfiles.profileToEdit.getNotificationRingtone());
|
||||
|
||||
guiUpdate = false;
|
||||
}
|
||||
|
||||
private boolean loadFormValuesToVariable()
|
||||
@ -359,6 +411,7 @@ public class ActivityManageProfile extends Activity
|
||||
|
||||
ActivityMainProfiles.profileToEdit.setName(etName.getText().toString());
|
||||
ActivityMainProfiles.profileToEdit.setChangeSoundMode(checkBoxChangeSoundMode.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeDndMode(checkBoxChangeDnd.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked());
|
||||
@ -374,6 +427,7 @@ public class ActivityManageProfile extends Activity
|
||||
ActivityMainProfiles.profileToEdit.setHapticFeedback(checkBoxHapticFeedback.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setVibrateWhenRinging(checkBoxVibrateWhenRinging.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setSoundMode(spinnerSoundMode.getSelectedItemPosition());
|
||||
ActivityMainProfiles.profileToEdit.setDndMode(spinnerDndMode.getSelectedItemPosition()+1);
|
||||
ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress());
|
||||
ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress());
|
||||
ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress());
|
||||
@ -401,21 +455,23 @@ public class ActivityManageProfile extends Activity
|
||||
}
|
||||
|
||||
if(!checkBoxChangeSoundMode.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeDnd.isChecked()
|
||||
&&
|
||||
!checkBoxChangeVolumeMusicVideoGameMedia.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeVolumeNotifications.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeVolumeAlarms.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeIncomingCallsRingtone.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeNotificationRingtone.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeAudibleSelection.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeScreenLockUnlockSound.isChecked()
|
||||
&
|
||||
&&
|
||||
!checkBoxChangeHapticFeedback.isChecked()
|
||||
)
|
||||
{
|
||||
@ -440,15 +496,20 @@ public class ActivityManageProfile extends Activity
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
if (uri != null)
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, uri);
|
||||
setIncomingCallsRingtone(new File(ringTonePath));
|
||||
// if(Build.VERSION.SDK_INT < 26)
|
||||
// {
|
||||
// String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, uri);
|
||||
// setIncomingCallsRingtone(ringTonePath);
|
||||
// }
|
||||
// else
|
||||
setIncomingCallsRingtone(uri.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerCallsFile:
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, data.getData());
|
||||
setIncomingCallsRingtone(new File(ringTonePath));
|
||||
setIncomingCallsRingtone(ringTonePath);
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerNotificationsRingtone: // notifications
|
||||
@ -456,15 +517,20 @@ public class ActivityManageProfile extends Activity
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
if (uri != null)
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, data.getData());
|
||||
setNotificationsRingtone(new File(ringTonePath));
|
||||
// if(Build.VERSION.SDK_INT < 26)
|
||||
// {
|
||||
// String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, uri);
|
||||
// setNotificationsRingtone(ringTonePath);
|
||||
// }
|
||||
// else
|
||||
setNotificationsRingtone(uri.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerNotificationsFile:
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageProfile.this, data.getData());
|
||||
setNotificationsRingtone(new File(ringTonePath));
|
||||
setNotificationsRingtone(ringTonePath);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@ -12,6 +13,7 @@ import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
@ -22,6 +24,7 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange;
|
||||
Button bSaveBluetoothTrigger;
|
||||
Spinner spinnerBluetoothDevices;
|
||||
TextView tvBluetoothNotPresentNotice;
|
||||
|
||||
ArrayAdapter<String> bluetoothDevicesSpinnerAdapter;
|
||||
|
||||
@ -29,7 +32,8 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_bluetooth_trigger);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_bluetooth);
|
||||
|
||||
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
|
||||
radioNoDevice = (RadioButton)findViewById(R.id.radioNoDevice);
|
||||
@ -40,9 +44,15 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
radioBluetoothOutRange = (RadioButton)findViewById(R.id.radioBluetoothOutRange);
|
||||
bSaveBluetoothTrigger = (Button)findViewById(R.id.bSaveBluetoothTrigger);
|
||||
spinnerBluetoothDevices = (Spinner)findViewById(R.id.spinnerBluetoothDevices);
|
||||
tvBluetoothNotPresentNotice = (TextView)findViewById(R.id.tvBluetoothNotPresentNotice);
|
||||
|
||||
bluetoothDevicesSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, BluetoothReceiver.getAllPairedBluetoothDevicesStrings());
|
||||
|
||||
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
|
||||
tvBluetoothNotPresentNotice.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvBluetoothNotPresentNotice.setVisibility(View.GONE);
|
||||
|
||||
radioDeviceFromList.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
|
@ -0,0 +1,422 @@
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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,404 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageTriggerCalendar extends Activity
|
||||
{
|
||||
CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent, chkCalendarEvaluateAllDayEvent, chkCalendarEvaluateReoccurring, chkCalendarReoccurring;
|
||||
Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection;
|
||||
EditText etCalendarTitle, etCalendarLocation, etCalendarDescription;
|
||||
LinearLayout llCalendarSelection;
|
||||
Button bSaveTriggerCalendar;
|
||||
List<CheckBox> checkboxesCalendars = new ArrayList<>();
|
||||
final static String separator = ",";
|
||||
TextView tvMissingCalendarHint;
|
||||
|
||||
private static String[] directions;
|
||||
ArrayAdapter<String> directionSpinnerAdapter;
|
||||
public static int requestCodePermissionReadCalendar = 815;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_calendar);
|
||||
|
||||
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
|
||||
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
|
||||
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);
|
||||
spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection);
|
||||
chkCalendarAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarAllDayEvent);
|
||||
chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy);
|
||||
chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree);
|
||||
chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative);
|
||||
chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice);
|
||||
chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere);
|
||||
chkCalendarEvaluateAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarEvaluateAllDayEvent);
|
||||
chkCalendarEvaluateReoccurring = (CheckBox)findViewById(R.id.chkCalendarEvaluateReoccurring);
|
||||
chkCalendarReoccurring = (CheckBox)findViewById(R.id.chkCalendarReoccurring);
|
||||
|
||||
tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint);
|
||||
|
||||
llCalendarSelection = (LinearLayout)findViewById(R.id.llCalendarSelection);
|
||||
|
||||
etCalendarTitle = (EditText)findViewById(R.id.etCalendarTitle);
|
||||
etCalendarLocation = (EditText)findViewById(R.id.etCalendarLocation);
|
||||
etCalendarDescription = (EditText)findViewById(R.id.etCalendarDescription);
|
||||
|
||||
bSaveTriggerCalendar = (Button)findViewById(R.id.bSaveTriggerCalendar);
|
||||
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringDoesNotContain),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
};
|
||||
directionSpinnerAdapter = new ArrayAdapter<>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageTriggerCalendar.directions);
|
||||
spinnerCalendarTitleDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarLocationDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter);
|
||||
directionSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
chkCalendarEvaluateAllDayEvent.setChecked(false);
|
||||
chkCalendarAllDayEvent.setEnabled(false);
|
||||
chkCalendarEvaluateAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
chkCalendarAllDayEvent.setEnabled(checked);
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarEvaluateReoccurring.setChecked(false);
|
||||
chkCalendarReoccurring.setEnabled(false);
|
||||
chkCalendarEvaluateReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
chkCalendarReoccurring.setEnabled(checked);
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this))
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerCalendar.this);
|
||||
builder.setTitle(getResources().getString(R.string.info));
|
||||
builder.setMessage(getResources().getString(R.string.permissionCalendarRequired));
|
||||
builder.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
ActivityManageTriggerCalendar.this.finish();
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
requestPermissions(new String[]{ Manifest.permission.READ_CALENDAR } , requestCodePermissionReadCalendar);
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
else
|
||||
populateCalenderCheckboxes();
|
||||
|
||||
chkCalendarEventActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyHappening);
|
||||
else
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyNotHappening);
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventTrue));
|
||||
else
|
||||
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventFalse));
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarReoccurring.setText(R.string.reoccurringTrue);
|
||||
else
|
||||
chkCalendarReoccurring.setText(R.string.reoccurringFalse);
|
||||
}
|
||||
});
|
||||
|
||||
bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
String titleDir = Trigger.getMatchCode(spinnerCalendarTitleDirection.getSelectedItem().toString());
|
||||
String title = etCalendarTitle.getText().toString();
|
||||
String descriptionDir = Trigger.getMatchCode(spinnerCalendarDescriptionDirection.getSelectedItem().toString());
|
||||
String description = etCalendarDescription.getText().toString();
|
||||
String locationDir = Trigger.getMatchCode(spinnerCalendarLocationDirection.getSelectedItem().toString());
|
||||
String location = etCalendarLocation.getText().toString();
|
||||
|
||||
List<String> availabilityList = new ArrayList<>();
|
||||
if(chkCalendarAvailabilityBusy.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_BUSY));
|
||||
|
||||
if(chkCalendarAvailabilityFree.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_FREE));
|
||||
|
||||
if(chkCalendarAvailabilityTentative.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_TENTATIVE));
|
||||
|
||||
if(chkCalendarAvailabilityOutOfOffice.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE));
|
||||
|
||||
if(chkCalendarAvailabilityWorkingElsewhere.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE));
|
||||
|
||||
List<CalendarReceiver.AndroidCalendar> selectedCalendarsList = new ArrayList<>();
|
||||
for(CheckBox calCheckbox : checkboxesCalendars)
|
||||
{
|
||||
if(calCheckbox.isChecked())
|
||||
selectedCalendarsList.add((CalendarReceiver.AndroidCalendar) calCheckbox.getTag());
|
||||
}
|
||||
List<String> selectedCalendarsIdArray = new ArrayList<>();
|
||||
for(CalendarReceiver.AndroidCalendar cal : selectedCalendarsList)
|
||||
selectedCalendarsIdArray.add(String.valueOf(cal.calendarId));
|
||||
|
||||
String returnString =
|
||||
titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split +
|
||||
descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split +
|
||||
locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarEvaluateAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarEvaluateReoccurring.isChecked()) + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarReoccurring.isChecked()) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()]));
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkCalendarEventActive.isChecked());
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, returnString);
|
||||
ActivityManageTriggerCalendar.this.setResult(RESULT_OK, data);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Intent inputIntent = getIntent();
|
||||
if(inputIntent.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
loadValuesIntoGui(inputIntent);
|
||||
}
|
||||
|
||||
private void populateCalenderCheckboxes()
|
||||
{
|
||||
List<CalendarReceiver.AndroidCalendar> calList = CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this);
|
||||
|
||||
if(calList != null)
|
||||
{
|
||||
if(calList.size() > 0)
|
||||
{
|
||||
for (CalendarReceiver.AndroidCalendar cal : calList)
|
||||
{
|
||||
CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this);
|
||||
oneCalCheckbox.setText(cal.toString());
|
||||
oneCalCheckbox.setTag(cal);
|
||||
llCalendarSelection.addView(oneCalCheckbox);
|
||||
checkboxesCalendars.add(oneCalCheckbox);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.noCalendarsOnYourDevice), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.errorReadingCalendars), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
|
||||
void loadValuesIntoGui(Intent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
chkCalendarEventActive.setChecked(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
|
||||
if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split, -1);
|
||||
/*
|
||||
0 = titleDir
|
||||
1 = title
|
||||
2 = descriptionDir
|
||||
3 = description
|
||||
4 = locationDir
|
||||
5 = location
|
||||
6 = evaluate all day event
|
||||
7 = all day event
|
||||
8 = evaluate reoccurring
|
||||
9 = reoccurring
|
||||
10 = availability list
|
||||
11 = calendars list
|
||||
*/
|
||||
|
||||
for (int i = 0; i < directions.length; i++)
|
||||
{
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[0]))
|
||||
spinnerCalendarTitleDirection.setSelection(i);
|
||||
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[2]))
|
||||
spinnerCalendarDescriptionDirection.setSelection(i);
|
||||
|
||||
if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[4]))
|
||||
spinnerCalendarLocationDirection.setSelection(i);
|
||||
}
|
||||
|
||||
etCalendarTitle.setText(input[1]);
|
||||
etCalendarDescription.setText(input[3]);
|
||||
etCalendarLocation.setText(input[5]);
|
||||
|
||||
chkCalendarEvaluateAllDayEvent.setChecked(Boolean.parseBoolean(input[6]));
|
||||
chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[7]));
|
||||
|
||||
chkCalendarEvaluateReoccurring.setChecked(Boolean.parseBoolean(input[8]));
|
||||
chkCalendarReoccurring.setChecked(Boolean.parseBoolean(input[9]));
|
||||
|
||||
String[] availabilities = null;
|
||||
if (!StringUtils.isEmpty(input[10]))
|
||||
availabilities = input[10].split(separator);
|
||||
|
||||
if (availabilities != null)
|
||||
{
|
||||
for (String avail : availabilities)
|
||||
{
|
||||
if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY)
|
||||
chkCalendarAvailabilityBusy.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_FREE)
|
||||
chkCalendarAvailabilityFree.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_TENTATIVE)
|
||||
chkCalendarAvailabilityTentative.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE)
|
||||
chkCalendarAvailabilityOutOfOffice.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE)
|
||||
chkCalendarAvailabilityWorkingElsewhere.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
String[] calendars = null;
|
||||
if (!StringUtils.isEmpty(input[11]))
|
||||
calendars = input[11].split(separator);
|
||||
|
||||
if (calendars != null)
|
||||
{
|
||||
List<String> usedCalendarIDs = new ArrayList<>();
|
||||
List<String> unusedCalendarIDs = new ArrayList<>();
|
||||
for (CheckBox checkbox : checkboxesCalendars)
|
||||
{
|
||||
int id = ((CalendarReceiver.AndroidCalendar) checkbox.getTag()).calendarId;
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (calId.equals(String.valueOf(id)))
|
||||
{
|
||||
usedCalendarIDs.add(String.valueOf(id));
|
||||
checkbox.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch((ArrayList<String>) usedCalendarIDs, calId, false, true))
|
||||
unusedCalendarIDs.add(calId);
|
||||
}
|
||||
if (unusedCalendarIDs.size() > 0)
|
||||
{
|
||||
/*
|
||||
A calendar has been configured that has been deleted since. We cannot resolve it.
|
||||
It will be removed with the next save, but we should inform this user
|
||||
of these circumstances.
|
||||
*/
|
||||
|
||||
tvMissingCalendarHint.setText(String.format(getResources().getString(R.string.calendarsMissingHint), Miscellaneous.explode(", ", (ArrayList<String>) unusedCalendarIDs)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActivityManagerTriggerCalender", "Error loading values into GUI: " + Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(ActivityManageTriggerCalendar.this, getResources().getString(R.string.errorLoadingValues), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
if(requestCode == requestCodePermissionReadCalendar)
|
||||
{
|
||||
if(
|
||||
permissions[0].equals(Manifest.permission.READ_CALENDAR)
|
||||
||
|
||||
permissions[0].equals(Manifest.permission.WRITE_CALENDAR)
|
||||
)
|
||||
{
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.ActivityManageRule;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.R;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageTriggerCharging extends Activity
|
||||
{
|
||||
RadioButton rbChargingOn, rbChargingOff, rbChargingTypeAny, rbChargingTypeAc, rbChargingTypeUsb, rbChargingTypeWireless;
|
||||
Button bTriggerChargingSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_charging);
|
||||
|
||||
rbChargingOn = (RadioButton) findViewById(R.id.rbChargingOn);
|
||||
rbChargingOff = (RadioButton) findViewById(R.id.rbChargingOff);
|
||||
rbChargingTypeAny = (RadioButton) findViewById(R.id.rbChargingTypeAny);
|
||||
rbChargingTypeAc = (RadioButton) findViewById(R.id.rbChargingTypeAc);
|
||||
rbChargingTypeUsb = (RadioButton) findViewById(R.id.rbChargingTypeUsb);
|
||||
rbChargingTypeWireless = (RadioButton) findViewById(R.id.rbChargingTypeWireless);
|
||||
|
||||
bTriggerChargingSave = (Button) findViewById(R.id.bTriggerChargingSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
{
|
||||
|
||||
rbChargingOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
rbChargingOff.setChecked(!input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, false));
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
|
||||
String[] params2 = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
|
||||
int chargingType = Integer.parseInt(params2[0]);
|
||||
|
||||
rbChargingTypeAny.setChecked(chargingType == 0);
|
||||
rbChargingTypeAc.setChecked(chargingType == BatteryManager.BATTERY_PLUGGED_AC);
|
||||
rbChargingTypeUsb.setChecked(chargingType == BatteryManager.BATTERY_PLUGGED_USB);
|
||||
rbChargingTypeWireless.setChecked(chargingType == BatteryManager.BATTERY_PLUGGED_WIRELESS);
|
||||
}
|
||||
}
|
||||
|
||||
bTriggerChargingSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbChargingOn.isChecked());
|
||||
|
||||
String param2 = "";
|
||||
|
||||
if(rbChargingTypeAny.isChecked())
|
||||
param2 = "0";
|
||||
else if(rbChargingTypeAc.isChecked())
|
||||
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_AC);
|
||||
else if(rbChargingTypeUsb.isChecked())
|
||||
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_USB);
|
||||
else if(rbChargingTypeWireless.isChecked())
|
||||
param2 = String.valueOf(BatteryManager.BATTERY_PLUGGED_WIRELESS);
|
||||
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, param2);
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
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 androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageTriggerCheckVariable extends Activity
|
||||
{
|
||||
EditText etVariableKeyTrigger, etVariableValueTrigger;
|
||||
Button bTriggerVariableSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_check_variable);
|
||||
|
||||
etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger);
|
||||
etVariableValueTrigger = (EditText) findViewById(R.id.etVariableValueTrigger);
|
||||
bTriggerVariableSave = (Button) findViewById(R.id.bTriggerVariableSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
String[] conditions = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
|
||||
etVariableKeyTrigger.setText(conditions[0]);
|
||||
if(conditions.length > 1)
|
||||
etVariableValueTrigger.setText(conditions[1]);
|
||||
}
|
||||
|
||||
bTriggerVariableSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
// response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbTetheringOn.isChecked());
|
||||
|
||||
if(StringUtils.isEmpty(etVariableValueTrigger.getText().toString()))
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, etVariableKeyTrigger.getText().toString());
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, etVariableKeyTrigger.getText().toString() + Trigger.triggerParameter2Split + etVariableValueTrigger.getText().toString());
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,298 @@
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ public class ActivityManageTriggerNfc extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_nfc);
|
||||
|
||||
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
|
||||
|
@ -31,14 +31,22 @@ import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class ActivityManageTriggerNotification extends Activity
|
||||
{
|
||||
public static final String intentNameNotificationApp = "app";
|
||||
public static final String intentNameNotificationTitleDir = "titleDir";
|
||||
public static final String intentNameNotificationTitle = "title";
|
||||
public static final String intentNameNotificationTextDir = "textDir";
|
||||
public static final String intentNameNotificationText = "text";
|
||||
public static final String intentNameNotificationDirection = "direction";
|
||||
|
||||
public static Trigger editedNotificationTrigger;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
EditText etNotificationTitle, etNotificationText;
|
||||
Button bSelectApp, bSaveTriggerNotification;
|
||||
Spinner spinnerTitleDirection, spinnerTextDirection;
|
||||
TextView tvSelectedApplication;
|
||||
CheckBox chkNotificationDirection;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
public static Trigger resultingTrigger;
|
||||
@ -250,20 +258,22 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_trigger_notification);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_notification);
|
||||
|
||||
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.etSelectedApplication);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etActivityOrActionPath);
|
||||
chkNotificationDirection = (CheckBox)findViewById(R.id.chkNotificationDirection);
|
||||
|
||||
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)
|
||||
@ -304,7 +314,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();
|
||||
|
||||
@ -313,23 +323,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);
|
||||
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();
|
||||
}
|
||||
@ -359,7 +360,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++)
|
||||
@ -393,7 +394,5 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class ActivityManageTriggerPhoneCall extends Activity
|
||||
{
|
||||
public static Trigger editedPhoneCallTrigger;
|
||||
boolean edit = false;
|
||||
public static Trigger resultingTrigger;
|
||||
ProgressDialog progressDialog = null;
|
||||
protected final static int requestCodeForContactsPermissions = 2345;
|
||||
protected final static int requestCodeGetContact = 3235;
|
||||
|
||||
EditText etTriggerPhoneCallPhoneNumber;
|
||||
RadioButton rbTriggerPhoneCallStateRinging, rbTriggerPhoneCallStateStarted, rbTriggerPhoneCallStateStopped, rbTriggerPhoneCallDirectionAny, rbTriggerPhoneCallDirectionIncoming, rbTriggerPhoneCallDirectionOutgoing;
|
||||
Button bSaveTriggerPhoneCall, bTriggerPhoneCallImportFromContacts;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_phone_call);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
|
||||
rbTriggerPhoneCallStateRinging = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateRinging);
|
||||
rbTriggerPhoneCallStateStarted = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStarted);
|
||||
rbTriggerPhoneCallStateStopped = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStopped);
|
||||
rbTriggerPhoneCallDirectionAny = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionAny);
|
||||
rbTriggerPhoneCallDirectionIncoming = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionIncoming);
|
||||
rbTriggerPhoneCallDirectionOutgoing = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionOutgoing);
|
||||
bTriggerPhoneCallImportFromContacts = (Button) findViewById(R.id.bTriggerPhoneCallImportFromContacts);
|
||||
bSaveTriggerPhoneCall = (Button) findViewById(R.id.bSaveTriggerPhoneCall);
|
||||
|
||||
bSaveTriggerPhoneCall.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
String tp2Result = "";
|
||||
|
||||
if(rbTriggerPhoneCallStateRinging.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateRinging;
|
||||
else if(rbTriggerPhoneCallStateStarted.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateStarted;
|
||||
else if(rbTriggerPhoneCallStateStopped.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateStopped;
|
||||
|
||||
tp2Result += triggerParameter2Split;
|
||||
|
||||
if(rbTriggerPhoneCallDirectionAny.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionAny;
|
||||
else if(rbTriggerPhoneCallDirectionIncoming.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionIncoming;
|
||||
else if(rbTriggerPhoneCallDirectionOutgoing.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionOutgoing;
|
||||
|
||||
tp2Result += triggerParameter2Split;
|
||||
|
||||
if(etTriggerPhoneCallPhoneNumber.getText() != null && etTriggerPhoneCallPhoneNumber.getText().toString().length() > 0)
|
||||
tp2Result += etTriggerPhoneCallPhoneNumber.getText().toString();
|
||||
else
|
||||
tp2Result += Trigger.triggerPhoneCallNumberAny;
|
||||
|
||||
if(edit)
|
||||
{
|
||||
editedPhoneCallTrigger.setTriggerParameter(false);
|
||||
editedPhoneCallTrigger.setTriggerParameter2(tp2Result);
|
||||
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent data = new Intent();
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, false);
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, tp2Result);
|
||||
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK, data);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
bTriggerPhoneCallImportFromContacts.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageTriggerPhoneCall.this))
|
||||
{
|
||||
requestPermissions("android.permission.READ_CONTACTS");
|
||||
}
|
||||
else
|
||||
openContactsDialogue();
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui();
|
||||
}
|
||||
}
|
||||
|
||||
protected void requestPermissions(String... requiredPermissions)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(requiredPermissions.length > 0)
|
||||
{
|
||||
StringBuilder permissions = new StringBuilder();
|
||||
for (String perm : requiredPermissions)
|
||||
permissions.append(perm + "; ");
|
||||
if (permissions.length() > 0)
|
||||
permissions.delete(permissions.length() - 2, permissions.length());
|
||||
|
||||
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
|
||||
|
||||
requestPermissions(requiredPermissions, requestCodeForContactsPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openContactsDialogue()
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
|
||||
startActivityForResult(intent, requestCodeGetContact);
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
String[] parts = editedPhoneCallTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
if(parts[0].equals(Trigger.triggerPhoneCallStateRinging))
|
||||
rbTriggerPhoneCallStateRinging.setChecked(true);
|
||||
else if(parts[0].equals(Trigger.triggerPhoneCallStateStarted))
|
||||
rbTriggerPhoneCallStateStarted.setChecked(true);
|
||||
else if(parts[0].equals(Trigger.triggerPhoneCallStateStopped))
|
||||
rbTriggerPhoneCallStateStopped.setChecked(true);
|
||||
|
||||
if(parts[1].equals(Trigger.triggerPhoneCallDirectionAny))
|
||||
rbTriggerPhoneCallDirectionAny.setChecked(true);
|
||||
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionIncoming))
|
||||
rbTriggerPhoneCallDirectionIncoming.setChecked(true);
|
||||
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionOutgoing))
|
||||
rbTriggerPhoneCallDirectionOutgoing.setChecked(true);
|
||||
|
||||
if(!parts[2].equals(Trigger.triggerPhoneCallNumberAny))
|
||||
etTriggerPhoneCallPhoneNumber.setText(parts[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(requestCode == requestCodeGetContact)
|
||||
{
|
||||
if(resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
String phoneNo = null;
|
||||
String name = null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
Cursor cursor = ActivityManageTriggerPhoneCall.this.getContentResolver().query(uri, null, null, null, null);
|
||||
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
|
||||
int nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
|
||||
|
||||
phoneNo = cursor.getString(phoneIndex);
|
||||
name = cursor.getString(nameIndex);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber.setText(phoneNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
//super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
if(requestCode == requestCodeForContactsPermissions)
|
||||
{
|
||||
for(int i=0; i<permissions.length; i++)
|
||||
{
|
||||
if(permissions[i].equals("android.permission.READ_CONTACTS"))
|
||||
{
|
||||
if(grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
openContactsDialogue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
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);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
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 androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.Trigger.subSystemStates;
|
||||
|
||||
public class ActivityManageTriggerSubSystemState extends Activity
|
||||
{
|
||||
RadioButton rbSubSystemStateWifi, rbSubSystemStateBluetooth;
|
||||
RadioButton rbSubSystemStateEnabled, rbSubSystemStateDisabled;
|
||||
Button bSubSystemStateSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_subsystemstate);
|
||||
|
||||
rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi);
|
||||
rbSubSystemStateBluetooth = (RadioButton)findViewById(R.id.rbSubSystemStateBluetooth);
|
||||
rbSubSystemStateEnabled = (RadioButton)findViewById(R.id.rbSubSystemStateEnabled);
|
||||
rbSubSystemStateDisabled = (RadioButton)findViewById(R.id.rbSubSystemStateDisabled);
|
||||
bSubSystemStateSave = (Button)findViewById(R.id.bSubSystemStateSave);
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter1) && getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
subSystemStates desiredState = subSystemStates.valueOf(getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
|
||||
|
||||
switch(desiredState)
|
||||
{
|
||||
case wifi:
|
||||
rbSubSystemStateWifi.setChecked(true);
|
||||
break;
|
||||
case bluetooth:
|
||||
rbSubSystemStateBluetooth.setChecked(true);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if(getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true))
|
||||
rbSubSystemStateEnabled.setChecked(true);
|
||||
else
|
||||
rbSubSystemStateDisabled.setChecked(true);
|
||||
}
|
||||
|
||||
bSubSystemStateSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent data = new Intent();
|
||||
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbSubSystemStateEnabled.isChecked());
|
||||
|
||||
if(rbSubSystemStateWifi.isChecked())
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, subSystemStates.wifi.name());
|
||||
else if(rbSubSystemStateBluetooth.isChecked())
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, subSystemStates.bluetooth.name());
|
||||
|
||||
ActivityManageTriggerSubSystemState.this.setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
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 androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageTriggerTethering extends Activity
|
||||
{
|
||||
RadioButton rbTetheringOn, rbTetheringOff, rbTetheringTypeAny, rbTetheringTypeWifi, rbTetheringTypeBluetooth, rbTetheringTypeUsb, rbTetheringTypeCable;
|
||||
Button bTriggerTetheringSave;
|
||||
|
||||
public final static String tetheringTypeAny = "tetheringTypeAny";
|
||||
public final static String tetheringTypeWifi = "tetheringTypeWifi";
|
||||
public final static String tetheringTypeBluetooth = "tetheringTypeBluetooth";
|
||||
public final static String tetheringTypeUsb = "tetheringTypeUsb";
|
||||
public final static String tetheringTypeCable = "tetheringTypeCable";
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_tethering);
|
||||
|
||||
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
|
||||
rbTetheringOff = (RadioButton)findViewById(R.id.rbTetheringOff);
|
||||
rbTetheringTypeAny = (RadioButton) findViewById(R.id.rbTetheringTypeAny);
|
||||
rbTetheringTypeWifi = (RadioButton) findViewById(R.id.rbTetheringTypeWifi);
|
||||
rbTetheringTypeBluetooth = (RadioButton) findViewById(R.id.rbTetheringTypeBluetooth);
|
||||
rbTetheringTypeUsb = (RadioButton) findViewById(R.id.rbTetheringTypeUsb);
|
||||
rbTetheringTypeCable = (RadioButton) findViewById(R.id.rbTetheringTypeCable);
|
||||
bTriggerTetheringSave = (Button) findViewById(R.id.bTriggerTetheringSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
{
|
||||
rbTetheringOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
rbTetheringOff.setChecked(!input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, false));
|
||||
}
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
String type = input.getStringExtra(ActivityManageRule.intentNameTriggerParameter2);
|
||||
|
||||
if(!StringUtils.isEmpty(type))
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case tetheringTypeAny:
|
||||
rbTetheringTypeAny.setChecked(true);
|
||||
break;
|
||||
case tetheringTypeWifi:
|
||||
rbTetheringTypeWifi.setChecked(true);
|
||||
break;
|
||||
case tetheringTypeBluetooth:
|
||||
rbTetheringTypeBluetooth.setChecked(true);
|
||||
break;
|
||||
case tetheringTypeUsb:
|
||||
rbTetheringTypeUsb.setChecked(true);
|
||||
break;
|
||||
case tetheringTypeCable:
|
||||
rbTetheringTypeCable.setChecked(true);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rbTetheringTypeAny.setChecked(true);
|
||||
|
||||
bTriggerTetheringSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbTetheringOn.isChecked());
|
||||
|
||||
if(rbTetheringTypeAny.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, tetheringTypeAny);
|
||||
else if(rbTetheringTypeWifi.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, tetheringTypeWifi);
|
||||
else if(rbTetheringTypeBluetooth.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, tetheringTypeBluetooth);
|
||||
else if(rbTetheringTypeUsb.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, tetheringTypeUsb);
|
||||
else if(rbTetheringTypeCable.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, tetheringTypeCable);
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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,16 +24,19 @@ 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)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_trigger_timeframe);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_timeframe);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
|
||||
@ -44,17 +53,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());
|
||||
|
||||
@ -94,9 +106,41 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
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,19 +148,69 @@ 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());
|
||||
editedTimeFrameTrigger.setTriggerParameter2(editedTimeFrameTrigger.getTimeFrame().toTriggerParameter2String());
|
||||
|
||||
setResult(RESULT_OK);
|
||||
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()
|
||||
{
|
||||
startPicker.setCurrentHour(editedTimeFrameTrigger.getTimeFrame().getTriggerTimeStart().getHours());
|
||||
@ -158,6 +252,11 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(editedTimeFrameTrigger.getTimeFrame().getRepetition() > 0)
|
||||
{
|
||||
chkRepeat.setChecked(true);
|
||||
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageTriggerWifi extends Activity
|
||||
{
|
||||
public final static String intentNameWifiState = "wifiState";
|
||||
public final static String intentNameWifiName = "wifiName";
|
||||
|
||||
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
|
||||
EditText etTriggerWifiName;
|
||||
Spinner spinnerWifiList;
|
||||
Button bTriggerWifiSave, bLoadWifiList;
|
||||
List<String> wifiList = new ArrayList<>();
|
||||
ArrayAdapter<String> wifiSpinnerAdapter;
|
||||
private final static int requestCodeLocationPermission = 124;
|
||||
TextView tvWifiTriggerNameLocationNotice, tvWifiTriggerDisconnectionHint;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_wifi);
|
||||
|
||||
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
|
||||
rbTriggerWifiDisconnected = (RadioButton) findViewById(R.id.rbTriggerWifiDisconnected);
|
||||
etTriggerWifiName = (EditText) findViewById(R.id.etTriggerWifiName);
|
||||
spinnerWifiList = (Spinner) findViewById(R.id.spinnerWifiList);
|
||||
bTriggerWifiSave = (Button) findViewById(R.id.bTriggerWifiSave);
|
||||
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
|
||||
tvWifiTriggerNameLocationNotice = (TextView)findViewById(R.id.tvWifiTriggerNameLocationNotice);
|
||||
tvWifiTriggerDisconnectionHint = (TextView)findViewById(R.id.tvWifiTriggerDisconnectionHint);
|
||||
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
|
||||
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
|
||||
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
|
||||
spinnerWifiList.setEnabled(false); // bug in Android; this only works when done in code, not in xml
|
||||
|
||||
if(
|
||||
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
|
||||
&&
|
||||
!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
)
|
||||
tvWifiTriggerNameLocationNotice.setVisibility(View.VISIBLE);
|
||||
|
||||
if (getIntent().hasExtra("edit"))
|
||||
{
|
||||
boolean connected = getIntent().getBooleanExtra("wifiState", false);
|
||||
String wifiName = getIntent().getStringExtra("wifiName");
|
||||
|
||||
rbTriggerWifiConnected.setChecked(connected);
|
||||
rbTriggerWifiDisconnected.setChecked(!connected);
|
||||
|
||||
etTriggerWifiName.setText(wifiName);
|
||||
}
|
||||
|
||||
bTriggerWifiSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra("wifiState", rbTriggerWifiConnected.isChecked());
|
||||
response.putExtra("wifiName", etTriggerWifiName.getText().toString());
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
spinnerWifiList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
etTriggerWifiName.setText(wifiList.get(position));
|
||||
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
bLoadWifiList.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
loadWifis();
|
||||
}
|
||||
});
|
||||
|
||||
rbTriggerWifiDisconnected.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && b)
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
etTriggerWifiName.addTextChangedListener(new TextWatcher()
|
||||
{
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadWifis()
|
||||
{
|
||||
if(!ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityManageTriggerWifi.this))
|
||||
{
|
||||
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.permissionsTitle), getResources().getString(R.string.needLocationPermForWifiList), ActivityManageTriggerWifi.this);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{
|
||||
ActivityCompat.requestPermissions(ActivityManageTriggerWifi.this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, requestCodeLocationPermission);
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
reallyLoadWifiList();
|
||||
}
|
||||
}
|
||||
|
||||
void reallyLoadWifiList()
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= 30)
|
||||
{
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.wifiApi30), ActivityManageTriggerWifi.this).show();
|
||||
loadListOfVisibleWifis();
|
||||
}
|
||||
else
|
||||
{
|
||||
WifiManager myWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||
|
||||
for (WifiConfiguration wifi : myWifiManager.getConfiguredNetworks())
|
||||
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
|
||||
}
|
||||
|
||||
if (wifiList.size() > 0)
|
||||
{
|
||||
spinnerWifiList.setEnabled(true);
|
||||
Collections.sort(wifiList);
|
||||
}
|
||||
else
|
||||
{
|
||||
spinnerWifiList.setEnabled(false);
|
||||
Toast.makeText(ActivityManageTriggerWifi.this, getResources().getString(R.string.noKnownWifis), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
wifiSpinnerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
void loadListOfVisibleWifis()
|
||||
{
|
||||
List<ScanResult> results = null;
|
||||
|
||||
try
|
||||
{
|
||||
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
results = wifiManager.getScanResults();
|
||||
|
||||
for (ScanResult wifi : results)
|
||||
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "loadListOfVisibleWifis()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
switch (requestCode)
|
||||
{
|
||||
case requestCodeLocationPermission:
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
reallyLoadWifiList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
@ -9,11 +10,26 @@ import com.jens.automation2.R.layout;
|
||||
public class ActivitySettings extends PreferenceActivity
|
||||
{
|
||||
ListPreference lpStartScreenOptionsValues;
|
||||
CheckBoxPreference chkPrefUpdateCheck;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(layout.settings);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
addPreferencesFromResource(layout.activity_settings);
|
||||
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
{
|
||||
chkPrefUpdateCheck = (CheckBoxPreference) findPreference("automaticUpdateCheck");
|
||||
chkPrefUpdateCheck.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
}
|
@ -30,14 +30,15 @@ public class ActivityVolumeTest extends Activity
|
||||
instance = this;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_volume_test);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
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));
|
||||
|
||||
@ -48,20 +49,15 @@ public class ActivityVolumeTest extends Activity
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||
boolean fromUser)
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
||||
{
|
||||
etReferenceValue.setText(String.valueOf(sbReferenceValue.getProgress()));
|
||||
}
|
||||
|
64
app/src/main/java/com/jens/automation2/AsyncTasks.java
Normal file
64
app/src/main/java/com/jens/automation2/AsyncTasks.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AsyncTasks
|
||||
{
|
||||
public static class AsyncTaskUpdateCheck extends AsyncTask<Context, Void, Boolean>
|
||||
{
|
||||
public static boolean checkRunning = false;
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Context... contexts)
|
||||
{
|
||||
if(checkRunning)
|
||||
return false;
|
||||
else
|
||||
checkRunning = true;
|
||||
|
||||
try
|
||||
{
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null, ActivityManageActionTriggerUrl.methodGet, null).trim();
|
||||
int latestVersion = Integer.parseInt(result);
|
||||
|
||||
// At this point the update check itself has already been successful.
|
||||
|
||||
Settings.lastUpdateCheck = Calendar.getInstance().getTimeInMillis();
|
||||
Settings.writeSettings(contexts[0]);
|
||||
|
||||
if (latestVersion > BuildConfig.VERSION_CODE)
|
||||
{
|
||||
// There's a new update
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Error checking for update", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result)
|
||||
{
|
||||
try
|
||||
{
|
||||
ActivityMainScreen.getActivityMainScreenInstance().processUpdateCheckResult(result);
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result, probably ActivityMainScreen isn't currently shown: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
@ -23,24 +24,41 @@ import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
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.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
protected TextToSpeech ttsEngine = null;
|
||||
protected int ttsStatus = -1;
|
||||
protected final static int notificationId = 1000;
|
||||
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";
|
||||
public static final String flavor_name_apk = "apkFlavor";
|
||||
public static final String flavor_name_fdroid = "fdroidFlavor";
|
||||
public static final String flavor_name_googleplay = "googlePlayFlavor";
|
||||
|
||||
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;
|
||||
@ -49,6 +67,10 @@ public class AutomationService extends Service implements OnInitListener
|
||||
protected Calendar lockSoundChangesEnd = null;
|
||||
protected boolean isRunning;
|
||||
|
||||
Map<String,String> variableMap = new HashMap();
|
||||
|
||||
protected static AutomationService centralInstance = null;
|
||||
|
||||
public void nullLockSoundChangesEnd()
|
||||
{
|
||||
lockSoundChangesEnd = null;
|
||||
@ -63,7 +85,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
lockSoundChangesEnd = Calendar.getInstance();
|
||||
|
||||
lockSoundChangesEnd.add(Calendar.MINUTE, Settings.lockSoundChangesInterval);
|
||||
// ActivityMainScreen.getActivityMainScreenInstance().updateMainScreen();
|
||||
}
|
||||
|
||||
public void checkLockSoundChangesTimeElapsed()
|
||||
@ -78,6 +99,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
this.lockSoundChangesEnd = lockSoundChangesEnd;
|
||||
}
|
||||
|
||||
public int getTtsStatus()
|
||||
{
|
||||
return ttsStatus;
|
||||
}
|
||||
|
||||
protected final IBinder myBinder = new LocalBinder();
|
||||
|
||||
protected LocationProvider myLocationProvider;
|
||||
@ -87,8 +113,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
return myLocationProvider;
|
||||
}
|
||||
|
||||
protected static AutomationService centralInstance = null;
|
||||
|
||||
public static AutomationService getInstance()
|
||||
{
|
||||
return centralInstance;
|
||||
@ -103,39 +127,45 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
// Store a reference to myself. Other classes often need a context or something, this can provide that.
|
||||
centralInstance = this;
|
||||
|
||||
/*
|
||||
This has been reported to throw a NullPointerException under
|
||||
rare circumstances. The root cause remains unknown.
|
||||
*/
|
||||
try
|
||||
{
|
||||
Miscellaneous.setDisplayLanguage(AutomationService.this);
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "setDisplayLanguage()", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
|
||||
{
|
||||
// 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(ActivityPermissions.permissionNameStartService, AutomationService.this))
|
||||
if (!ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE, AutomationService.this))
|
||||
{
|
||||
/*
|
||||
Don't have permission to start service. This is a show stopper.
|
||||
*/
|
||||
Miscellaneous.logEvent("e", "Permission", "Don't have permission to start foreground service. Will request it now.", 4);
|
||||
// Toast.makeText(AutomationService.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
ActivityPermissions.requestSpecificPermission(ActivityPermissions.permissionNameStartService);
|
||||
ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -171,7 +201,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();
|
||||
@ -192,17 +222,24 @@ 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), 1);
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
|
||||
Miscellaneous.logEvent("i", "Service", ActivityControlCenter.getSystemInfo(), 1);
|
||||
|
||||
startUpRoutine();
|
||||
|
||||
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
|
||||
if(getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_MUTABLE);
|
||||
else
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
notificationBuilder = createDefaultNotificationBuilder();
|
||||
notificationBuilder = createServiceNotificationBuilder();
|
||||
|
||||
updateNotification();
|
||||
|
||||
@ -210,13 +247,18 @@ public class AutomationService extends Service implements OnInitListener
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
this.isRunning = true;
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " " + String.format(this.getResources().getString(R.string.version), BuildConfig.VERSION_NAME + "(Build " + BuildConfig.VERSION_CODE + ")"), 1);
|
||||
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 **********
|
||||
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
|
||||
|
||||
/*
|
||||
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
|
||||
@ -238,8 +280,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);
|
||||
@ -257,6 +297,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
case reloadSettings:
|
||||
Settings.readFromPersistentStorage(this);
|
||||
applySettingsAndRules();
|
||||
if(myLocationProvider != null)
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
break;
|
||||
case updateNotification:
|
||||
@ -270,16 +311,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();
|
||||
@ -287,6 +319,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
|
||||
ReceiverCoordinator.applySettingsAndRules();
|
||||
|
||||
DateTimeListener.setOrResetAlarms();
|
||||
CalendarReceiver.armOrRearmTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -296,17 +331,36 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
stopRoutine();
|
||||
this.isRunning = false;
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(this, getResources().getString(R.string.serviceStopped), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.serviceStopped), 1);
|
||||
}
|
||||
|
||||
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);
|
||||
} else
|
||||
{
|
||||
ttsEngine = new TextToSpeech(this, new TextToSpeech.OnInitListener()
|
||||
{
|
||||
@Override
|
||||
public void onInit(int status)
|
||||
{
|
||||
ttsStatus = status;
|
||||
|
||||
if (status == TextToSpeech.SUCCESS)
|
||||
{
|
||||
ttsEngine.setLanguage(Locale.getDefault());
|
||||
Miscellaneous.logEvent("i", "TTS engine", "TTS engine available.", 3);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "TTS engine", "TTS engine not available. Status: " + String.valueOf(status), 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ttsEngine != null)
|
||||
ttsEngine.shutdown();
|
||||
@ -315,23 +369,34 @@ 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()
|
||||
{
|
||||
if(ActivityPermissions.havePermission("android.permission.ACCESS_COARSE_LOCATION", AutomationService.this))
|
||||
if(ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.this))
|
||||
myLocationProvider = new LocationProvider(this); //autostart with this (only) constructor
|
||||
}
|
||||
|
||||
@ -341,19 +406,22 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
boolean displayNotification = false;
|
||||
|
||||
String rule = "";
|
||||
|
||||
outerLoop:
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
{
|
||||
if(r.isRuleActive())
|
||||
{
|
||||
if(!r.haveEnoughPermissions())
|
||||
// for (String permission : ActivityPermissions.getPermissionsForRule(r))
|
||||
{
|
||||
// if (!ActivityPermissions.havePermission(permission, AutomationService.this))
|
||||
{
|
||||
// r.setRuleActive(false);
|
||||
// r.change(AutomationService.this);
|
||||
if(!displayNotification)
|
||||
{
|
||||
displayNotification = true;
|
||||
rule = r.getName();
|
||||
break outerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,18 +429,16 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
if(displayNotification)
|
||||
{
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Require more permissions.", Toast.LENGTH_LONG).show();
|
||||
// Update notification or show new one that notifiies of the lack or permissions.
|
||||
|
||||
Intent intent = new Intent(AutomationService.this, ActivityPermissions.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
|
||||
Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(1010, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
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);
|
||||
}
|
||||
// else
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Have all required permissions.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,14 +455,22 @@ public class AutomationService extends Service implements OnInitListener
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.settingsReferringToRestrictedFeatures), ActivityPermissions.notificationIdPermissions, pi);
|
||||
|
||||
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(3300, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
|
||||
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()
|
||||
{
|
||||
NotificationManagerCompat.from(AutomationService.this).cancelAll();
|
||||
}
|
||||
|
||||
protected void checkForMissingBackgroundLocationPermission()
|
||||
{
|
||||
if(Miscellaneous.googleToBlameForLocation(true))
|
||||
@ -404,29 +478,14 @@ public class AutomationService extends Service implements OnInitListener
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
}
|
||||
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
|
||||
|
||||
/*
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
|
||||
{
|
||||
if (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||
{
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||
{
|
||||
@ -445,7 +504,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
private void stopRoutine()
|
||||
{
|
||||
Log.i("STOP", "Stopping");
|
||||
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
|
||||
|
||||
// Clear variables for trigger/action with same name
|
||||
variableMap.clear();
|
||||
|
||||
try
|
||||
{
|
||||
myLocationProvider.stopLocationService();
|
||||
@ -460,6 +523,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
ttsEngine.shutdown();
|
||||
|
||||
PackageReplacedReceiver.setHasServiceBeenRunning(false, this);
|
||||
|
||||
centralInstance = null;
|
||||
Settings.serviceStartDone = false;
|
||||
}
|
||||
|
||||
protected static Builder createDefaultNotificationBuilderOld()
|
||||
@ -468,16 +534,20 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setContentTitle("Automation");
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setContentIntent(myPendingIntent);
|
||||
|
||||
// Notification defaultNotification = new Notification();
|
||||
Notification defaultNotification = builder.build();
|
||||
|
||||
defaultNotification.icon = R.drawable.ic_launcher;
|
||||
defaultNotification.icon = R.drawable.crane;
|
||||
defaultNotification.when = System.currentTimeMillis();
|
||||
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
@ -492,34 +562,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);
|
||||
|
||||
@ -527,14 +572,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());
|
||||
@ -549,7 +594,12 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
// builder.setContentText(textToDisplay);
|
||||
// builder.setSmallIcon(icon);
|
||||
@ -566,8 +616,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
if(instance != null)
|
||||
{
|
||||
// if(Settings.showIconWhenServiceIsRunning)
|
||||
// {
|
||||
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
|
||||
|
||||
String bodyText="";
|
||||
@ -581,11 +629,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
if(activePoi == null)
|
||||
{
|
||||
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
|
||||
bodyText = "Active POI: none" + "\n" + "Closest POI: " + closestPoi.getName() + lastRuleString;
|
||||
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 = "Active POI: " + activePoi.getName() + lastRuleString;
|
||||
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + " " + activePoi.getName() + lastRuleString;
|
||||
}
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
@ -593,9 +641,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
|
||||
)
|
||||
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
|
||||
else
|
||||
@ -613,18 +661,15 @@ public class AutomationService extends Service implements OnInitListener
|
||||
}
|
||||
|
||||
String textToDisplay = bodyText + " " + lastRuleString;
|
||||
// if(Build.VERSION.SDK_INT < 11)
|
||||
// {
|
||||
// myNotification.setLatestEventInfo(instance, "Automation", textToDisplay, myPendingIntent);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
|
||||
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
|
||||
@ -633,9 +678,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
// notificationManager.notify(notificationId, myNotification);
|
||||
|
||||
instance.startForeground(notificationId, myNotification);
|
||||
// }
|
||||
// else
|
||||
// instance.startForeground(notificationId, null); // do not show icon in task bar
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,8 +692,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
@Override
|
||||
public void onInit(int status)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -659,18 +699,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
|
||||
)
|
||||
{
|
||||
@ -683,66 +723,47 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < 5; i++)
|
||||
for(int i = 0; i < 60; i++)
|
||||
{
|
||||
if(ttsEngine != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
if(ttsEngine == null || ttsStatus != TextToSpeech.SUCCESS)
|
||||
{
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TTS", "Waiting for a moment to give the TTS service time to load...", 4);
|
||||
Thread.sleep(1000); // give the tts engine time to load
|
||||
Thread.sleep(500); // give the tts engine time to load
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking \"" + text + "\" in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
|
||||
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "TTS engine not available after waiting 30 seconds, yet. Aborting.", 3);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getVariableMap()
|
||||
{
|
||||
return variableMap;
|
||||
}
|
||||
|
||||
public static boolean isMainActivityRunning(Context context)
|
||||
{
|
||||
if(ActivityMainScreen.getActivityMainScreenInstance() == null)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
// boolean isActivityFound = false;
|
||||
// ActivityManager activityManager = (ActivityManager)context.getSystemService (Context.ACTIVITY_SERVICE);
|
||||
// List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
|
||||
// isActivityFound = false;
|
||||
// for (int i = 0; i < activitys.size(); i++)
|
||||
// {
|
||||
// if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.jens.automation/com.jens.automation.ActivityMainScreen}"))
|
||||
// {
|
||||
// isActivityFound = true;
|
||||
// }
|
||||
// }
|
||||
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity running status: " + String.valueOf(isActivityFound), 5);
|
||||
// return isActivityFound;
|
||||
|
||||
// ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
|
||||
//
|
||||
// for (RunningTaskInfo task : tasks)
|
||||
// {
|
||||
// if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
}
|
||||
|
||||
public static boolean isMyServiceRunning(Context context)
|
||||
@ -754,7 +775,6 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
if(AutomationService.class.getName().equals(service.service.getClassName()))
|
||||
{
|
||||
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -763,7 +783,6 @@ 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);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,51 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class MyAccessibilityService extends AccessibilityService
|
||||
{
|
||||
static MyAccessibilityService instance;
|
||||
|
||||
public static MyAccessibilityService getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
{
|
||||
instance = new MyAccessibilityService();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceConnected()
|
||||
{
|
||||
super.onServiceConnected();
|
||||
Miscellaneous.logEvent("i", "Accessibility service", "Service started.", 4);
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||
public class News
|
||||
{
|
||||
Calendar publishDate;
|
||||
String applicablePlattform;
|
||||
String applicablePlatform;
|
||||
Map<String,NewsTranslation> translations = new HashMap<>();
|
||||
|
||||
public static class NewsTranslation
|
||||
@ -76,10 +76,10 @@ public class News
|
||||
if(oldFilePath.exists())
|
||||
oldFilePath.delete();
|
||||
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == -1 || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
String newsUrl = "https://server47.de/automation/appNews.php";
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null, ActivityManageActionTriggerUrl.methodGet, null);
|
||||
|
||||
// Cache content to local storage
|
||||
if(Miscellaneous.writeStringToFile(filePath, newsContent))
|
||||
@ -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
|
||||
|
@ -64,7 +64,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
public void setName(String desiredName)
|
||||
{
|
||||
this.oldName = this.name;
|
||||
this.name = desiredName;
|
||||
this.name = desiredName.trim();
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
@ -253,7 +253,8 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
|
||||
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,7 +265,7 @@ 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);
|
||||
@ -272,10 +273,14 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
@ -286,7 +291,8 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
|
||||
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);
|
||||
@ -415,14 +421,18 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
public boolean create(Context context)
|
||||
{
|
||||
for(PointOfInterest poi : PointOfInterest.pointOfInterestCollection)
|
||||
{
|
||||
if (poi.getName().equals(this.getName()))
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.anotherPoiByThatName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Creating POI", this.toStringLong(), 3);
|
||||
|
||||
PointOfInterest.pointOfInterestCollection.add(this);
|
||||
PointOfInterest.writePoisToFile();
|
||||
|
||||
@ -486,15 +496,25 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Changing POI", "Old name: " + this.oldName + ", new data: " + this.toStringLong(), 3);
|
||||
|
||||
if(PointOfInterest.writePoisToFile())
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if (service != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
service.applySettingsAndRules();
|
||||
//Easiest way to check for changes in location, reset the last known location.
|
||||
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Just log the event. This should not cause an interruption in the program flow.
|
||||
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -530,14 +550,18 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
PointOfInterest.writePoisToFile();
|
||||
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if(service != null)
|
||||
|
||||
try
|
||||
{
|
||||
service.applySettingsAndRules();
|
||||
|
||||
//Easiest way to check for changes in location, reset the last known location.
|
||||
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
|
||||
}
|
||||
|
||||
catch(Exception e)
|
||||
{
|
||||
// Just log the event. This should not cause an interruption in the program flow.
|
||||
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -670,22 +694,16 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,6 +811,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
{
|
||||
String text = String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.overlapBetweenPois), otherPoi.getName(), String.valueOf(overlap));
|
||||
Miscellaneous.logEvent("w", "POI", text, 2);
|
||||
// Miscellaneous.messageBox("POI", text, Miscellaneous.getAnyContext()).show();
|
||||
Toast.makeText(Miscellaneous.getAnyContext(), text, Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
@ -13,10 +16,12 @@ import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Profile implements Comparable<Profile>
|
||||
{
|
||||
protected static ArrayList<Profile> profileCollection = new ArrayList<Profile>();
|
||||
protected static List<Profile> profileCollection = new ArrayList<Profile>();
|
||||
protected static List<Profile> profileActivationHistory = new ArrayList<>();
|
||||
|
||||
protected String name;
|
||||
protected String oldName;
|
||||
@ -24,6 +29,9 @@ public class Profile implements Comparable<Profile>
|
||||
protected boolean changeSoundMode;
|
||||
protected int soundMode;
|
||||
|
||||
protected boolean changeDndMode;
|
||||
protected int dndMode;
|
||||
|
||||
boolean changeVolumeMusicVideoGameMedia;
|
||||
protected int volumeMusic;
|
||||
|
||||
@ -34,13 +42,13 @@ public class Profile implements Comparable<Profile>
|
||||
protected int volumeAlarms;
|
||||
|
||||
protected boolean changeIncomingCallsRingtone;
|
||||
protected File incomingCallsRingtone;
|
||||
protected String incomingCallsRingtone;
|
||||
|
||||
protected boolean changeVibrateWhenRinging;
|
||||
protected boolean vibrateWhenRinging;
|
||||
|
||||
protected boolean changeNotificationRingtone;
|
||||
protected File notificationRingtone;
|
||||
protected String notificationRingtone;
|
||||
|
||||
protected boolean changeAudibleSelection;
|
||||
protected boolean audibleSelection;
|
||||
@ -55,7 +63,7 @@ public class Profile implements Comparable<Profile>
|
||||
public void setName(String name)
|
||||
{
|
||||
this.oldName = this.name;
|
||||
this.name = name;
|
||||
this.name = name.trim();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
@ -81,6 +89,26 @@ public class Profile implements Comparable<Profile>
|
||||
return soundMode;
|
||||
}
|
||||
|
||||
public boolean getChangeDndMode()
|
||||
{
|
||||
return changeDndMode;
|
||||
}
|
||||
|
||||
public void setChangeDndMode(boolean changeDndMode)
|
||||
{
|
||||
this.changeDndMode = changeDndMode;
|
||||
}
|
||||
|
||||
public int getDndMode()
|
||||
{
|
||||
return dndMode;
|
||||
}
|
||||
|
||||
public void setDndMode(int dndMode)
|
||||
{
|
||||
this.dndMode = dndMode;
|
||||
}
|
||||
|
||||
public void setChangeVolumeMusicVideoGameMedia(boolean changeVolumeMusicVideoGameMedia)
|
||||
{
|
||||
this.changeVolumeMusicVideoGameMedia = changeVolumeMusicVideoGameMedia;
|
||||
@ -144,11 +172,11 @@ public class Profile implements Comparable<Profile>
|
||||
return changeIncomingCallsRingtone;
|
||||
}
|
||||
|
||||
public void setIncomingCallsRingtone(File incomingCallsRingtone)
|
||||
public void setIncomingCallsRingtone(String incomingCallsRingtone)
|
||||
{
|
||||
this.incomingCallsRingtone = incomingCallsRingtone;
|
||||
}
|
||||
public File getIncomingCallsRingtone()
|
||||
public String getIncomingCallsRingtone()
|
||||
{
|
||||
return incomingCallsRingtone;
|
||||
}
|
||||
@ -180,11 +208,11 @@ public class Profile implements Comparable<Profile>
|
||||
return changeNotificationRingtone;
|
||||
}
|
||||
|
||||
public void setNotificationRingtone(File notificationsRingtone)
|
||||
public void setNotificationRingtone(String notificationsRingtone)
|
||||
{
|
||||
this.notificationRingtone = notificationsRingtone;
|
||||
}
|
||||
public File getNotificationRingtone()
|
||||
public String getNotificationRingtone()
|
||||
{
|
||||
return notificationRingtone;
|
||||
}
|
||||
@ -243,7 +271,7 @@ public class Profile implements Comparable<Profile>
|
||||
return hapticFeedback;
|
||||
}
|
||||
|
||||
public static ArrayList<Profile> getProfileCollection()
|
||||
public static List<Profile> getProfileCollection()
|
||||
{
|
||||
return profileCollection;
|
||||
}
|
||||
@ -265,49 +293,60 @@ public class Profile implements Comparable<Profile>
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean delete(AutomationService myAutomationService)
|
||||
private boolean applyRingTone(String ringtoneFile, int ringtoneType, Context context)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile, 3);
|
||||
|
||||
private boolean applyRingTone(File ringtoneFile, int ringtoneType, Context context)
|
||||
// if(!ringtoneFile.exists() || !ringtoneFile.canRead())
|
||||
// {
|
||||
// String message = "Ringtone file does not exist or cannot read it: " + ringtoneFile.getAbsolutePath();
|
||||
// Miscellaneous.logEvent("i", "Profile", message, 3);
|
||||
// Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Set by URI
|
||||
if(ringtoneFile.contains("//"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile.getAbsolutePath(), 3);
|
||||
|
||||
if(!ringtoneFile.exists() | !ringtoneFile.canRead())
|
||||
Uri target = Uri.parse(ringtoneFile);
|
||||
RingtoneManager.setActualDefaultRingtoneUri(context, ringtoneType, target);
|
||||
Miscellaneous.logEvent("i", "Profile", "Ringtone set to: " + ringtoneFile, 1);
|
||||
return true;
|
||||
} // Set by filepath
|
||||
else
|
||||
{
|
||||
String message = "Ringtone file does not exist or cannot read it: " + ringtoneFile.getAbsolutePath();
|
||||
Miscellaneous.logEvent("i", "Profile", message, 3);
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
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.DATA, ringtoneFile);
|
||||
values.put(MediaStore.MediaColumns.TITLE, ringtoneFile);
|
||||
//values.put(MediaStore.MediaColumns.TITLE, ringtoneFile.getName());
|
||||
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;
|
||||
|
||||
Uri existingRingTone = MediaStore.Audio.Media.getContentUriForPath(ringtoneFile);
|
||||
|
||||
try
|
||||
{
|
||||
if (existingRingTone != null)
|
||||
context.getContentResolver().delete(existingRingTone, MediaStore.MediaColumns.DATA + "=\"" + ringtoneFile + "\"", null);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w","Delete file from ringtones", "Deleting ringtone from library failed: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -315,6 +354,7 @@ public class Profile implements Comparable<Profile>
|
||||
String message = "Error setting ringtone: " + Log.getStackTraceString(t);
|
||||
Miscellaneous.logEvent("e", "Profile", message, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -366,11 +406,23 @@ public class Profile implements Comparable<Profile>
|
||||
}
|
||||
|
||||
// Check if rules reference this profile
|
||||
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByProfile(this);
|
||||
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByActionProfile(this);
|
||||
if(rulesThatReferenceMe.size() > 0)
|
||||
{
|
||||
for(Rule oneRule : rulesThatReferenceMe)
|
||||
{
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.profileActive)
|
||||
{
|
||||
String[] parts = oneTrigger.getTriggerParameter2().split(Trigger.triggerParameter2Split);
|
||||
parts[0] = this.name;
|
||||
|
||||
oneTrigger.setTriggerParameter2(Miscellaneous.explode(Trigger.triggerParameter2Split, parts));
|
||||
// We don't need to save the file. This will happen anyway in PointOfInterest.writePoisToFile() below.
|
||||
}
|
||||
}
|
||||
|
||||
for(Action oneAction : oneRule.getActionSet())
|
||||
{
|
||||
if(oneAction.getAction() == Action_Enum.changeSoundProfile)
|
||||
@ -399,22 +451,41 @@ public class Profile implements Comparable<Profile>
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean delete()
|
||||
public Rule isInUseByRules()
|
||||
{
|
||||
for(int i = 0; i< Profile.getProfileCollection().size(); i++)
|
||||
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);
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
|
||||
{
|
||||
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
|
||||
{
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
// write to file
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean plausibilityCheck()
|
||||
{
|
||||
if(this.getName().equals("null"))
|
||||
@ -439,6 +510,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)
|
||||
@ -450,6 +523,9 @@ public class Profile implements Comparable<Profile>
|
||||
if(changeSoundMode)
|
||||
Actions.setSound(context, soundMode);
|
||||
|
||||
if(changeDndMode)
|
||||
Actions.setDoNotDisturb(context, dndMode);
|
||||
|
||||
if(changeVolumeMusicVideoGameMedia)
|
||||
am.setStreamVolume(AudioManager.STREAM_MUSIC, volumeMusic, AudioManager.FLAG_PLAY_SOUND);
|
||||
|
||||
@ -464,10 +540,19 @@ public class Profile implements Comparable<Profile>
|
||||
applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
|
||||
|
||||
if(changeVibrateWhenRinging)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
{
|
||||
android.provider.Settings.System.putInt(context.getContentResolver(), "vibrate_when_ringing", vibrateWhenRinging?1:0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vibrateWhenRinging)
|
||||
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
|
||||
else
|
||||
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
if(changeNotificationRingtone)
|
||||
if(notificationRingtone != null)
|
||||
@ -498,6 +583,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", "Profile", "Checking for applicable rules 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", "Profile", "Rule " + ruleCandidates.get(i).getName() + " applies after " + this.getName() + " has been activated.", 2);
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
Miscellaneous.logEvent("i", "Profile", "Done checking for applicable rules after profile " + this.getName() + " has been activated.", 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -505,6 +604,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()
|
||||
{
|
||||
@ -540,4 +779,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,22 @@ 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.CalendarReceiver;
|
||||
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.SubSystemStateReceiver;
|
||||
import com.jens.automation2.receivers.TetheringReceiver;
|
||||
import com.jens.automation2.receivers.TimeZoneListener;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
@ -42,33 +49,40 @@ 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,
|
||||
TimeZoneListener.class
|
||||
MediaPlayerListener.class,
|
||||
ScreenStateReceiver.class,
|
||||
TimeZoneListener.class,
|
||||
TetheringReceiver.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,
|
||||
TimeZoneListener.class
|
||||
ScreenStateReceiver.class,
|
||||
TimeZoneListener.class,
|
||||
TetheringReceiver.class
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -131,63 +145,75 @@ 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
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
ConnectivityReceiver.startConnectivityReceiver(AutomationService.getInstance());
|
||||
|
||||
// startCellLocationChangedReceiver
|
||||
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.speed)))
|
||||
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.speed)))
|
||||
{
|
||||
if(!Miscellaneous.googleToBlameForLocation(true))
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
}
|
||||
|
||||
// startBatteryReceiver
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.charging) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.usb_host_connection) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.batteryLevel))
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.charging) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.usb_host_connection) || Rule.isAnyRuleUsing(Trigger.Trigger_Enum.batteryLevel))
|
||||
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
|
||||
|
||||
// startAlarmListener
|
||||
AlarmListener.startAlarmListener(AutomationService.getInstance());
|
||||
DateTimeListener.startAlarmListener(AutomationService.getInstance());
|
||||
TimeZoneListener.startTimeZoneListener(AutomationService.getInstance());
|
||||
|
||||
// startNoiseListener
|
||||
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());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.tethering))
|
||||
TetheringReceiver.getInstance().startListener(AutomationService.getInstance());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.subSystemState))
|
||||
SubSystemStateReceiver.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());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
CalendarReceiver.startCalendarReceiver(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
public static void stopAllReceivers()
|
||||
@ -199,23 +225,29 @@ 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());
|
||||
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
SubSystemStateReceiver.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());
|
||||
CalendarReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -239,7 +271,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 +291,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,9 +314,34 @@ 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(AutomationService.flavor_name_fdroid))
|
||||
{
|
||||
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
{
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);;
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
|
||||
|
||||
if (runResult instanceof Boolean)
|
||||
{
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
@ -309,6 +377,7 @@ public class ReceiverCoordinator
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.bluetoothConnection))
|
||||
{
|
||||
@ -332,7 +401,7 @@ public class ReceiverCoordinator
|
||||
{
|
||||
if(!HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
if(HeadphoneJackListener.getInstance().haveAllPermission())
|
||||
HeadphoneJackListener.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
@ -341,11 +410,78 @@ public class ReceiverCoordinator
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.tethering))
|
||||
{
|
||||
if(!TetheringReceiver.getInstance().isListenerRunning())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TetheringReceiver", "Starting TetheringReceiver because used in a new/changed rule.", 4);
|
||||
// if(DevicePositionListener.getInstance().haveAllPermission())
|
||||
TetheringReceiver.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(TetheringReceiver.getInstance().isListenerRunning())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TetheringReceiver", "Shutting down TetheringReceiver because not used in any rule.", 4);
|
||||
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.subSystemState))
|
||||
{
|
||||
if(!SubSystemStateReceiver.getInstance().isListenerRunning())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "SubSystemStateReceiver", "Starting SubSystemStateReceiver because used in a new/changed rule.", 4);
|
||||
// if(DevicePositionListener.getInstance().haveAllPermission())
|
||||
TetheringReceiver.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(SubSystemStateReceiver.getInstance().isListenerRunning())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "SubSystemStateReceiver", "Shutting down SubSystemStateReceiver because not used in any rule.", 4);
|
||||
SubSystemStateReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
if(!CalendarReceiver.getInstance().isListenerRunning())
|
||||
CalendarReceiver.getInstance().startListener(AutomationService.getInstance());
|
||||
else
|
||||
CalendarReceiver.armOrRearmTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CalendarReceiver.getInstance().isListenerRunning())
|
||||
CalendarReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
AutomationService.updateNotification();
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,15 @@ 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;
|
||||
public static final String folderName = "Automation";
|
||||
public static final String zipFileName = "automation.zip";
|
||||
|
||||
public static final String constNewsOptInDone ="newsOptInDone";
|
||||
public static final String constNotificationChannelCleanupApk118 ="notificationChannelCleanupApk118";
|
||||
|
||||
public static long minimumDistanceChangeForGpsUpdate;
|
||||
public static long minimumDistanceChangeForNetworkUpdate;
|
||||
@ -55,67 +57,89 @@ public class Settings implements SharedPreferences
|
||||
public static boolean rememberLastActivePoi;
|
||||
public static int locationRingBufferSize;
|
||||
public static long timeBetweenProcessMonitorings;
|
||||
public static long acceptDeviceOrientationSignalEveryX_MilliSeconds;
|
||||
public static int activityDetectionFrequency;
|
||||
public static int activityDetectionRequiredProbability;
|
||||
public static boolean privacyLocationing;
|
||||
public static int startScreen;
|
||||
public static int tabsPlacement;
|
||||
public static boolean executeRulesAndProfilesWithSingleClick;
|
||||
public static boolean displayNewsOnMainScreen;
|
||||
public static boolean showToasts;
|
||||
public static boolean automaticUpdateCheck;
|
||||
public static long musicCheckFrequency;
|
||||
public static String displayLanguage;
|
||||
|
||||
public static boolean lockSoundChanges;
|
||||
public static boolean noticeAndroid9MicrophoneShown;
|
||||
public static boolean noticeAndroid10WifiShown;
|
||||
public static long lastNewsPolltime;
|
||||
public static long lastUpdateCheck;
|
||||
|
||||
public static ArrayList<String> whatHasBeenDone;
|
||||
|
||||
/*
|
||||
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 boolean default_executeRulesAndProfilesWithSingleClick = false;
|
||||
protected static final boolean default_displayNewsOnMainScreen = false;
|
||||
protected static final boolean default_lockSoundChanges = false;
|
||||
protected static final long default_lastNewsPolltime = -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_showToasts = true;
|
||||
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;
|
||||
public static final String default_displayLanguage = "systemDefaultLanguage";
|
||||
|
||||
@Override
|
||||
public boolean contains(String arg0)
|
||||
@ -125,56 +149,45 @@ public class Settings implements SharedPreferences
|
||||
@Override
|
||||
public Editor edit()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Map<String, ?> getAll()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean getBoolean(String arg0, boolean arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public float getFloat(String arg0, float arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getInt(String arg0, int arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public long getLong(String arg0, long arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public String getString(String arg0, String arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public static void readFromPersistentStorage(Context context)
|
||||
@ -228,6 +241,7 @@ public class Settings implements SharedPreferences
|
||||
lengthOfNoiseLevelMeasurements = Long.parseLong(prefs.getString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements)));
|
||||
referenceValueForNoiseLevelMeasurements = Long.parseLong(prefs.getString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements)));
|
||||
timeBetweenProcessMonitorings = Long.parseLong(prefs.getString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings)));
|
||||
acceptDeviceOrientationSignalEveryX_MilliSeconds = Long.parseLong(prefs.getString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds)));
|
||||
|
||||
httpAcceptAllCertificates = prefs.getBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates);
|
||||
httpAttempts = Integer.parseInt(prefs.getString("httpAttempts", String.valueOf(default_httpAttempts)));
|
||||
@ -247,15 +261,25 @@ public class Settings implements SharedPreferences
|
||||
|
||||
privacyLocationing = prefs.getBoolean("privacyLocationing", default_privacyLocationing);
|
||||
startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
|
||||
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
|
||||
|
||||
musicCheckFrequency = Long.parseLong(prefs.getString("musicCheckFrequency", String.valueOf(default_musicCheckFrequency)));
|
||||
displayLanguage = prefs.getString("displayLanguage", default_displayLanguage);
|
||||
|
||||
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);
|
||||
showToasts = prefs.getBoolean("showToasts", default_showToasts);
|
||||
|
||||
lockSoundChanges = prefs.getBoolean("lockSoundChanges", default_lockSoundChanges);
|
||||
noticeAndroid9MicrophoneShown = prefs.getBoolean("noticeAndroid9MicrophoneShown", false);
|
||||
noticeAndroid10WifiShown = prefs.getBoolean("noticeAndroid10WifiShown", false);
|
||||
|
||||
lastNewsPolltime = prefs.getLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
lastUpdateCheck = prefs.getLong("lastUpdateCheck", default_lastUpdateCheck);
|
||||
|
||||
String whbdString = prefs.getString("whatHasBeenDone", "");
|
||||
if(whbdString != null && whbdString.length() > 0)
|
||||
@ -312,142 +336,160 @@ 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("executeRulesAndProfilesWithSingleClick") | force)
|
||||
if(!prefs.contains("tabsPlacement") || force)
|
||||
editor.putString("tabsPlacement", String.valueOf(default_tabsPlacement));
|
||||
|
||||
if(!prefs.contains("executeRulesAndProfilesWithSingleClick") || force)
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
|
||||
if(!prefs.contains("displayNewsOnMainScreen") | force)
|
||||
if(!prefs.contains("automaticUpdateCheck") || force)
|
||||
editor.putBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
|
||||
if(!prefs.contains("displayNewsOnMainScreen") || force)
|
||||
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
|
||||
if(!prefs.contains("lockSoundChanges") | force)
|
||||
if(!prefs.contains("showToasts") || force)
|
||||
editor.putBoolean("showToasts", default_showToasts);
|
||||
|
||||
if(!prefs.contains("musicCheckFrequency") || force)
|
||||
editor.putLong("musicCheckFrequency", default_musicCheckFrequency);
|
||||
|
||||
if(!prefs.contains("displayLanguage") || force)
|
||||
editor.putString("displayLanguage", default_displayLanguage);
|
||||
|
||||
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("whatHasBeenDone") | force)
|
||||
if(!prefs.contains("lastUpdateCheck") || force)
|
||||
editor.putLong("lastUpdateCheck", default_lastUpdateCheck);
|
||||
|
||||
if(!prefs.contains("whatHasBeenDone") || force)
|
||||
editor.putString("whatHasBeenDone", "");
|
||||
|
||||
editor.commit();
|
||||
@ -506,18 +548,29 @@ public class Settings implements SharedPreferences
|
||||
editor.putString("httpAttemptGap", String.valueOf(httpAttemptGap));
|
||||
editor.putString("locationRingBufferSize", String.valueOf(locationRingBufferSize));
|
||||
editor.putString("timeBetweenProcessMonitorings", String.valueOf(timeBetweenProcessMonitorings));
|
||||
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(acceptDeviceOrientationSignalEveryX_MilliSeconds));
|
||||
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
|
||||
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
|
||||
editor.putBoolean("privacyLocationing", privacyLocationing);
|
||||
editor.putString("startScreen", String.valueOf(startScreen));
|
||||
editor.putString("tabsPlacement", String.valueOf(tabsPlacement));
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
|
||||
editor.putBoolean("automaticUpdateCheck", automaticUpdateCheck);
|
||||
editor.putBoolean("displayNewsOnMainScreen", displayNewsOnMainScreen);
|
||||
editor.putBoolean("showToasts", showToasts);
|
||||
|
||||
if(Settings.musicCheckFrequency == 0)
|
||||
Settings.musicCheckFrequency = Settings.default_musicCheckFrequency;
|
||||
editor.putString("musicCheckFrequency", String.valueOf(musicCheckFrequency));
|
||||
|
||||
editor.putString("displayLanguage", displayLanguage);
|
||||
|
||||
editor.putBoolean("lockSoundChanges", lockSoundChanges);
|
||||
editor.putBoolean("noticeAndroid9MicrophoneShown", noticeAndroid9MicrophoneShown);
|
||||
editor.putBoolean("noticeAndroid10WifiShown", noticeAndroid10WifiShown);
|
||||
|
||||
editor.putLong("lastNewsPolltime", lastNewsPolltime);
|
||||
editor.putLong("lastUpdateCheck", lastUpdateCheck);
|
||||
|
||||
editor.putString("whatHasBeenDone", Miscellaneous.explode(";", whatHasBeenDone));
|
||||
|
||||
@ -555,8 +608,6 @@ public class Settings implements SharedPreferences
|
||||
@Override
|
||||
public Set<String> getStringSet(String arg0, Set<String> arg1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -2,12 +2,16 @@ package com.jens.automation2;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class TimeFrame
|
||||
{
|
||||
// Defines a timeframe
|
||||
private Time triggerTimeStart;
|
||||
private Time triggerTimeStop;
|
||||
protected TimeObject triggerTimeStart;
|
||||
protected TimeObject triggerTimeStop;
|
||||
protected long repetition;
|
||||
|
||||
protected final static String separator = "/";
|
||||
|
||||
private ArrayList<Integer> dayList = new ArrayList<Integer>();
|
||||
public ArrayList<Integer> getDayList()
|
||||
@ -17,59 +21,100 @@ public class TimeFrame
|
||||
public void setDayList(ArrayList<Integer> dayList)
|
||||
{
|
||||
this.dayList = dayList;
|
||||
Collections.sort(dayList);
|
||||
}
|
||||
public void setDayListFromString(String dayListString)
|
||||
{
|
||||
// Log.i("Parsing", "Full string: " + dayListString);
|
||||
char[] dayListCharArray = dayListString.toCharArray();
|
||||
|
||||
dayList = new ArrayList<Integer>();
|
||||
for(char item : dayListCharArray)
|
||||
{
|
||||
// Log.i("Parsing", String.valueOf(item));
|
||||
dayList.add(Integer.parseInt(String.valueOf(item)));
|
||||
}
|
||||
|
||||
Collections.sort(dayList);
|
||||
}
|
||||
|
||||
|
||||
public Time getTriggerTimeStart()
|
||||
public TimeObject getTriggerTimeStart()
|
||||
{
|
||||
return triggerTimeStart;
|
||||
}
|
||||
public void setTriggerTimeStart(Time triggerTimeStart)
|
||||
public void setTriggerTimeStart(TimeObject triggerTimeStart)
|
||||
{
|
||||
this.triggerTimeStart = triggerTimeStart;
|
||||
}
|
||||
public Time getTriggerTimeStop()
|
||||
|
||||
public TimeObject getTriggerTimeStop()
|
||||
{
|
||||
return triggerTimeStop;
|
||||
}
|
||||
public void setTriggerTimeStop(Time triggerTimeStop)
|
||||
public void setTriggerTimeStop(TimeObject triggerTimeStop)
|
||||
{
|
||||
this.triggerTimeStop = triggerTimeStop;
|
||||
}
|
||||
|
||||
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2)
|
||||
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);
|
||||
}
|
||||
TimeFrame (String fileContent)
|
||||
|
||||
public TimeFrame (String fileContent)
|
||||
{
|
||||
String[] dateArray = fileContent.split("/"); // example: timestart/timestop/days[int]
|
||||
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
|
||||
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
|
||||
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)
|
||||
{
|
||||
response.append(separator + this.getRepetition());
|
||||
}
|
||||
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String returnString = this.getTriggerTimeStart().toString() + "/" + this.getTriggerTimeStop().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;
|
||||
}
|
||||
}
|
78
app/src/main/java/com/jens/automation2/TimeObject.java
Normal file
78
app/src/main/java/com/jens/automation2/TimeObject.java
Normal file
@ -0,0 +1,78 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
Time time = Time.valueOf(this.getHours() + ":" + this.getMinutes() + ":" + this.getSeconds());
|
||||
return time.toString();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,8 @@ import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class XmlFileInterface
|
||||
{
|
||||
public static String settingsFileName = "Automation_settings.xml";
|
||||
@ -158,9 +160,9 @@ public class XmlFileInterface
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeIncomingCallsRingtone()));
|
||||
serializer.endTag(null, "changeIncomingCallsRingtone");//
|
||||
serializer.startTag(null, "incomingCallsRingtone");
|
||||
File incomingFile = Profile.getProfileCollection().get(i).getIncomingCallsRingtone();
|
||||
String incomingFile = Profile.getProfileCollection().get(i).getIncomingCallsRingtone();
|
||||
if(incomingFile != null)
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getIncomingCallsRingtone().getPath()));
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getIncomingCallsRingtone()));
|
||||
else
|
||||
serializer.text("null");
|
||||
serializer.endTag(null, "incomingCallsRingtone");
|
||||
@ -168,17 +170,17 @@ public class XmlFileInterface
|
||||
serializer.startTag(null, "changeVibrateWhenRinging");
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeVibrateWhenRinging()));
|
||||
serializer.endTag(null, "changeVibrateWhenRinging");//
|
||||
serializer.startTag(null, "changeVibrateWhenRinging");
|
||||
serializer.startTag(null, "vibrateWhenRinging");
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getVibrateWhenRinging()));
|
||||
serializer.endTag(null, "changeVibrateWhenRinging");
|
||||
serializer.endTag(null, "vibrateWhenRinging");
|
||||
|
||||
serializer.startTag(null, "changeNotificationRingtone");
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeNotificationRingtone()));
|
||||
serializer.endTag(null, "changeNotificationRingtone");//
|
||||
serializer.startTag(null, "notificationRingtone");
|
||||
File notificationFile = Profile.getProfileCollection().get(i).getNotificationRingtone();
|
||||
String notificationFile = Profile.getProfileCollection().get(i).getNotificationRingtone();
|
||||
if(notificationFile != null)
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getNotificationRingtone().getPath()));
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getNotificationRingtone()));
|
||||
else
|
||||
serializer.text("null");
|
||||
serializer.endTag(null, "notificationRingtone");
|
||||
@ -204,12 +206,18 @@ public class XmlFileInterface
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getHapticFeedback()));
|
||||
serializer.endTag(null, "hapticFeedback");
|
||||
|
||||
serializer.startTag(null, "changeDndMode");
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getChangeDndMode()));
|
||||
serializer.endTag(null, "changeDndMode");//
|
||||
serializer.startTag(null, "dndMode");
|
||||
serializer.text(String.valueOf(Profile.getProfileCollection().get(i).getDndMode()));
|
||||
serializer.endTag(null, "dndMode");
|
||||
|
||||
serializer.endTag(null, "Profile");
|
||||
}
|
||||
serializer.endTag(null, "ProfileCollection");
|
||||
|
||||
|
||||
|
||||
serializer.startTag(null, "RuleCollection");
|
||||
for(int i=0; i<Rule.getRuleCollection().size(); i++)
|
||||
{
|
||||
@ -246,20 +254,16 @@ 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)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getNoiseLevelDb()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getWifiName());
|
||||
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)
|
||||
@ -273,6 +277,8 @@ public class XmlFileInterface
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getHeadphoneType()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.notification)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2()));
|
||||
else
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2()));
|
||||
serializer.endTag(null, "TriggerParameter2");
|
||||
serializer.endTag(null, "Trigger");
|
||||
}
|
||||
@ -603,6 +609,10 @@ public class XmlFileInterface
|
||||
newProfile.setChangeSoundMode(Boolean.parseBoolean(readTag(parser, "changeSoundMode")));
|
||||
else if (name.equals("soundMode"))
|
||||
newProfile.setSoundMode(Integer.parseInt(readTag(parser, "soundMode")));
|
||||
else if (name.equals("changeDndMode"))
|
||||
newProfile.setChangeDndMode(Boolean.parseBoolean(readTag(parser, "changeDndMode")));
|
||||
else if (name.equals("dndMode"))
|
||||
newProfile.setDndMode(Integer.parseInt(readTag(parser, "dndMode")));
|
||||
else if (name.equals("changeVolumeMusicVideoGameMedia"))
|
||||
newProfile.setChangeVolumeMusicVideoGameMedia(Boolean.parseBoolean(readTag(parser, "changeVolumeMusicVideoGameMedia")));
|
||||
else if (name.equals("volumeMusic"))
|
||||
@ -621,7 +631,7 @@ public class XmlFileInterface
|
||||
{
|
||||
String path = readTag(parser, "incomingCallsRingtone");
|
||||
if(!path.equals("null"))
|
||||
newProfile.setIncomingCallsRingtone(new File(path));
|
||||
newProfile.setIncomingCallsRingtone(path);
|
||||
else
|
||||
newProfile.setIncomingCallsRingtone(null);
|
||||
}
|
||||
@ -633,10 +643,12 @@ public class XmlFileInterface
|
||||
{
|
||||
String path = readTag(parser, "notificationRingtone");
|
||||
if(!path.equals("null"))
|
||||
newProfile.setNotificationRingtone(new File(path));
|
||||
newProfile.setNotificationRingtone(path);
|
||||
else
|
||||
newProfile.setNotificationRingtone(null);
|
||||
}
|
||||
else if (name.equals("vibrateWhenRinging"))
|
||||
newProfile.setVibrateWhenRinging(Boolean.parseBoolean(readTag(parser, "vibrateWhenRinging")));
|
||||
else if (name.equals("changeAudibleSelection"))
|
||||
newProfile.setChangeAudibleSelection(Boolean.parseBoolean(readTag(parser, "changeAudibleSelection")));
|
||||
else if (name.equals("audibleSelection"))
|
||||
@ -748,6 +760,8 @@ public class XmlFileInterface
|
||||
try
|
||||
{
|
||||
newRule.setTriggerSet(readTriggerCollection(parser));
|
||||
for(Trigger t : newRule.getTriggerSet())
|
||||
t.setParentRule(newRule);
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
@ -763,6 +777,8 @@ public class XmlFileInterface
|
||||
try
|
||||
{
|
||||
newRule.setActionSet(readActionCollection(parser));
|
||||
for(Action a : newRule.getActionSet())
|
||||
a.setParentRule(newRule);
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
@ -798,9 +814,17 @@ public class XmlFileInterface
|
||||
String name = parser.getName();
|
||||
// Starts by looking for the entry tag
|
||||
if (name.equals("Trigger"))
|
||||
{
|
||||
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
|
||||
{
|
||||
skip(parser);
|
||||
@ -810,10 +834,8 @@ public class XmlFileInterface
|
||||
return (triggerCollection);
|
||||
}
|
||||
|
||||
|
||||
private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException
|
||||
{
|
||||
|
||||
/* FILE EXAMPE:
|
||||
* *****************
|
||||
* <Automation>
|
||||
@ -861,43 +883,9 @@ public class XmlFileInterface
|
||||
if (name.equals("TriggerEvent"))
|
||||
{
|
||||
String triggerEventString = readTag(parser, "TriggerEvent");
|
||||
// if(triggerEventString.equals("pointOfInterest"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.pointOfInterest);
|
||||
// else if(triggerEventString.equals("timeFrame"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.timeFrame);
|
||||
// else if(triggerEventString.equals("charging"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.charging);
|
||||
// else if(triggerEventString.equals("usb_host_connection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.usb_host_connection);
|
||||
// else if(triggerEventString.equals("batteryLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
|
||||
// else if(triggerEventString.equals("speed"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.speed);
|
||||
// else if(triggerEventString.equals("noiseLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.noiseLevel);
|
||||
// else if(triggerEventString.equals("wifiConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
// else
|
||||
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 if(triggerEventString.equals("airplaneMode"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.airplaneMode);
|
||||
// else if(triggerEventString.equals("roaming"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.roaming);
|
||||
// else if(triggerEventString.equals("phoneCall"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.phoneCall);
|
||||
// else if(triggerEventString.equals("nfcTag"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.nfcTag);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
// else if(triggerEventString.equals("activityDetection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||
// else if(triggerEventString.equals("bluetoothConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
|
||||
// else if(triggerEventString.equals("headsetPlugged"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.headsetPlugged);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
else
|
||||
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
|
||||
}
|
||||
@ -922,42 +910,98 @@ public class XmlFileInterface
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 2);
|
||||
Toast.makeText(context, "Error while writing file: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.timeFrame)
|
||||
{
|
||||
newTrigger.setTimeFrame(new TimeFrame(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.batteryLevel)
|
||||
{
|
||||
newTrigger.setBatteryLevel(Integer.parseInt(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.speed)
|
||||
{
|
||||
newTrigger.setSpeed(Double.parseDouble(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.noiseLevel)
|
||||
{
|
||||
newTrigger.setNoiseLevelDb(Long.parseLong(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
{
|
||||
newTrigger.setWifiName(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped)
|
||||
{
|
||||
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)
|
||||
{
|
||||
String[] elements = triggerParameter2.split(",");
|
||||
if(elements.length == 2) //old format
|
||||
{
|
||||
// 0/1/2,number
|
||||
int direction = Integer.parseInt(triggerParameter2.substring(0, 1));
|
||||
String number = triggerParameter2.substring(2);
|
||||
int direction = Integer.parseInt(elements[0]);
|
||||
|
||||
String number = elements[1];
|
||||
newTrigger.setPhoneDirection(direction);
|
||||
newTrigger.setPhoneNumber(number);
|
||||
|
||||
String tp2String = "";
|
||||
|
||||
if(newTrigger.getTriggerParameter())
|
||||
tp2String+= Trigger.triggerPhoneCallStateStarted;
|
||||
else
|
||||
tp2String+= Trigger.triggerPhoneCallStateStopped;
|
||||
|
||||
tp2String += triggerParameter2Split;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
case 0:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionAny;
|
||||
break;
|
||||
case 1:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionIncoming;
|
||||
break;
|
||||
case 2:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionOutgoing;
|
||||
break;
|
||||
}
|
||||
|
||||
tp2String += triggerParameter2Split;
|
||||
|
||||
tp2String += number;
|
||||
|
||||
newTrigger.setTriggerParameter2(tp2String);
|
||||
}
|
||||
/*else // new format
|
||||
{
|
||||
//tp1 is now irrelevant
|
||||
elements = triggerParameter2.split(Trigger.triggerParameter2Split);
|
||||
// state/direction/number
|
||||
}*/
|
||||
else
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.nfcTag)
|
||||
{
|
||||
newTrigger.setNfcTagId(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.activityDetection)
|
||||
{
|
||||
@ -969,6 +1013,7 @@ public class XmlFileInterface
|
||||
{
|
||||
newTrigger.setActivityDetectionType(0);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.bluetoothConnection)
|
||||
{
|
||||
@ -978,6 +1023,7 @@ public class XmlFileInterface
|
||||
newTrigger.setBluetoothEvent(substrings[0]);
|
||||
newTrigger.setBluetoothDeviceAddress(substrings[1]);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.headsetPlugged)
|
||||
{
|
||||
@ -989,8 +1035,9 @@ public class XmlFileInterface
|
||||
{
|
||||
newTrigger.setHeadphoneType(-1);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
|
||||
else
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else
|
||||
@ -1016,9 +1063,17 @@ public class XmlFileInterface
|
||||
String name = parser.getName();
|
||||
// Starts by looking for the entry tag
|
||||
if (name.equals("Action"))
|
||||
{
|
||||
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
|
||||
{
|
||||
skip(parser);
|
||||
@ -1027,7 +1082,6 @@ public class XmlFileInterface
|
||||
return (actionCollection);
|
||||
}
|
||||
|
||||
|
||||
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
|
||||
{
|
||||
/* FILE EXAMPE:
|
||||
@ -1079,17 +1133,6 @@ public class XmlFileInterface
|
||||
{
|
||||
String actionNameString = readTag(parser, "ActionName");
|
||||
|
||||
// if(actionNameString.equals("setWifi"))
|
||||
// newAction.setAction(Action_Enum.setWifi);
|
||||
// else if(actionNameString.equals("setBluetooth"))
|
||||
// newAction.setAction(Action_Enum.setBluetooth);
|
||||
// else if(actionNameString.equals("setUsbTethering"))
|
||||
// newAction.setAction(Action_Enum.setUsbTethering);
|
||||
// else if(actionNameString.equals("setWifiTethering"))
|
||||
// newAction.setAction(Action_Enum.setWifiTethering);
|
||||
// else if(actionNameString.equals("setDisplayRotation"))
|
||||
// newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
|
||||
// *** deprecated
|
||||
//else
|
||||
if(actionNameString.equals("turnWifiOn"))
|
||||
@ -1112,30 +1155,20 @@ 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 if(actionNameString.equals("triggerUrl"))
|
||||
// newAction.setAction(Action_Enum.triggerUrl);
|
||||
// else if(actionNameString.equals("changeSoundProfile"))
|
||||
// newAction.setAction(Action_Enum.changeSoundProfile);
|
||||
// else if(actionNameString.equals("startOtherActivity"))
|
||||
// newAction.setAction(Action_Enum.startOtherActivity);
|
||||
// else if(actionNameString.equals("waitBeforeNextAction"))
|
||||
// newAction.setAction(Action_Enum.waitBeforeNextAction);
|
||||
// else if(actionNameString.equals("wakeupDevice"))
|
||||
// newAction.setAction(Action_Enum.wakeupDevice);
|
||||
// else if(actionNameString.equals("setAirplaneMode"))
|
||||
// newAction.setAction(Action_Enum.setAirplaneMode);
|
||||
// else if(actionNameString.equals("setDataConnection"))
|
||||
// newAction.setAction(Action_Enum.setDataConnection);
|
||||
// else if(actionNameString.equals("speakText"))
|
||||
// newAction.setAction(Action_Enum.speakText);
|
||||
// else if(actionNameString.equals("sendTextMessage"))
|
||||
// newAction.setAction(Action_Enum.sendTextMessage);
|
||||
// else if(actionNameString.equals("playMusic"))
|
||||
// newAction.setAction(Action_Enum.playMusic);
|
||||
// else if(actionNameString.equals("setScreenBrightness"))
|
||||
// newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
else
|
||||
newAction.setAction(Action_Enum.valueOf(actionNameString));
|
||||
}
|
||||
@ -1201,6 +1234,18 @@ public class XmlFileInterface
|
||||
newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
newAction.setParameter1(false);
|
||||
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
newAction.setParameter1(false);
|
||||
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.turnScreenOnOrOff) && newAction.getParameter1())
|
||||
{
|
||||
/*
|
||||
If param1 == true we will keep it because this action used to be of type wakeUpDevice.
|
||||
*/
|
||||
}
|
||||
else
|
||||
// exclusion for deprecated types
|
||||
@ -1223,8 +1268,46 @@ public class XmlFileInterface
|
||||
{
|
||||
newAction.setParameter2(tag);
|
||||
}
|
||||
/*
|
||||
androidx.security.crypto.MasterKey.Builder
|
||||
|
||||
MasterKey mainKey = new MasterKey.Builder(context)
|
||||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
||||
.build();
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.startOtherActivity)) // separator has been changed, convert in old files
|
||||
{
|
||||
String newTag;
|
||||
|
||||
if(tag.contains(Action.intentPairSeparator)) // already has new format
|
||||
newTag = tag;
|
||||
else
|
||||
newTag = tag.replace("/", Action.intentPairSeparator);
|
||||
|
||||
String[] newTagPieces = new String[0];
|
||||
if(newTag.contains(Action.actionParameter2Split))
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
else
|
||||
newTag.split(";");
|
||||
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeparator)))
|
||||
{
|
||||
newTag = Actions.dummyPackageString + Action.actionParameter2Split + newTag;
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
}
|
||||
|
||||
if(newTagPieces.length < 3)
|
||||
newTag += Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString;
|
||||
else if(newTagPieces.length >= 3)
|
||||
{
|
||||
if(newTagPieces[2].contains(Action.intentPairSeparator))
|
||||
newTag = newTagPieces[0] + Action.actionParameter2Split + newTagPieces[1] + Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString + Action.actionParameter2Split + newTagPieces[2];
|
||||
}
|
||||
|
||||
newAction.setParameter2(newTag);
|
||||
}
|
||||
else
|
||||
newAction.setParameter2(tag);
|
||||
}
|
||||
@ -1247,9 +1330,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;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.jens.automation2.actions.wifi_router;
|
||||
|
||||
/*
|
||||
Class taken from here:
|
||||
https://github.com/aegis1980/WifiHotSpot
|
||||
*/
|
||||
|
||||
public abstract class MyOnStartTetheringCallback
|
||||
{
|
||||
/**
|
||||
* Called when tethering has been successfully started.
|
||||
*/
|
||||
public abstract void onTetheringStarted();
|
||||
|
||||
/**
|
||||
* Called when starting tethering failed.
|
||||
*/
|
||||
public abstract void onTetheringFailed();
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
package com.jens.automation2.actions.wifi_router;
|
||||
|
||||
/*
|
||||
Class taken from here:
|
||||
https://github.com/aegis1980/WifiHotSpot
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.android.dx.stock.ProxyBuilder;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by jonro on 19/03/2018.
|
||||
*/
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public class MyOreoWifiManager
|
||||
{
|
||||
private static final String TAG = MyOreoWifiManager.class.getSimpleName();
|
||||
|
||||
private Context mContext;
|
||||
private WifiManager mWifiManager;
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
|
||||
public MyOreoWifiManager(Context c)
|
||||
{
|
||||
mContext = c;
|
||||
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
|
||||
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the Wifi SSID and password
|
||||
* Call this before {@code startTethering} if app is a system/privileged app
|
||||
* Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
|
||||
*/
|
||||
public void configureHotspot(String name, String password)
|
||||
{
|
||||
WifiConfiguration apConfig = new WifiConfiguration();
|
||||
apConfig.SSID = name;
|
||||
apConfig.preSharedKey = password;
|
||||
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
|
||||
try
|
||||
{
|
||||
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
|
||||
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
|
||||
Miscellaneous.logEvent("i", "configureHotspot()", "setWifiApConfiguration - success? " + status, 2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "configureHotspot()", "Error in configureHotspot: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks where tethering is on.
|
||||
* This is determined by the getTetheredIfaces() method,
|
||||
* that will return an empty array if not devices are tethered
|
||||
*
|
||||
* @return true if a tethered device is found, false if not found
|
||||
*/
|
||||
public boolean isTetherActive()
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "getTetheredIfaces()", "getTetheredIfaces is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
String res[] = (String []) method.invoke(mConnectivityManager, null);
|
||||
Miscellaneous.logEvent("i", "isTetherActive()", "getTetheredIfaces invoked", 5);
|
||||
Miscellaneous.logEvent("i", "isTetherActive()", Arrays.toString(res), 4);
|
||||
|
||||
if (res.length > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "isTetherActive()", "Error in getTetheredIfaces: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
|
||||
* Does not require app to have system/privileged access
|
||||
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
|
||||
*/
|
||||
public boolean startTethering(final MyOnStartTetheringCallback callback)
|
||||
{
|
||||
// On Pie if we try to start tethering while it is already on, it will
|
||||
// be disabled. This is needed when startTethering() is called programmatically.
|
||||
if (isTetherActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "startTethering()", "Tether already active, returning", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
File outputDir = mContext.getCodeCacheDir();
|
||||
Object proxy;
|
||||
try
|
||||
{
|
||||
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
|
||||
.dexCache(outputDir).handler(new InvocationHandler()
|
||||
{
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
switch (method.getName())
|
||||
{
|
||||
case "onTetheringStarted":
|
||||
callback.onTetheringStarted();
|
||||
break;
|
||||
case "onTetheringFailed":
|
||||
callback.onTetheringFailed();
|
||||
break;
|
||||
default:
|
||||
ProxyBuilder.callSuper(proxy, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}).build();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "startTethering()", "Error in enableTethering ProxyBuilder", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
Method method = null;
|
||||
try
|
||||
{
|
||||
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "startTethering()", "startTetheringMethod is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
|
||||
Miscellaneous.logEvent("i", "startTethering()", "startTethering invoked", 5);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "startTethering()", "Error in enableTethering: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void stopTethering()
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "stopTethering", "stopTetheringMethod is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
|
||||
Miscellaneous.logEvent("i", "stopTethering", "stopTethering invoked", 5);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "stopTethering", "stopTethering error: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
private Class OnStartTetheringCallbackClass()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "OnStartTetheringCallbackClass()", "OnStartTetheringCallbackClass error: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -130,6 +130,21 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCellLocationChangedReceiverPossible()
|
||||
{
|
||||
if(telephonyManager == null)
|
||||
telephonyManager = (TelephonyManager) AutomationService.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
||||
if(
|
||||
ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance())
|
||||
||
|
||||
telephonyManager.getSimState() != TelephonyManager.SIM_STATE_READY
|
||||
)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public Location getLocation(String accuracy)
|
||||
{
|
||||
Criteria crit = new Criteria();
|
||||
@ -137,7 +152,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
String myProviderName;
|
||||
|
||||
// If privacy mode or no data connection available
|
||||
if(Settings.privacyLocationing | !ConnectivityReceiver.isDataConnectionAvailable(AutomationService.getInstance()))
|
||||
if(Settings.privacyLocationing || !ConnectivityReceiver.isDataConnectionAvailable(AutomationService.getInstance()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CellLocation", Miscellaneous.getAnyContext().getResources().getString(R.string.enforcingGps), 4);
|
||||
myProviderName = LocationManager.GPS_PROVIDER;
|
||||
@ -175,6 +190,9 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
}
|
||||
else
|
||||
{
|
||||
if(myLocationManager == null)
|
||||
myLocationManager = (LocationManager) AutomationService.getInstance().getSystemService(Context.LOCATION_SERVICE);
|
||||
|
||||
if(!myLocationManager.isProviderEnabled(myProviderName))
|
||||
{
|
||||
if(myProviderName.equals(LocationManager.NETWORK_PROVIDER))
|
||||
@ -226,13 +244,11 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
|
||||
public void setCurrentLocation(Location currentLocation)
|
||||
{
|
||||
this.currentLocation = currentLocation;
|
||||
}
|
||||
|
||||
|
||||
public class MyLocationListener implements LocationListener
|
||||
{
|
||||
@Override
|
||||
@ -256,29 +272,23 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
locationListenerArmed = false;
|
||||
Miscellaneous.logEvent("i", "LocationListener", "Disarmed location listener, accuracy reached", 4);
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "LocationListener", "Giving update to POI class");
|
||||
// PointOfInterest.positionUpdate(up2DateLocation, parentLocationProvider.parentService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@ -327,7 +337,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
{
|
||||
if(!cellLocationListenerActive)
|
||||
{
|
||||
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()))
|
||||
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && telephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY)
|
||||
{
|
||||
if(WifiBroadcastReceiver.mayCellLocationReceiverBeActivated())
|
||||
{
|
||||
@ -356,7 +366,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
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.", 4);
|
||||
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
@ -410,4 +420,3 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
ActivityPermissions.havePermission("android.permission.ACCESS_WIFI_STATE", Miscellaneous.getAnyContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
|
||||
import com.jens.automation2.ActivityMainScreen;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.BuildConfig;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.PointOfInterest;
|
||||
import com.jens.automation2.R;
|
||||
@ -26,13 +27,9 @@ import java.util.Calendar;
|
||||
|
||||
public class LocationProvider
|
||||
{
|
||||
|
||||
protected static boolean passiveLocationListenerActive = false;
|
||||
|
||||
protected static LocationListener passiveLocationListener;
|
||||
|
||||
protected static LocationProvider locationProviderInstance = null;
|
||||
|
||||
protected AutomationService parentService;
|
||||
public AutomationService getParentService()
|
||||
{
|
||||
@ -108,6 +105,8 @@ public class LocationProvider
|
||||
}
|
||||
|
||||
public void setCurrentLocation(Location newLocation, boolean skipVerification)
|
||||
{
|
||||
if(newLocation != null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Location", "Setting location.", 4);
|
||||
|
||||
@ -144,8 +143,33 @@ public class LocationProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
speedCalculation:
|
||||
if (locationList.size() >= 2)
|
||||
{
|
||||
while (locationList.size() > 2)
|
||||
{
|
||||
// Remove all entries except for the last 2
|
||||
Miscellaneous.logEvent("i", "Speed", "About to delete oldest position record until only 2 left. Currently have " + String.valueOf(locationList.size()) + " records.", 4);
|
||||
locationList.remove(0);
|
||||
}
|
||||
|
||||
/*
|
||||
The two most recent locations in the list must have a usable accuracy.
|
||||
*/
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if
|
||||
(
|
||||
(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)
|
||||
)
|
||||
{
|
||||
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);
|
||||
break speedCalculation;
|
||||
}
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "Speed", "Trying to calculate speed based on the last locations.", 4);
|
||||
|
||||
double currentSpeed;
|
||||
@ -165,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
|
||||
{
|
||||
@ -174,24 +198,16 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Speed", "Last two locations are too far apart in terms of time. Cannot use them for speed calculation.", 4);
|
||||
|
||||
|
||||
while (locationList.size() > 2)
|
||||
{
|
||||
// Remove all entries except for the last 2
|
||||
Miscellaneous.logEvent("i", "Speed", "About to delete oldest position record until only 2 left. Currently have " + String.valueOf(locationList.size()) + " records.", 4);
|
||||
locationList.remove(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -210,31 +226,51 @@ public class LocationProvider
|
||||
if (AutomationService.isMainActivityRunning(parentService))
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Location", "New location given is null. Ignoring.", 5);
|
||||
}
|
||||
|
||||
public void startLocationService()
|
||||
{
|
||||
// if(Settings.useAccelerometerForPositioning && !Miscellaneous.isAndroidEmulator())
|
||||
// {
|
||||
// accelerometerHandler = new AccelerometerHandler();
|
||||
// mySensorActivity = new SensorActivity(this);
|
||||
// }
|
||||
|
||||
// startPhoneStateListener
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(parentService); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
ConnectivityReceiver.startConnectivityReceiver(parentService);
|
||||
|
||||
if(Settings.positioningEngine == 0)
|
||||
{
|
||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) || Rule.isAnyRuleUsing(Trigger_Enum.speed))
|
||||
{
|
||||
// startCellLocationChangedReceiver
|
||||
if (!ConnectivityReceiver.isAirplaneMode(this.parentService) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger_Enum.speed)))
|
||||
if (CellLocationChangedReceiver.isCellLocationChangedReceiverPossible())
|
||||
{
|
||||
if (WifiBroadcastReceiver.mayCellLocationReceiverBeActivated())
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Reasons why we may end up here:
|
||||
- Airplane mode is active
|
||||
- No phone module present (pure wifi device)
|
||||
- No SIM card is inserted or it's not unlocked
|
||||
|
||||
We'd have to try GPS now to get an initial position.
|
||||
For permanent use there is no way we could know when it
|
||||
would make sense to check the position again.
|
||||
*/
|
||||
|
||||
// Trigger a one-time-position-search
|
||||
Location loc = CellLocationChangedReceiver.getInstance().getLocation("fine");
|
||||
LocationProvider.getInstance().setCurrentLocation(loc, true);
|
||||
}
|
||||
|
||||
// startPassiveLocationListener
|
||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger_Enum.speed))
|
||||
startPassiveLocationListener();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||
@ -366,12 +402,12 @@ public class LocationProvider
|
||||
Miscellaneous.logEvent("i", "LocationProvider", this.getParentService().getResources().getString(R.string.applyingSettingsAndRules), 3);
|
||||
|
||||
// *********** SETTING CHANGES ***********
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive())
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive() || Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting WifiReceiver because settings now allow to.", 4);
|
||||
WifiBroadcastReceiver.startWifiReceiver(this);
|
||||
}
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive())
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive() && !Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down WifiReceiver because settings forbid to.", 4);
|
||||
WifiBroadcastReceiver.stopWifiReceiver();
|
||||
@ -389,7 +425,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())
|
||||
@ -450,7 +486,6 @@ public class LocationProvider
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void resetSpeedTimer(Calendar timeOfForcedLocationCheck)
|
||||
{
|
||||
if(speedTimerActive)
|
||||
@ -471,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
|
||||
@ -488,19 +522,11 @@ 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", "AccelerometerHandler", text, 5);
|
||||
// CellLocationChangedReceiver.stopCellLocationChangedReceiver();
|
||||
// startAccelerometerReceiver();
|
||||
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);
|
||||
}
|
||||
/*else if(msg.what == 0)
|
||||
{
|
||||
String text = "Abort command received, deactivating SpeedReceiver";
|
||||
Miscellaneous.logEvent("i", "SpeedHandler", text, 4);
|
||||
stopAccelerometerReceiver();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package com.jens.automation2.location;
|
||||
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -10,11 +9,15 @@ import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
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 org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -23,13 +26,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
public static LocationProvider parentLocationProvider;
|
||||
public static Boolean wasConnected = false;
|
||||
protected static String lastWifiSsid = "";
|
||||
protected static String lastWifiSsidReal = "";
|
||||
public static boolean lastConnectedState = false;
|
||||
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
|
||||
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
|
||||
protected static WifiBroadcastReceiver wifiBrInstance;
|
||||
protected static IntentFilter wifiListenerIntentFilter;
|
||||
protected static boolean wifiListenerActive = false;
|
||||
|
||||
final static String unknownSsidName = "<unknown ssid>";
|
||||
|
||||
public static String getLastWifiSsidReal()
|
||||
{
|
||||
return lastWifiSsidReal;
|
||||
}
|
||||
|
||||
public static String getLastWifiSsid()
|
||||
{
|
||||
@ -38,11 +47,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
|
||||
public static void setLastWifiSsid(String newWifiSsid)
|
||||
{
|
||||
// Remove double quotes that sometimes come
|
||||
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
|
||||
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
|
||||
|
||||
// If it's a real name, not an empty string, it's stored as the last ssid
|
||||
if(newWifiSsid.length() > 0)
|
||||
{
|
||||
if(!newWifiSsid.equals(unknownSsidName))
|
||||
WifiBroadcastReceiver.lastWifiSsidReal = lastWifiSsid;
|
||||
|
||||
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWifiListenerActive()
|
||||
{
|
||||
@ -51,7 +68,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
|
||||
public static boolean mayCellLocationReceiverBeActivated()
|
||||
{
|
||||
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi;
|
||||
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -59,29 +76,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
// int state = -1;
|
||||
if(!StringUtils.isEmpty(intent.getAction()))
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Received signal with action \""+ intent.getAction() + "\".", 4);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Received signal with empty action.", 4);
|
||||
|
||||
NetworkInfo myWifi = null;
|
||||
|
||||
// if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) //gefeuert bei Verbindung
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "WifiReceiver", "RSSI_CHANGED_ACTION: " + String.valueOf(intent.getIntExtra(WifiManager.RSSI_CHANGED_ACTION, -1)));
|
||||
// }
|
||||
// else
|
||||
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) //gefeuert bei Trennung
|
||||
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) // fired upon disconnection
|
||||
{
|
||||
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
|
||||
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));
|
||||
myWifi = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
|
||||
}
|
||||
|
||||
|
||||
WifiManager myWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
|
||||
// ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
|
||||
// myWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
// myWifi = state
|
||||
// WifiInfo wifiInfo = myWifiManager.getConnectionInfo();
|
||||
|
||||
// SupplicantState supState = wifiInfo.getSupplicantState();
|
||||
|
||||
if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) // fired upon connection
|
||||
{
|
||||
@ -94,8 +101,14 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
if(Settings.useWifiForPositioning && PointOfInterest.reachedPoiWithActivateWifiRule()) // Poi has wifi
|
||||
{
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", context.getResources().getString(R.string.poiHasWifiStoppingCellLocationListener), 2);
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = false;
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = false;
|
||||
CellLocationChangedReceiver.stopCellLocationChangedReceiver();
|
||||
|
||||
/*
|
||||
TODO: Every time the screen is turned on, we receive a "wifi has been connected"-event.
|
||||
This is technically wrong and not really any change to when the screen was off. It has
|
||||
to be filtered.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -103,32 +116,32 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", context.getResources().getString(R.string.poiHasNoWifiNotStoppingCellLocationListener), 2);
|
||||
}
|
||||
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
else if(myWifi.isConnectedOrConnecting()) // first time connect from wifi-listener-perspective
|
||||
{
|
||||
wasConnected = true;
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "WifiReceiver just activated. Wifi already connected. Stopping CellLocationReceiver", 3);
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = false;
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = false;
|
||||
CellLocationChangedReceiver.stopCellLocationChangedReceiver();
|
||||
SensorActivity.stopAccelerometerTimer();
|
||||
String ssid = myWifiManager.getConnectionInfo().getSSID();
|
||||
setLastWifiSsid(ssid);
|
||||
lastConnectedState = true;
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
else if(!myWifi.isConnectedOrConnecting()) // really disconnected? because sometimes also fires on connect
|
||||
{
|
||||
if(wasConnected) // wir könnten einfach noch nicht daheim sein
|
||||
if(wasConnected) // we could simply not be home yet
|
||||
{
|
||||
try
|
||||
{
|
||||
wasConnected = false;
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", String.format(context.getResources().getString(R.string.disconnectedFromWifi), getLastWifiSsid()) + " Switching to CellLocationChangedReceiver.", 3);
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", "Disconnected from wifi \"" + getLastWifiSsid() + "\". Switching to CellLocationChangedReceiver.", 3);
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
lastConnectedState = false;
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -143,13 +156,13 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
}
|
||||
}
|
||||
|
||||
public static void findRules(LocationProvider parentLocationProvider)
|
||||
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(parentLocationProvider.parentService))
|
||||
oneRule.activate(parentLocationProvider.parentService, false);
|
||||
if(oneRule.getsGreenLight(automationServiceInstance))
|
||||
oneRule.activate(automationServiceInstance, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,5 +238,4 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
Miscellaneous.logEvent("e", "Wifi Listener", "Error stopping wifiListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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,12 +1,12 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
@ -18,14 +18,17 @@ import java.util.ArrayList;
|
||||
|
||||
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static int batteryLevel=-1; // initialize with a better value than this
|
||||
public static AutomationService automationServiceRef = null;
|
||||
private static boolean usbHostConnected = false;
|
||||
static int batteryLevel = -1; // initialize with a better value than this
|
||||
static boolean usbHostConnected = false;
|
||||
static boolean batteryReceiverActive = false;
|
||||
static IntentFilter batteryIntentFilter = null;
|
||||
static Intent batteryStatus = null;
|
||||
|
||||
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
|
||||
private static int currentChargingType = 0; //AC, wireless, USB
|
||||
static BroadcastReceiver batteryInfoReceiverInstance = null;
|
||||
|
||||
private static boolean batteryReceiverActive = false;
|
||||
private static IntentFilter batteryIntentFilter = null;
|
||||
private static Intent batteryStatus = null;
|
||||
private static BroadcastReceiver batteryInfoReceiverInstance = null;
|
||||
public static void startBatteryReceiver(final AutomationService automationServiceRef)
|
||||
{
|
||||
if(!batteryReceiverActive)
|
||||
@ -40,8 +43,6 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
batteryIntentFilter = new IntentFilter();
|
||||
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
}
|
||||
|
||||
batteryStatus = automationServiceRef.registerReceiver(batteryInfoReceiverInstance, batteryIntentFilter);
|
||||
@ -78,17 +79,15 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
private static int deviceIsCharging = 0; //0=unknown, 1=no, 2=yes
|
||||
|
||||
public static int getDeviceIsCharging()
|
||||
public static int getCurrentChargingState()
|
||||
{
|
||||
return deviceIsCharging;
|
||||
return currentChargingState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
// Log.i("Battery", "Some battery event");
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Received event " + intent.getAction(), 5);
|
||||
|
||||
if (intent == null)
|
||||
return;
|
||||
@ -97,15 +96,12 @@ 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;
|
||||
@ -118,14 +114,19 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
|
||||
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged));
|
||||
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.");
|
||||
this.actionCharging(context);
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
|
||||
this.actionCharging(context, statusPlugged);
|
||||
break;
|
||||
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
|
||||
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Wireless charging.", 5);
|
||||
this.actionCharging(context, statusPlugged);
|
||||
break;
|
||||
case BatteryManager.BATTERY_PLUGGED_USB:
|
||||
this.actionUsbConnected(context);
|
||||
@ -134,42 +135,16 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
|
||||
switch(status)
|
||||
{
|
||||
// case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
// break;
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
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);
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
this.actionCharging(context, statusPlugged);
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
||||
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());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -180,33 +155,39 @@ 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);
|
||||
Miscellaneous.logEvent("w", "ChargingInfo", "Information isn't available, yet.", 4);
|
||||
break;
|
||||
case 1:
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is discharging.", 3);
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Device is discharging.", 3);
|
||||
break;
|
||||
case 2:
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3);
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Device is charging.", 3);
|
||||
break;
|
||||
}
|
||||
|
||||
return deviceIsCharging;
|
||||
return currentChargingState;
|
||||
}
|
||||
|
||||
private void actionCharging(Context context)
|
||||
public static int getCurrentChargingType()
|
||||
{
|
||||
if(deviceIsCharging != 2) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
return currentChargingType;
|
||||
}
|
||||
|
||||
private void actionCharging(Context context, int statusPlugged)
|
||||
{
|
||||
if(currentChargingState != BatteryManager.BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
|
||||
deviceIsCharging = 2;
|
||||
//activate rule(s)
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
||||
currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING;
|
||||
currentChargingType = statusPlugged;
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
|
||||
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 +197,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);
|
||||
}
|
||||
|
||||
@ -252,16 +234,16 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
usbHostConnected = true;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
|
||||
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(context))
|
||||
if(oneRule.getsGreenLight(context))
|
||||
oneRule.activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
this.actionCharging(context);
|
||||
this.actionCharging(context, BatteryManager.BATTERY_PLUGGED_USB);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,21 +255,24 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
usbHostConnected = false;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
|
||||
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.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 +281,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
|
||||
|
@ -94,12 +94,13 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event.", 4);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event: " + action, 5);
|
||||
|
||||
BluetoothDevice bluetoothDevice = null;
|
||||
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) | action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) || action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -107,7 +108,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
connectedDevices.add(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothConnectionTo), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) | action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) || action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -115,7 +116,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
connectedDevices.remove(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDisconnectFrom), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) | action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) || action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -124,10 +125,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);
|
||||
}
|
||||
}
|
||||
@ -300,4 +301,16 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
{
|
||||
return new Trigger_Enum[] { Trigger_Enum.bluetoothConnection };
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for Bluetooth.
|
||||
*
|
||||
* @return true if Bluetooth is available.
|
||||
*/
|
||||
public static boolean isBluetoothEnabled()
|
||||
{
|
||||
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
return bluetoothAdapter != null && bluetoothAdapter.isEnabled() && bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON;
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
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()));
|
||||
|
||||
Miscellaneous.logEvent("i", "Broadcast received", "Broadcast " + intent.getAction() + " received.", 4);
|
||||
if(intent.getExtras() != null && intent.getExtras().size() > 0)
|
||||
{
|
||||
for (String key : intent.getExtras().keySet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
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 };
|
||||
}
|
||||
}
|
@ -0,0 +1,659 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.CalendarContract;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class CalendarReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
static CalendarReceiver calendarReceiverInstance = null;
|
||||
static boolean calendarReceiverActive = false;
|
||||
static IntentFilter calendarIntentFilter = null;
|
||||
private static Intent calendarIntent = null;
|
||||
|
||||
public static final int AVAILABILITY_OUT_OF_OFFICE = 4;
|
||||
public static final int AVAILABILITY_WORKING_ELSEWHERE = 5;
|
||||
public static final String calendarAlarmAction = "ALARM_FOR_CALENDAR";
|
||||
|
||||
static List<AndroidCalendar> calendarsCache = null;
|
||||
static List<CalendarEvent> calendarEventsCache = null;
|
||||
static List<CalendarEvent> calendarEventsReoccurringCache = null;
|
||||
|
||||
// To determine for which events which rules have been executed
|
||||
static List<RuleEventPair> calendarEventsUsed = new ArrayList<>();
|
||||
|
||||
static Timer timer = null;
|
||||
static TimerTask timerTask = null;
|
||||
static Calendar nextWakeup = null;
|
||||
static AlarmManager alarmManager = null;
|
||||
static boolean wakeupNeedsToBeScheduledOrRescheduled = false;
|
||||
|
||||
public static CalendarEvent getLastTriggeringEvent()
|
||||
{
|
||||
if(calendarEventsUsed.size() > 0)
|
||||
{
|
||||
return calendarEventsUsed.get(calendarEventsUsed.size() -1).event;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class RuleEventPair
|
||||
{
|
||||
Rule rule;
|
||||
CalendarEvent event;
|
||||
|
||||
public RuleEventPair(Rule rule, CalendarEvent event)
|
||||
{
|
||||
this.rule = rule;
|
||||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addUsedPair(RuleEventPair pair)
|
||||
{
|
||||
// Add pair only if it's not in the list already.
|
||||
for(RuleEventPair usedPair : calendarEventsUsed)
|
||||
{
|
||||
if(usedPair.rule.equals(pair.rule) && usedPair.event.equals(pair.event))
|
||||
return;
|
||||
}
|
||||
|
||||
calendarEventsUsed.add(pair);
|
||||
}
|
||||
|
||||
public static CalendarReceiver getInstance()
|
||||
{
|
||||
if(calendarReceiverInstance == null)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
return calendarReceiverInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Received " + intent.getAction(), 4);
|
||||
|
||||
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Clearing calendar caches.", 4);
|
||||
|
||||
clearCaches();
|
||||
|
||||
routineAtAlarm();
|
||||
}
|
||||
else if(intent.getAction().equalsIgnoreCase(calendarAlarmAction))
|
||||
{
|
||||
routineAtAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
static void checkForRules(Context context)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationServiceRef)
|
||||
{
|
||||
startCalendarReceiver(automationServiceRef);
|
||||
}
|
||||
|
||||
static void clearCaches()
|
||||
{
|
||||
calendarsCache = null;
|
||||
calendarEventsCache = null;
|
||||
calendarEventsReoccurringCache = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
if(calendarReceiverActive)
|
||||
{
|
||||
if(calendarReceiverInstance != null)
|
||||
{
|
||||
AutomationService.getInstance().unregisterReceiver(calendarReceiverInstance);
|
||||
calendarReceiverInstance = null;
|
||||
}
|
||||
|
||||
clearCaches();
|
||||
calendarEventsUsed.clear();
|
||||
|
||||
calendarReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return calendarReceiverActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[]{Trigger.Trigger_Enum.calendarEvent};
|
||||
}
|
||||
|
||||
public static class AndroidCalendar
|
||||
{
|
||||
public int calendarId;
|
||||
public String displayName;
|
||||
public String accountString;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return displayName + " (" + accountString + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static class CalendarEvent
|
||||
{
|
||||
public AndroidCalendar calendar;
|
||||
public int calendarId;
|
||||
public String eventId;
|
||||
public String title;
|
||||
public String description;
|
||||
public String location;
|
||||
public String availability;
|
||||
public Calendar start, end;
|
||||
public boolean allDay, reoccurring;
|
||||
|
||||
public boolean isCurrentlyActive()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
return now.getTimeInMillis() >= start.getTimeInMillis() && now.getTimeInMillis() < end.getTimeInMillis();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Title: " + title + ", location: " + location + ", description: " + description + ", start: " + Miscellaneous.formatDate(start.getTime()) + ", end: " + Miscellaneous.formatDate(end.getTime()) + ", is currently active: " + String.valueOf(isCurrentlyActive()) + ", all day: " + String.valueOf(allDay) + ", availability: " + availability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent compareEvent = (CalendarEvent) obj;
|
||||
return calendarId == compareEvent.calendarId
|
||||
&&
|
||||
eventId.equals(compareEvent.eventId)
|
||||
&&
|
||||
title.equals(compareEvent.title)
|
||||
&&
|
||||
description.equals(compareEvent.description)
|
||||
&&
|
||||
location.equals(compareEvent.location)
|
||||
&&
|
||||
availability.equals(compareEvent.availability)
|
||||
&&
|
||||
start.getTimeInMillis() == compareEvent.start.getTimeInMillis()
|
||||
&&
|
||||
end.getTimeInMillis() == compareEvent.end.getTimeInMillis()
|
||||
&&
|
||||
allDay == compareEvent.allDay;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "CalendarReceiver compare()", Log.getStackTraceString(e), 5);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<AndroidCalendar> readCalendars(Context context)
|
||||
{
|
||||
if(calendarsCache == null)
|
||||
{
|
||||
calendarsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/calendars"),
|
||||
|
||||
new String[]{ CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CalendarContract.Calendars.OWNER_ACCOUNT, },
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
AndroidCalendar calendar = new AndroidCalendar();
|
||||
calendar.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
calendar.displayName = cursor.getString(1);
|
||||
calendar.accountString = cursor.getString(2);
|
||||
|
||||
calendarsCache.add(calendar);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
return calendarsCache;
|
||||
}
|
||||
|
||||
public static List<CalendarEvent> readCalendarEvents(Context context, boolean includeReoccurring, boolean includePastEvents)
|
||||
{
|
||||
if(calendarEventsCache == null)
|
||||
{
|
||||
calendarEventsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/events"),
|
||||
new String[] {
|
||||
CalendarContract.Events.CALENDAR_ID,
|
||||
CalendarContract.Events._ID,
|
||||
CalendarContract.Events.TITLE,
|
||||
CalendarContract.Events.DESCRIPTION,
|
||||
CalendarContract.Events.ALL_DAY,
|
||||
CalendarContract.Events.DTSTART,
|
||||
CalendarContract.Events.DTEND,
|
||||
CalendarContract.Events.EVENT_LOCATION,
|
||||
CalendarContract.Events.AVAILABILITY
|
||||
},
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent event = new CalendarEvent();
|
||||
event.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
|
||||
for(AndroidCalendar cal : readCalendars(context))
|
||||
{
|
||||
if(cal.calendarId == event.calendarId)
|
||||
{
|
||||
event.calendar = cal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.eventId = cursor.getString(1);
|
||||
event.title = cursor.getString(2);
|
||||
event.description = cursor.getString(3);
|
||||
event.allDay = cursor.getString(4).equals("1");
|
||||
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
|
||||
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
|
||||
event.location = cursor.getString(7);
|
||||
event.availability = cursor.getString(8);
|
||||
event.reoccurring = false;
|
||||
|
||||
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
calendarEventsCache.add(event);
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
if(includeReoccurring && calendarEventsReoccurringCache == null)
|
||||
{
|
||||
calendarEventsReoccurringCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
Calendar queryStart, queryEnd;
|
||||
if(includePastEvents)
|
||||
queryStart = Miscellaneous.calendarFromLong(0);
|
||||
else
|
||||
queryStart = Calendar.getInstance();
|
||||
|
||||
queryEnd = Calendar.getInstance();
|
||||
queryEnd.add(Calendar.YEAR, 1);
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/instances/when/" + queryStart.getTimeInMillis() + "/" + queryEnd.getTimeInMillis()),
|
||||
new String[] {
|
||||
CalendarContract.Instances.CALENDAR_ID,
|
||||
CalendarContract.Instances._ID,
|
||||
CalendarContract.Instances.TITLE,
|
||||
CalendarContract.Instances.DESCRIPTION,
|
||||
CalendarContract.Instances.ALL_DAY,
|
||||
CalendarContract.Instances.BEGIN,
|
||||
CalendarContract.Instances.END,
|
||||
CalendarContract.Instances.EVENT_LOCATION,
|
||||
CalendarContract.Instances.AVAILABILITY
|
||||
},
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent event = new CalendarEvent();
|
||||
event.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
|
||||
for(AndroidCalendar cal : readCalendars(context))
|
||||
{
|
||||
if(cal.calendarId == event.calendarId)
|
||||
{
|
||||
event.calendar = cal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.eventId = cursor.getString(1);
|
||||
event.title = cursor.getString(2);
|
||||
event.description = cursor.getString(3);
|
||||
event.allDay = cursor.getString(4).equals("1");
|
||||
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
|
||||
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
|
||||
event.location = cursor.getString(7);
|
||||
event.availability = cursor.getString(8);
|
||||
event.reoccurring = true;
|
||||
|
||||
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
{
|
||||
// For the moment keeping separate records to some extent
|
||||
calendarEventsReoccurringCache.add(event);
|
||||
calendarEventsCache.add(event);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
return calendarEventsCache;
|
||||
}
|
||||
|
||||
protected static void routineAtAlarm()
|
||||
{
|
||||
checkForRules(Miscellaneous.getAnyContext());
|
||||
|
||||
// Set next timer
|
||||
calculateNextWakeup();
|
||||
armOrRearmTimer();
|
||||
}
|
||||
|
||||
public static void armOrRearmTimer()
|
||||
{
|
||||
PendingIntent pi = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (alarmManager == null)
|
||||
{
|
||||
alarmManager = (AlarmManager) Miscellaneous.getAnyContext().getSystemService(Context.ALARM_SERVICE);
|
||||
}
|
||||
|
||||
if(pi == null)
|
||||
{
|
||||
Intent intent = new Intent(Miscellaneous.getAnyContext(), CalendarReceiver.class);
|
||||
intent.setAction(calendarAlarmAction);
|
||||
pi = PendingIntent.getBroadcast(AutomationService.getInstance(), 0, intent, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timerTask = new TimerTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
routineAtAlarm();
|
||||
}
|
||||
};
|
||||
|
||||
if(timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
timer = new Timer();
|
||||
}
|
||||
|
||||
if(nextWakeup == null)
|
||||
{
|
||||
readCalendarEvents(Miscellaneous.getAnyContext(), true,false);
|
||||
calculateNextWakeup();
|
||||
}
|
||||
|
||||
// If it's now filled, go on
|
||||
if(nextWakeup != null && wakeupNeedsToBeScheduledOrRescheduled)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && alarmManager.canScheduleExactAlarms()))
|
||||
{
|
||||
try
|
||||
{
|
||||
alarmManager.cancel(pi);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
Miscellaneous.logEvent("i", "armOrRearmTimer()", "Scheduling wakeup for calendar at " + Miscellaneous.formatDate(nextWakeup.getTime()), 4);
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
wakeupNeedsToBeScheduledOrRescheduled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
timer.schedule(timerTask, nextWakeup.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateNextWakeup()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false);
|
||||
|
||||
if (events.size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeup()", "No future events, nothing to schedule.", 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
List<Long> wakeUpCandidatesList = new ArrayList<>();
|
||||
|
||||
for (CalendarEvent event : events)
|
||||
{
|
||||
for (Rule r : ruleCandidates)
|
||||
{
|
||||
for (Trigger t : r.getTriggerSet())
|
||||
{
|
||||
if (t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent) && t.checkCalendarEvent(event, true))
|
||||
{
|
||||
/*
|
||||
Device needs to wakeup at start AND end of events, no matter what is specified in triggers.
|
||||
This is because we also need to know when a trigger doesn't apply anymore to make it
|
||||
count for hasStateNotAppliedSinceLastRuleExecution().
|
||||
Otherwise the same rule would not get executed again even after calendar events have come and gone.
|
||||
*/
|
||||
|
||||
if(event.start.getTimeInMillis() > now.getTimeInMillis())
|
||||
wakeUpCandidatesList.add(event.start.getTimeInMillis());
|
||||
|
||||
if(event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
wakeUpCandidatesList.add(event.end.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(wakeUpCandidatesList);
|
||||
|
||||
if(wakeUpCandidatesList.size() == 0)
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Not scheduling any calendar related wakeup as there are no future events that might match a configured trigger.", 4);
|
||||
else
|
||||
{
|
||||
if (nextWakeup == null || nextWakeup.getTimeInMillis() != wakeUpCandidatesList.get(0))
|
||||
{
|
||||
Calendar newAlarm = Miscellaneous.calendarFromLong(wakeUpCandidatesList.get(0));
|
||||
if (nextWakeup == null)
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was null.", 4);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Chose " + Miscellaneous.formatDate(newAlarm.getTime()) + " as next wakeup for calendar triggers. Old was " + Miscellaneous.formatDate(nextWakeup.getTime()), 4);
|
||||
nextWakeup = newAlarm;
|
||||
if (!wakeupNeedsToBeScheduledOrRescheduled)
|
||||
wakeupNeedsToBeScheduledOrRescheduled = true;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Alarm " + Miscellaneous.formatDate(nextWakeup.getTime()) + " has been selected as next wakeup, but not rescheduling since this was not a change.", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startCalendarReceiver(final AutomationService automationServiceRef)
|
||||
{
|
||||
if (!calendarReceiverActive)
|
||||
{
|
||||
if (calendarReceiverInstance == null)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
if (calendarIntentFilter == null)
|
||||
{
|
||||
calendarIntentFilter = new IntentFilter();
|
||||
calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED);
|
||||
calendarIntentFilter.addDataScheme("content");
|
||||
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
|
||||
}
|
||||
|
||||
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter);
|
||||
|
||||
calendarReceiverActive = true;
|
||||
|
||||
armOrRearmTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean mayRuleStillBeActivatedForPendingCalendarEvents(Rule rule)
|
||||
{
|
||||
for(RuleEventPair pair : calendarEventsUsed)
|
||||
Miscellaneous.logEvent("i", "mayRuleStillBeActivatedForPendingCalendarEvents()", "Existing pair of " + pair.rule.getName() + " and " + pair.event, 5);
|
||||
|
||||
for(CalendarEvent event : readCalendarEvents(Miscellaneous.getAnyContext(), true,false))
|
||||
{
|
||||
for(Trigger t : rule.getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent) && t.checkCalendarEvent(event, false))
|
||||
{
|
||||
if (!hasEventBeenUsedInRule(rule, event))
|
||||
{
|
||||
/*
|
||||
If there are multiple parallel calendar events and a rule has multiple
|
||||
triggers of type calendar event, we don't want the rule to fire only once.
|
||||
*/
|
||||
if(rule.getAmountOfTriggersForType(Trigger.Trigger_Enum.calendarEvent) == 1)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "mayRuleStillBeActivatedForPendingCalendarEvents()", "Rule " + rule.getName() + " has not been used in conjunction with event " + event, 4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasEventBeenUsedInRule(Rule rule, CalendarEvent event)
|
||||
{
|
||||
for (RuleEventPair executedPair : calendarEventsUsed)
|
||||
{
|
||||
if (executedPair.rule.equals(rule) && executedPair.event.equals(event))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<CalendarReceiver.CalendarEvent> getApplyingCalendarEvents(Rule rule)
|
||||
{
|
||||
List<CalendarReceiver.CalendarEvent> returnList = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
|
||||
|
||||
for(Trigger t : rule.getTriggerSet())
|
||||
{
|
||||
if(t.getTriggerType().equals(Trigger.Trigger_Enum.calendarEvent))
|
||||
{
|
||||
for (CalendarReceiver.CalendarEvent event : calendarEvents)
|
||||
{
|
||||
if (t.checkCalendarEvent(event, false))
|
||||
returnList.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "getApplyingCalendarEvents()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
@ -161,7 +162,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
|
||||
WifiBroadcastReceiver.setLastWifiSsid(wifiInfo.getSSID());
|
||||
WifiBroadcastReceiver.findRules(automationServiceRef.getLocationProvider());
|
||||
WifiBroadcastReceiver.findRules(automationServiceRef);
|
||||
break;
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
boolean isRoaming = isRoaming(context);
|
||||
@ -171,10 +172,11 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -219,7 +221,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
// This will serve as a disconnected event. Happens if wifi is connected, then module deactivated.
|
||||
Miscellaneous.logEvent("i", "Connectivity", "Wifi deactivated while having been connected before.", 4);
|
||||
WifiBroadcastReceiver.lastConnectedState = false;
|
||||
WifiBroadcastReceiver.findRules(automationServiceRef.getLocationProvider());
|
||||
WifiBroadcastReceiver.findRules(automationServiceRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,584 @@
|
||||
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.Nullable;
|
||||
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.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
private static AutomationService automationServiceRef;
|
||||
private static AlarmManager centralAlarmManagerInstance;
|
||||
private static boolean alarmListenerActive=false;
|
||||
private static 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> allRulesWithTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
|
||||
for(int i=0; i < allRulesWithTimeFrame.size(); i++)
|
||||
{
|
||||
if(allRulesWithTimeFrame.get(i).getsGreenLight(context))
|
||||
allRulesWithTimeFrame.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
setOrResetAlarms();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public static void setOrResetAlarms()
|
||||
{
|
||||
alarmCandidates.clear();
|
||||
|
||||
Calendar calNow = Calendar.getInstance();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
|
||||
|
||||
clearAlarms();
|
||||
|
||||
int i=0;
|
||||
|
||||
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
|
||||
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
|
||||
|
||||
if(tf.getRepetition() > 0)
|
||||
{
|
||||
// if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
|
||||
// {
|
||||
Calendar calSchedule = getNextRepeatedExecution(oneTrigger);
|
||||
|
||||
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);
|
||||
|
||||
if(Miscellaneous.getAnyContext().getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
else
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
centralAlarmManagerInstance.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
else
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis());
|
||||
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
alarmListenerActive = true;
|
||||
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
|
||||
DateTimeListener.setOrResetAlarms();
|
||||
|
||||
// // 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);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
static int getNextDayIntForExecution(Trigger trigger)
|
||||
{
|
||||
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
if(tf.getDayList().contains(now.get(Calendar.DAY_OF_WEEK)))
|
||||
return now.get(Calendar.DAY_OF_WEEK);
|
||||
else
|
||||
{
|
||||
int dayNumberOfNextExecution = now.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
while(!tf.getDayList().contains(dayNumberOfNextExecution))
|
||||
{
|
||||
dayNumberOfNextExecution++;
|
||||
if(dayNumberOfNextExecution > 6)
|
||||
dayNumberOfNextExecution = 1;
|
||||
}
|
||||
|
||||
return dayNumberOfNextExecution;
|
||||
}
|
||||
}
|
||||
|
||||
static int getDayDelta(Calendar now, int dayNumberOfNextExecution)
|
||||
{
|
||||
int result = dayNumberOfNextExecution - now.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
if(result >= 0)
|
||||
return result;
|
||||
else
|
||||
return 6 + result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public static Calendar getNextRepeatedExecution(Trigger trigger)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
Miscellaneous.logEvent("i", "DateTimeListener", "Checking for next repetition execution after " + Miscellaneous.formatDate(now.getTime()), 5);
|
||||
Calendar calculationStart, calSchedule = null;
|
||||
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
|
||||
|
||||
if(tf.getRepetition() > 0)
|
||||
{
|
||||
/*
|
||||
Are we inside of the timeframe or outside?
|
||||
|
||||
Inside -> is this demanded?
|
||||
Yes:
|
||||
If last execution known, calculate from it
|
||||
If not known, calculate from start of timeframe
|
||||
No:
|
||||
Use end-time and add repetition
|
||||
|
||||
Outside? -> is this demanded?
|
||||
Yes:
|
||||
If last execution known, calculate from it
|
||||
If not known, calculate from end of timeframe
|
||||
No:
|
||||
Use start-time and add repetition
|
||||
*/
|
||||
|
||||
if(areWeInTimeFrame(trigger, new Date()))
|
||||
{
|
||||
if(trigger.getTriggerParameter())
|
||||
{
|
||||
if(trigger.getParentRule().getLastExecution() != null)
|
||||
{
|
||||
calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
calculationStart = (Calendar) now.clone();
|
||||
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours());
|
||||
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes());
|
||||
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds());
|
||||
calculationStart.set(Calendar.MILLISECOND, 0);
|
||||
}
|
||||
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
|
||||
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
|
||||
}
|
||||
else
|
||||
{
|
||||
calculationStart = (Calendar) now.clone();
|
||||
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours());
|
||||
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
|
||||
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds());
|
||||
calculationStart.set(Calendar.MILLISECOND, 0);
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
calSchedule.add(Calendar.SECOND, (int) tf.getRepetition());
|
||||
}
|
||||
}
|
||||
else // not in timeframe
|
||||
{
|
||||
if (!trigger.getTriggerParameter())
|
||||
{
|
||||
if (trigger.getParentRule().getLastExecution() != null)
|
||||
{
|
||||
calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone();
|
||||
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
|
||||
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
|
||||
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
|
||||
return calSchedule;
|
||||
}
|
||||
else
|
||||
{
|
||||
calculationStart = (Calendar) now.clone();
|
||||
if(tf.getDayList().contains(now.get(Calendar.DAY_OF_WEEK)))
|
||||
{
|
||||
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours());
|
||||
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
|
||||
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds());
|
||||
calculationStart.set(Calendar.MILLISECOND, 0);
|
||||
calculationStart.add(Calendar.SECOND, (int) tf.getRepetition());
|
||||
|
||||
int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger));
|
||||
calculationStart.add(Calendar.DAY_OF_WEEK, dayDelta);
|
||||
}
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
|
||||
return calSchedule;
|
||||
}
|
||||
/*long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
|
||||
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));*/
|
||||
}
|
||||
else
|
||||
{
|
||||
calculationStart = (Calendar) now.clone();
|
||||
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours());
|
||||
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes());
|
||||
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds());
|
||||
calculationStart.set(Calendar.MILLISECOND, 0);
|
||||
calSchedule = (Calendar) calculationStart.clone();
|
||||
calSchedule.add(Calendar.SECOND, (int) (tf.getRepetition()));
|
||||
}
|
||||
|
||||
if (Miscellaneous.compareTimes(calSchedule, now) > 0)
|
||||
calSchedule.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
|
||||
int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger));
|
||||
calSchedule.add(Calendar.DAY_OF_WEEK, dayDelta);
|
||||
|
||||
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Trigger " + trigger.toString() + " is not configured to repeat.", 5);
|
||||
|
||||
return calSchedule;
|
||||
}
|
||||
|
||||
public static boolean areWeInTimeFrame(Trigger trigger, Object triggeringObject)
|
||||
{
|
||||
/*
|
||||
* Use format known from Automation
|
||||
* 07:30:00/17:30:00/23456/300 <-- last parameter is optional: repetition in seconds
|
||||
* Also required: inside or outside that interval
|
||||
*/
|
||||
|
||||
Date triggeringTime;
|
||||
// if(triggeringObject instanceof Date)
|
||||
// triggeringTime = (Date)triggeringObject;
|
||||
// else
|
||||
triggeringTime = new Date();
|
||||
|
||||
String timeString = String.valueOf(triggeringTime.getHours()) + ":" + String.valueOf(triggeringTime.getMinutes()) + ":" + String.valueOf(triggeringTime.getSeconds());
|
||||
TimeObject nowTime = TimeObject.valueOf(timeString);
|
||||
Calendar calNow = Calendar.getInstance();
|
||||
|
||||
try
|
||||
{
|
||||
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
|
||||
|
||||
if(tf.getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK)))
|
||||
{
|
||||
if(
|
||||
// Regular case, start time is lower than end time
|
||||
(
|
||||
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
|
||||
&&
|
||||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
|
||||
)
|
||||
||
|
||||
// Other case, start time higher than end time, timeframe goes over midnight
|
||||
(
|
||||
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0
|
||||
&&
|
||||
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
|
||||
||
|
||||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0)
|
||||
)
|
||||
||
|
||||
// further case: start and end times are identical, meaning a 24h window
|
||||
(
|
||||
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) == 0
|
||||
)
|
||||
)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Trigger", "There was an error while checking if the time based trigger applies: " + Log.getStackTraceString(e), 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -74,10 +75,10 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Headset " + name + " plugged in.", 4);
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.headsetPlugged);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -102,13 +103,12 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
{
|
||||
Miscellaneous.logEvent("i", "HeadsetJackListener", "Starting HeadsetJackListener", 4);
|
||||
headphoneJackListenerActive = true;
|
||||
// getInstance().startHeadphoneJackListener(AutomationService.getInstance(), headphoneJackListenerIntentFilter);
|
||||
automationService.registerReceiver(this, headphoneJackListenerIntentFilter);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
Miscellaneous.logEvent("e", "HeadsetJackListener", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +120,6 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
if(headphoneJackListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "HeadsetJackListener", "Stopping HeadsetJackListener", 4);
|
||||
// getInstance().stopHeadphoneJackListener(AutomationService.getInstance());
|
||||
automationService.unregisterReceiver(this);
|
||||
headphoneJackListenerActive = false;
|
||||
}
|
||||
@ -133,7 +132,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());
|
||||
}
|
||||
|
||||
|
||||
@ -148,5 +147,4 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
{
|
||||
return new Trigger_Enum[] { Trigger_Enum.headsetPlugged };
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
@ -216,6 +217,8 @@ public class NfcReceiver
|
||||
|
||||
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
|
||||
|
||||
if(ndefMessage != null)
|
||||
{
|
||||
NdefRecord[] records = ndefMessage.getRecords();
|
||||
for (NdefRecord ndefRecord : records)
|
||||
{
|
||||
@ -231,6 +234,7 @@ public class NfcReceiver
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,10 +1,15 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
@ -14,14 +19,14 @@ import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
// See here for reference: http://gmariotti.blogspot.com/2013/11/notificationlistenerservice-and-kitkat.html
|
||||
|
||||
@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 NotificationListener instance;
|
||||
static SimpleNotification lastNotification = null;
|
||||
|
||||
@ -37,11 +42,30 @@ 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";
|
||||
|
||||
public static void setLastNotification(SimpleNotification notification)
|
||||
{
|
||||
lastNotification = notification;
|
||||
}
|
||||
public static SimpleNotification getLastNotification()
|
||||
{
|
||||
return lastNotification;
|
||||
}
|
||||
|
||||
// To determine for which notifications which rules have been executed
|
||||
static List<RuleNotificationPair> notificationUsed = new ArrayList<>();
|
||||
|
||||
public static class RuleNotificationPair
|
||||
{
|
||||
Rule rule;
|
||||
SimpleNotification notification;
|
||||
|
||||
public RuleNotificationPair(Rule rule, SimpleNotification sn)
|
||||
{
|
||||
this.rule = rule;
|
||||
this.notification = sn;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
@ -76,37 +100,71 @@ public class NotificationListener extends NotificationListenerService
|
||||
|
||||
synchronized boolean checkNotification(boolean created, StatusBarNotification sbn)
|
||||
{
|
||||
//TODO: Merge with functino in Trigger class
|
||||
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(lastResponseToNotification == null || lastResponseToNotification.getTimeInMillis() < lastNotification.publishTime.getTimeInMillis())
|
||||
// {
|
||||
// lastResponseToNotification = Calendar.getInstance();
|
||||
if(created)
|
||||
Miscellaneous.logEvent("i", "New notification", lastNotification.toString(), 5);
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Notification removed", lastNotification.toString(), 5);
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).applies(NotificationListener.this))
|
||||
if(ruleCandidates.get(i).getsGreenLight(NotificationListener.this))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("e", "NotificationCheck", "Ignoring notification as it is old.", 5);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static class SimpleNotification
|
||||
{
|
||||
boolean created;
|
||||
@ -162,6 +220,31 @@ 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
|
||||
public boolean equals(@Nullable Object obj)
|
||||
{
|
||||
return
|
||||
this.publishTime.getTimeInMillis() == ((SimpleNotification)obj).publishTime.getTimeInMillis()
|
||||
&&
|
||||
this.app.equals(((SimpleNotification)obj).app)
|
||||
&&
|
||||
this.title.equals(((SimpleNotification)obj).title)
|
||||
&&
|
||||
this.text.equals(((SimpleNotification)obj).text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,4 +258,43 @@ 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());
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
public void clickNotificationButton(StatusBarNotification sbn, String buttonText)
|
||||
{
|
||||
boolean buttonFound = false;
|
||||
|
||||
if(sbn.getNotification().actions != null)
|
||||
{
|
||||
for (Notification.Action a : sbn.getNotification().actions)
|
||||
{
|
||||
if((Miscellaneous.isRegularExpression(buttonText) && a.title.toString().matches(buttonText)) || a.title.toString().equalsIgnoreCase(buttonText))
|
||||
{
|
||||
if (!buttonFound)
|
||||
buttonFound = true;
|
||||
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("w", "clickNotificationButton()", "Pressing button with text \"" + a.title.toString() + "\".", 2);
|
||||
a.actionIntent.send();
|
||||
}
|
||||
catch (PendingIntent.CanceledException e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "clickNotificationButton()", Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!buttonFound)
|
||||
Miscellaneous.logEvent("w", "clickNotificationButton()", "Button with text \n" + buttonText + "\n could not found.", 2);
|
||||
}
|
||||
}
|
@ -14,14 +14,6 @@ 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);
|
||||
|
||||
Miscellaneous.logEvent("i", context.getResources().getString(R.string.applicationHasBeenUpdated), context.getResources().getString(R.string.applicationHasBeenUpdated), 2);
|
||||
@ -34,9 +26,6 @@ public class PackageReplacedReceiver extends BroadcastReceiver
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", context.getResources().getString(R.string.logNotStartingServiceAfterAppUpdate), 2);
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", "Service", "Some other app has been updated.", 5);
|
||||
}
|
||||
|
||||
private static boolean hasServiceBeenRunning()
|
||||
|
@ -1,28 +1,36 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Build;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
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 com.jens.automation2.Trigger.Trigger_Enum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PhoneStatusListener implements AutomationListenerInterface
|
||||
{
|
||||
protected static int currentStateIncoming = -1;
|
||||
protected static int currentStateOutgoing = -1;
|
||||
static int problematicAndroidLevel = 29;
|
||||
protected static String lastPhoneNumber="";
|
||||
protected static int lastPhoneDirection = -1; //0=incoming, 1=outgoing
|
||||
protected static int currentState = -1;
|
||||
|
||||
protected static boolean incomingCallsReceiverActive = false;
|
||||
protected static boolean outgoingCallsReceiverActive = false;
|
||||
@ -31,7 +39,6 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
protected static IncomingCallsReceiver incomingCallsReceiverInstance;
|
||||
protected static BroadcastReceiver outgoingCallsReceiverInstance;
|
||||
|
||||
|
||||
public static boolean isIncomingCallsReceiverActive()
|
||||
{
|
||||
return incomingCallsReceiverActive;
|
||||
@ -59,12 +66,27 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
return lastPhoneNumber;
|
||||
}
|
||||
|
||||
public static class IncomingCallsReceiver extends PhoneStateListener
|
||||
public static void setCurrentState(int currentState)
|
||||
{
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber)
|
||||
PhoneStatusListener.currentState = currentState;
|
||||
}
|
||||
|
||||
public static int getCurrentState()
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "Call state", "New call state: " + String.valueOf(state), 4);
|
||||
return currentState;
|
||||
}
|
||||
|
||||
public static interface IncomingCallsReceiver
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected static void workWithIncomingCallData(int state, String incomingNumber)
|
||||
{
|
||||
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
|
||||
{
|
||||
// This status update is actually for an outgoing call
|
||||
setCurrentState(state);
|
||||
|
||||
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
@ -73,167 +95,154 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
if(currentStateIncoming == TelephonyManager.CALL_STATE_OFFHOOK)
|
||||
setCurrentStateIncoming(state);
|
||||
else if(currentStateOutgoing == TelephonyManager.CALL_STATE_OFFHOOK)
|
||||
setCurrentStateOutgoing(state);
|
||||
else
|
||||
currentStateIncoming = state;
|
||||
currentStateOutgoing = state;
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
if(currentStateIncoming == TelephonyManager.CALL_STATE_RINGING)
|
||||
setCurrentStateIncoming(state);
|
||||
else if(currentStateOutgoing == TelephonyManager.CALL_STATE_RINGING)
|
||||
setCurrentStateOutgoing(state);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
String number = "unknown";
|
||||
if(incomingNumber != null && incomingNumber.length() > 0)
|
||||
number = incomingNumber;
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), number), 4);
|
||||
|
||||
setCurrentStateIncoming(state);
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
|
||||
break;
|
||||
}
|
||||
|
||||
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).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setCurrentState(state);
|
||||
setLastPhoneDirection(1);
|
||||
|
||||
if (incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), incomingNumber), 4);
|
||||
break;
|
||||
}
|
||||
|
||||
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).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IncomingCallsReceiverOld extends PhoneStateListener implements IncomingCallsReceiver
|
||||
{
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "Call state", "New call state: " + String.valueOf(state), 4);
|
||||
|
||||
/*
|
||||
Unfortunately receivers for incoming and outgoing calls behave pretty differently:
|
||||
|
||||
The Outgoing-Receiver is called when starting a call (ringing)
|
||||
It is not called when that outgoing call ends however, only the incoming receiver.
|
||||
|
||||
If the last call was outgoing the state has not changed to idle this is kind of a fake alert.
|
||||
*/
|
||||
|
||||
workWithIncomingCallData(state, incomingNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public static class IncomingCallsReceiverNew extends BroadcastReceiver implements IncomingCallsReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
/*
|
||||
this code detects both incoming and outgoing,
|
||||
if the state changes idle => ringing you know it's an incoming call,
|
||||
if the state changes idle => offhook, you know it's an outgoing call
|
||||
*/
|
||||
|
||||
if (!intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL))
|
||||
{
|
||||
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
|
||||
int state = 99;
|
||||
|
||||
switch(stateStr)
|
||||
{
|
||||
case "RINGING":
|
||||
state = TelephonyManager.CALL_STATE_RINGING;
|
||||
break;
|
||||
case "IDLE":
|
||||
state = TelephonyManager.CALL_STATE_IDLE;
|
||||
break;
|
||||
case "OFFHOOK":
|
||||
state = TelephonyManager.CALL_STATE_OFFHOOK;
|
||||
break;
|
||||
}
|
||||
|
||||
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
|
||||
Log.i("test", "test");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setLastPhoneDirection(int i)
|
||||
{
|
||||
lastPhoneDirection = i;
|
||||
}
|
||||
|
||||
public static class OutgoingCallsReceiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
setCurrentStateOutgoing(2);
|
||||
setLastPhoneNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallFrom), getLastPhoneNumber()), 4);
|
||||
/*
|
||||
This receiver is ONLY triggered when outgoing calls ring, not when that call is established or ends.
|
||||
*/
|
||||
setLastPhoneDirection(2);
|
||||
|
||||
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.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for(int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInACall()
|
||||
{
|
||||
if(isInIncomingCall() | isInOutgoingCall())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return getCurrentState() != TelephonyManager.CALL_STATE_IDLE;
|
||||
}
|
||||
|
||||
public static boolean isInIncomingCall()
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "Incoming call state", String.valueOf(currentStateIncoming), 5);
|
||||
switch(currentStateIncoming)
|
||||
{
|
||||
// case -1:
|
||||
// return false;
|
||||
// case 0:
|
||||
// return false;
|
||||
// case 1:
|
||||
// return true;
|
||||
case 2:
|
||||
return true;
|
||||
// case 3:
|
||||
// return true;
|
||||
// case 4:
|
||||
// return true;
|
||||
// default:
|
||||
// return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isInOutgoingCall()
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "Outgoing call state", String.valueOf(currentStateOutgoing), 5);
|
||||
switch(currentStateOutgoing)
|
||||
{
|
||||
// case -1:
|
||||
// return false;
|
||||
// case 0:
|
||||
// return false;
|
||||
// case 1:
|
||||
// return true;
|
||||
case 2:
|
||||
return true;
|
||||
// case 3:
|
||||
// return true;
|
||||
// case 4:
|
||||
// return true;
|
||||
// default:
|
||||
// return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void setCurrentStateIncoming(int state)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "Call state", "New incoming call state: " + String.valueOf(state), 4);
|
||||
if(currentStateIncoming != state)
|
||||
{
|
||||
if(lastPhoneDirection != 1)
|
||||
lastPhoneDirection = 1;
|
||||
|
||||
if(
|
||||
(state == 0 && currentStateIncoming == 2)
|
||||
|
|
||||
(state == 2 && (currentStateIncoming == 0 | currentStateIncoming == 1))
|
||||
)
|
||||
{
|
||||
currentStateIncoming = state;
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(isInIncomingCall());
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).applies(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
currentStateIncoming = state;
|
||||
}
|
||||
}
|
||||
public static int getCurrentStateIncoming()
|
||||
{
|
||||
return currentStateIncoming;
|
||||
}
|
||||
|
||||
public static void setCurrentStateOutgoing(int state)
|
||||
{
|
||||
if(currentStateOutgoing != state)
|
||||
{
|
||||
if(lastPhoneDirection != 2)
|
||||
lastPhoneDirection = 2;
|
||||
|
||||
if(
|
||||
(state == 0 && currentStateOutgoing == 2)
|
||||
|
|
||||
(state == 2 && (currentStateOutgoing == 0 | currentStateOutgoing == 1)))
|
||||
{
|
||||
PhoneStatusListener.currentStateOutgoing = state;
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(isInOutgoingCall());
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).applies(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
PhoneStatusListener.currentStateOutgoing = state;
|
||||
}
|
||||
}
|
||||
public static int getCurrentStateOutgoing()
|
||||
{
|
||||
return currentStateOutgoing;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Future remark:
|
||||
Apps that redirect outgoing calls should use the android.telecom.CallRedirectionService API.
|
||||
Apps that perform call screening should use the android.telecom.CallScreeningService API.
|
||||
*/
|
||||
|
||||
public static void startPhoneStatusListener(AutomationService automationService)
|
||||
{
|
||||
@ -244,7 +253,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
}
|
||||
|
||||
if(incomingCallsReceiverInstance == null)
|
||||
incomingCallsReceiverInstance = new IncomingCallsReceiver();
|
||||
{
|
||||
// if(Build.VERSION.SDK_INT >= 31)
|
||||
// incomingCallsReceiverInstance = new IncomingCallsReceiverNew();
|
||||
// else
|
||||
incomingCallsReceiverInstance = new IncomingCallsReceiverOld();
|
||||
}
|
||||
|
||||
if(outgoingCallsReceiverInstance == null)
|
||||
outgoingCallsReceiverInstance = new OutgoingCallsReceiver();
|
||||
@ -254,8 +268,17 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
if(!incomingCallsReceiverActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->incomingCallsReceiver", 4);
|
||||
// if(Build.VERSION.SDK_INT >= problematicAndroidLevel)
|
||||
// {
|
||||
// IntentFilter callsFilter = new IntentFilter();
|
||||
// callsFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
||||
// automationService.registerReceiver((IncomingCallsReceiverNew)incomingCallsReceiverInstance, callsFilter);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
TelephonyManager tm = (TelephonyManager) automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
tm.listen((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
// }
|
||||
incomingCallsReceiverActive = true;
|
||||
}
|
||||
|
||||
@ -279,8 +302,15 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
if(incomingCallsReceiverActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "PhoneStatusListener", "Stopping phoneStatusListener", 4);
|
||||
// if(Build.VERSION.SDK_INT >= 31)
|
||||
// {
|
||||
// automationService.unregisterReceiver((IncomingCallsReceiverNew)incomingCallsReceiverInstance);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
TelephonyManager tm = (TelephonyManager) automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
|
||||
tm.listen((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
|
||||
// }
|
||||
incomingCallsReceiverActive = false;
|
||||
}
|
||||
|
||||
@ -312,9 +342,9 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
public static boolean haveAllPermission()
|
||||
{
|
||||
return
|
||||
ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext())
|
||||
ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameCall, Miscellaneous.getAnyContext());
|
||||
ActivityPermissions.havePermission(Manifest.permission.PROCESS_OUTGOING_CALLS, Miscellaneous.getAnyContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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,8 +45,6 @@ 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
|
||||
|
||||
@ -59,18 +59,13 @@ public class ProcessListener implements AutomationListenerInterface
|
||||
for(String entry : getRecentlyStoppedApps())
|
||||
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStopped), entry, 3);
|
||||
|
||||
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))
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,13 +11,14 @@ import com.jens.automation2.Settings;
|
||||
|
||||
public class StartupIntentReceiver extends BroadcastReceiver
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Settings.readFromPersistentStorage(context);
|
||||
|
||||
Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
|
||||
Miscellaneous.startupContext = context;
|
||||
|
||||
// Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
|
||||
|
||||
if(Settings.startServiceAtSystemBoot)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user