172 Commits

Author SHA1 Message Date
a8b2c3bf7d New version 2023-04-24 23:08:21 +02:00
49d272be1e PhoneStatusListener 2023-04-16 22:31:01 +02:00
d9e54c7780 PhoneStatusListener 2023-04-14 23:16:47 +02:00
170dbbc7e8 PhoneStatusListener 2023-04-13 00:10:21 +02:00
3fc1dd1a26 Telephony receiver 2023-04-12 18:05:00 +02:00
0acb52099c Added overlay permission 2023-03-31 23:58:11 +02:00
b6015a3f2e New versions prepared 2023-03-23 22:59:05 +01:00
ae1e767fa6 copy to clipboard action 2023-03-17 23:22:42 +01:00
6e12e71133 copy to clipboard action 2023-03-16 23:35:38 +01:00
e4e3faea06 copy to clipboard action 2023-03-15 23:27:27 +01:00
7c42250e13 copy to clipboard action 2023-03-12 23:57:54 +01:00
ebb0724b28 Android 13 wifi permission text 2023-03-08 23:11:58 +01:00
a7ae0c6588 Android 13 wifi permission 2023-03-01 23:35:19 +01:00
e5433bf2ec Possibility to pick custom language 2023-02-26 18:12:47 +01:00
fd8ffd4f7d translation error fixed 2023-02-19 00:09:20 +01:00
f49455712a Hint for notification access on Android 13 2023-02-18 23:59:29 +01:00
132f64114e Bug fixed: Editing variable action was not possible 2023-02-12 23:57:37 +01:00
27e9b3e0d1 New release 2023-02-09 23:24:29 +01:00
a6c6dfc6ba Bug fixed in TTS 2023-02-06 14:24:46 +01:00
6a7875cc61 Bugfix release 2023-02-01 23:29:26 +01:00
6f80caa1c6 Bugfix release 2023-01-17 22:38:49 +01:00
a9646cbf28 Autostart error fixed 2023-01-16 23:44:28 +01:00
52edfa32df Fixed bug with multiple time frames with reoccurrence configured 2023-01-16 16:54:54 +01:00
ca81e6a7bd Log improvements 2023-01-15 23:18:42 +01:00
49e4c20ab6 Allow negative integers as intents 2023-01-14 22:50:43 +01:00
ab98b4d1db Build number changed because of Google Play version 2023-01-14 22:20:31 +01:00
6b32301894 New version prepared 2023-01-14 21:55:52 +01:00
d9cdfab828 French translation updated 2023-01-13 22:52:45 +01:00
62a8723344 Setting ringtones from profiles works again 2023-01-13 18:48:00 +01:00
2b69938ad5 corrected date variables 2023-01-09 20:13:17 +01:00
c42f65bd3a corrected date variables 2023-01-05 20:39:29 +01:00
ad0d9962b5 trim()s inserted 2023-01-01 23:51:51 +01:00
58f24953f3 startByService() 2023-01-01 20:13:34 +01:00
3d212456e6 tests 2022-12-24 02:27:35 +01:00
fff0a28310 mms 2022-11-16 22:42:25 +01:00
48da91cb40 send mms with attachment 2022-11-13 17:49:02 +01:00
98df050f42 mms 2022-11-10 23:06:07 +01:00
93cb72ac2f cosmetics 2022-11-05 23:10:23 +01:00
713228c06e send mms with attachment 2022-10-30 15:04:09 +01:00
c868d45896 variables as triggers and actions 2022-10-09 17:14:02 +02:00
4abce042eb stop phone call action 2022-10-03 20:16:56 +02:00
62034e1b10 stop phone call action 2022-10-03 13:22:25 +02:00
135f4594be call phone 2022-10-02 23:26:27 +02:00
900aaf3c8c Merge remote-tracking branch 'origin/development' into development 2022-10-02 19:00:40 +02:00
5baa40ed59 make phone call action 2022-10-02 18:59:54 +02:00
759e8076c3 translation syntax 2022-09-30 22:37:30 +02:00
17b9f19dc2 Description text about run executable improved 2022-09-22 23:15:53 +02:00
374a5c4263 confirmation dialog for deletions 2022-09-21 23:29:54 +02:00
2fd79140cb possible fix 2022-09-05 23:53:22 +02:00
a0910e620f cosmetics 2022-09-02 19:31:00 +02:00
475c1719d7 translation 2022-08-29 23:06:08 +02:00
baa39c7a77 new version prepared 2022-08-28 02:23:39 +02:00
e11cc09da2 Bluetooth button disabled as not functional, yet 2022-08-27 02:13:46 +02:00
eff04037a1 Tethering 2022-08-27 02:07:47 +02:00
b73a45f4cd tethering type 2022-08-27 00:09:20 +02:00
fad6050c7a tethering type 2022-08-23 22:43:44 +02:00
8a00529991 french translation 2022-08-23 16:44:15 +02:00
1d7cf00b94 tethering type 2022-08-18 23:32:57 +02:00
d74e2eae68 tethering type 2022-08-17 23:36:30 +02:00
4f7c36c4f7 compile fix 2022-08-17 23:04:35 +02:00
b0df3efa27 Merge branch 'tmp' into development 2022-08-17 22:42:12 +02:00
f99418fda3 started to adapt tethering trigger to check a specific type 2022-08-17 22:32:14 +02:00
e05a42f5d6 multidex 2022-08-06 02:13:39 +02:00
83a27dcfdb started to adapt tethering trigger to check a specific type 2022-07-27 23:00:34 +02:00
bdc89a855b translations and libraries updated 2022-07-27 22:11:35 +02:00
7ce203a679 translations and libraries updated 2022-07-27 22:10:07 +02:00
57bc666453 translations 2022-07-25 23:29:02 +02:00
c966981eae translations 2022-07-25 20:31:35 +02:00
7a05b9a95b device is starting-trigger enhanced 2022-07-24 22:50:11 +02:00
7fdbf74906 service is starting can be inverted 2022-07-24 19:53:45 +02:00
d17e8b70fe notification dismiss with button 2022-07-24 14:22:17 +02:00
f97bfbb732 close notification with button 2022-07-21 23:05:51 +02:00
937c6ffe1d Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/res/values/strings.xml
2022-07-19 17:58:41 +02:00
1ecc61452f notification dismiss with button 2022-07-19 17:57:47 +02:00
19fd2d098b wifi trigger needs location permission 2022-07-17 23:40:17 +02:00
d07c1a05e4 set wifi with root fix 2022-07-15 22:37:55 +02:00
f9f9b30116 su changes 2022-07-14 22:55:54 +02:00
d154a3d64f wifi trigger - enabled regex 2022-07-12 17:03:32 +02:00
eeb4f4a39e battery level trigger fixed 2022-07-11 22:56:43 +02:00
53e62068a5 close notification with button 2022-07-09 14:22:33 +02:00
922807d903 meta data changed 2022-07-07 20:40:29 +02:00
a7d294c115 translations 2022-07-04 23:02:46 +02:00
2d2fd901a1 translations 2022-07-04 22:57:07 +02:00
536a5e22f9 wakelock action 2022-07-02 12:46:34 +02:00
99faa2f7ef wakelock action 2022-07-02 01:38:39 +02:00
f3fac2f4e8 wakelock 2022-07-01 20:24:58 +02:00
b3b713e454 email tetx 2022-06-30 23:01:26 +02:00
b0d509aafe Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values/strings.xml
2022-06-27 23:04:33 +02:00
efb4919a1e regex where comparisons are made 2022-06-27 23:02:53 +02:00
7bc858fee3 number format fix attempt 2022-06-27 22:42:55 +02:00
647d5bd511 fix attempt number format 2022-06-27 20:07:06 +02:00
f1f3be56cb new version prep 2022-06-25 02:36:33 +02:00
5856c93fc8 Merge branch 'development' into development-stable
# Conflicts:
#	app/src/main/res/values-it/strings.xml
2022-06-25 02:07:14 +02:00
8201b1d4e4 new version prep 2022-06-25 01:44:24 +02:00
ce9480d188 bug manage startOtherActivity 2022-06-13 23:15:25 +02:00
a69bbb1e05 translations 2022-06-13 19:59:14 +02:00
16817e6f53 function cleanup 2022-06-11 14:00:03 +02:00
26ed906521 function cleanup 2022-06-11 13:59:15 +02:00
d1ca9ab56b removed function 2022-06-11 13:55:02 +02:00
9c76340f24 bluetooth not present notice 2022-06-11 13:25:13 +02:00
aca5572f40 translation updates 2022-06-11 13:09:37 +02:00
944e165dd0 Merge remote-tracking branch 'origin/development' into development 2022-06-11 01:27:48 +02:00
7f2fc4b5de russia translation and bugfix in tethering trigger management 2022-06-11 01:27:34 +02:00
cd163afc47 Merge pull request 'Italian translation' (#1) from bagnacauda/Automation:italian into development
Reviewed-on: #1
2022-06-11 01:24:51 +02:00
6179f0e9ae translated new strings 2022-06-10 17:27:17 +02:00
581cdafb87 improved Italian translation 2022-06-10 17:00:59 +02:00
9162bcb451 Merge remote-tracking branch 'origin/development' into development-stable 2022-06-07 17:21:07 +02:00
5272b56032 send broadcast with intents 2022-06-07 17:18:35 +02:00
2361c758c9 store descriptions 2022-06-06 20:06:11 +02:00
f738e02b72 store descriptions 2022-06-06 02:47:51 +02:00
f5a3636222 intent pairs for sendBroadcast 2022-06-04 14:32:20 +02:00
bb1b3b0149 tethering detection 2022-06-04 02:44:26 +02:00
b35208b7aa tethering detection 2022-06-03 19:26:34 +02:00
b3ad72cc50 wifi receiver efficiency 2022-06-02 17:55:02 +02:00
92e58149a7 run executable action 2022-06-02 17:43:46 +02:00
c1809bd23c run executable action 2022-06-02 17:41:41 +02:00
88a3ab8241 Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/ActivityManageRule.java
2022-06-01 22:39:46 +02:00
00f296d2d1 wifi action 2022-06-01 22:36:30 +02:00
e84842361c Merge remote-tracking branch 'origin/development-stable' into development 2022-05-29 22:30:16 +02:00
efaf0ed270 wifi toggle dialog reduced 2022-05-29 22:29:58 +02:00
7167f0c03d run executable 2022-05-29 20:14:50 +02:00
a9673e65b9 crash when editing notification trigger 2022-05-29 15:13:30 +02:00
592abe5b0d not contains comparator 2022-05-29 14:17:11 +02:00
dd7c3cb1d6 not contains comparator 2022-05-29 14:15:47 +02:00
38665ccd92 Merge remote-tracking branch 'origin/development-stable' into development 2022-05-29 14:04:44 +02:00
c60347b990 syntax errors in translations fixed 2022-05-29 14:04:32 +02:00
1e7ccf5200 not equals direction 2022-05-29 13:57:47 +02:00
9b84b8dad7 translations 2022-05-29 13:38:57 +02:00
a19c84ea51 send broadcasts action 2022-05-29 02:42:12 +02:00
3a14a56fd0 translations 2022-05-28 19:54:29 +02:00
2dfc538343 screenstate no sec lock screen fixed 2022-05-27 20:21:13 +02:00
67a58077cc time class changed 2022-05-26 18:47:30 +02:00
df68f7ca5c delayed lock screen 2022-05-26 18:26:49 +02:00
ad18313284 delayed lock screen 2022-05-26 15:50:39 +02:00
29a93e0e43 language updates and screen locked trigger 2022-05-24 17:40:11 +02:00
a5d54c18d8 language updates and screen locked trigger 2022-05-24 17:31:25 +02:00
62f5ad0005 operator change 2022-05-23 22:59:00 +02:00
4eb7133d9d operator change 2022-05-23 22:45:54 +02:00
343cbba8f8 broadcast trigger 2022-05-23 20:28:56 +02:00
51caae0794 operator change 2022-05-22 23:07:05 +02:00
e39a2411ba broadcast trigger 2022-05-22 17:31:55 +02:00
98b49036a7 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
2022-05-21 14:08:19 +02:00
a7c4cc0965 app picker removed from play store version 2022-05-21 14:06:09 +02:00
5d67452486 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
2022-05-21 13:37:50 +02:00
7e12a0f3e5 full day time window 2022-05-21 13:34:44 +02:00
5786c1bfd4 full day time window 2022-05-21 02:33:56 +02:00
cf500c740e new release prep 2022-05-15 01:54:56 +02:00
41efa7c11b Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
#	build.gradle
#	fastlane/metadata/android/en-US/changelogs/119.txt
2022-05-15 01:54:32 +02:00
7046cccabe new release prep 2022-05-15 01:37:18 +02:00
bdbed3dbef app info text updated 2022-05-10 12:42:14 +02:00
3f36c4c6b3 bug when picking app to start 2022-05-09 20:09:11 +02:00
52a10fe626 bug when importing config while service is not running 2022-05-08 20:04:45 +02:00
9fce7d987e bug when importing config while service is not running 2022-05-08 14:50:40 +02:00
d5ce04f80b wifi trigger, memorize most recent ssid 2022-05-07 02:06:17 +02:00
62c97832a9 fix in DateTimeTrigger management and executions when service already stopped 2022-04-04 20:21:34 +02:00
391edc59bf fix in DateTimeTrigger management and executions when service already stopped 2022-04-03 20:25:10 +02:00
0d3a13e753 fix in DateTimeTrigger management and executions when service already stopped 2022-04-03 16:20:20 +02:00
152b0c3c49 fix in DateTimeTrigger management and executions when service already stopped 2022-04-03 14:46:28 +02:00
7ed04c7ae2 cosmetics 2022-03-29 17:56:04 +02:00
c688a4c460 TimeFrame repetition fix 2022-03-26 20:00:50 +01:00
5a09962cc9 TimeFrame repetition fix 2022-03-26 20:00:19 +01:00
965bf55811 Merge remote-tracking branch 'origin/development-stable' into development 2022-03-05 20:59:33 +01:00
13fd4c2aae magnetometer 2022-03-05 02:00:16 +01:00
195a60cfe0 magnetometer 2022-03-03 17:32:06 +01:00
76563eb89b Merge remote-tracking branch 'origin/development-stable' into development 2022-02-28 13:46:42 +01:00
7733d57435 gradle 2022-02-26 13:02:07 +01:00
481e4d1896 screen state string 2022-02-23 18:09:21 +01:00
5af59e1754 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Trigger.java
2022-02-22 22:21:39 +01:00
619f348a28 Merge remote-tracking branch 'origin/development-stable' into development 2022-02-20 18:57:38 +01:00
9bf353ea3a logging 2022-02-12 20:04:19 +01:00
af90b566c8 new triggers: service or device starts 2022-02-07 20:09:45 +01:00
0e51c577d5 new triggers: service or device starts 2022-02-06 20:12:11 +01:00
209 changed files with 9519 additions and 1546 deletions

2
.gitignore vendored
View File

@ -145,7 +145,7 @@ fabric.properties
# End of https://www.toptal.com/developers/gitignore/api/androidstudio
output-metadata.json
/app/app-release.apk
Automation_settings.xml
/app/googlePlayFlavor/

View File

@ -11,8 +11,8 @@ android {
compileSdkVersion 31
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 118
versionName "1.7.4"
versionCode 129
versionName "1.7.13"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -28,7 +28,6 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions "version"
productFlavors
@ -37,7 +36,7 @@ android {
{
dimension "version"
versionNameSuffix "-googlePlay"
targetSdkVersion 30
targetSdkVersion 31
}
fdroidFlavor
@ -57,6 +56,7 @@ android {
abortOnError false
checkReleaseBuilds false
}
namespace 'com.jens.automation2'
}
dependencies {
@ -72,9 +72,9 @@ dependencies {
//implementation "androidx.security:security-crypto:1.0.0"
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.3.0'
testImplementation 'junit:junit:4.+'
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.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

View File

@ -1,20 +0,0 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.jens.automation2",
"variantName": "googlePlayFlavorRelease",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 118,
"versionName": "1.7.4-googlePlay",
"outputFile": "app-googlePlayFlavor-release.apk"
}
],
"elementType": "File"
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -67,6 +66,10 @@
<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-feature
android:name="android.hardware.telephony"
@ -159,12 +162,24 @@
<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=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -12,6 +12,7 @@ import android.widget.Toast;
import com.google.android.gms.location.DetectedActivity;
import com.jens.automation2.receivers.ActivityDetectionReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
@ -21,23 +22,23 @@ import java.util.List;
public class Rule implements Comparable<Rule>
{
private static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
protected static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
private static List<Rule> ruleRunHistory = new ArrayList<Rule>();
protected static List<Rule> ruleRunHistory = new ArrayList<Rule>();
public static List<Rule> getRuleRunHistory()
{
return ruleRunHistory;
}
private ArrayList<Trigger> triggerSet;
private ArrayList<Action> actionSet;
private String name;
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
private Calendar lastExecution;
private static Date lastActivatedRuleActivationTime;
protected ArrayList<Trigger> triggerSet;
protected ArrayList<Action> actionSet;
protected String name;
protected boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
protected boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
protected Calendar lastExecution;
protected static Date lastActivatedRuleActivationTime;
public Calendar getLastExecution()
{
@ -106,7 +107,7 @@ public class Rule implements Comparable<Rule>
}
public void setName(String name)
{
this.name = name;
this.name = name.trim();
}
public static void readFromFile()
@ -185,6 +186,7 @@ public class Rule implements Comparable<Rule>
if(this.checkBeforeSaving(context, true))
{
Miscellaneous.logEvent("i", "Rule", "Changing rule: " + this.toString(), 3);
boolean returnValue = XmlFileInterface.writeFile();
if(returnValue)
@ -233,20 +235,24 @@ public class Rule implements Comparable<Rule>
}
if(!changeExistingRule)
for(Rule rule : Rule.ruleCollection)
if(rule.getName().equals(this.getName()))
{
for (Rule rule : Rule.ruleCollection)
{
if (rule.getName().equals(this.getName()))
{
Toast.makeText(context, context.getResources().getString(R.string.anotherRuleByThatName), Toast.LENGTH_LONG).show();
return false;
}
if(this.getTriggerSet().size()==0)
}
}
if(this.getTriggerSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyTrigger), Toast.LENGTH_LONG).show();
return false;
}
if(this.getActionSet().size()==0)
if(this.getActionSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyAction), Toast.LENGTH_LONG).show();
return false;
@ -334,6 +340,28 @@ public class Rule implements Comparable<Rule>
{
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
return true;
/*
Workaround for repetition in TimeFrame triggers
*/
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
{
if(oneTrigger.getTimeFrame().repetition > 0)
{
if(this.getLastExecution() != null)
{
Calendar now = Calendar.getInstance();
if (this.getLastExecution().getTimeInMillis() + oneTrigger.getTimeFrame().getRepetition() * 1000 <= now.getTimeInMillis())
return true;
}
else
return true;
}
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -372,11 +400,12 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}
@ -447,7 +476,9 @@ public class Rule implements Comparable<Rule>
{
AutomationService service = AutomationService.getInstance();
service.speak(messages[0], false);
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
if(Settings.showToasts)
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
super.onProgressUpdate(messages);
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -65,6 +64,10 @@
<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-feature
android:name="android.hardware.telephony"
@ -157,12 +160,23 @@
<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=".ActivityManageMakePhoneCall" />
<activity android:name=".ActivityManageActionSetVariable" />
<activity android:name=".ActivityManageTriggerCheckVariable" />
<activity android:name=".ActivityManageActionCopyToClipboard" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -10,6 +10,7 @@ import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@ -18,23 +19,23 @@ import java.util.List;
public class Rule implements Comparable<Rule>
{
private static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
protected static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
private static List<Rule> ruleRunHistory = new ArrayList<Rule>();
protected static List<Rule> ruleRunHistory = new ArrayList<Rule>();
public static List<Rule> getRuleRunHistory()
{
return ruleRunHistory;
}
private ArrayList<Trigger> triggerSet;
private ArrayList<Action> actionSet;
private String name;
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
private Calendar lastExecution;
private static Date lastActivatedRuleActivationTime;
protected ArrayList<Trigger> triggerSet;
protected ArrayList<Action> actionSet;
protected String name;
protected boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
protected boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
protected Calendar lastExecution;
protected static Date lastActivatedRuleActivationTime;
public Calendar getLastExecution()
{
@ -103,7 +104,7 @@ public class Rule implements Comparable<Rule>
}
public void setName(String name)
{
this.name = name;
this.name = name.trim();
}
public static void readFromFile()
@ -182,6 +183,7 @@ public class Rule implements Comparable<Rule>
if(this.checkBeforeSaving(context, true))
{
Miscellaneous.logEvent("i", "Rule", "Changing rule: " + this.toString(), 3);
boolean returnValue = XmlFileInterface.writeFile();
if(returnValue)
@ -230,20 +232,24 @@ public class Rule implements Comparable<Rule>
}
if(!changeExistingRule)
for(Rule rule : Rule.ruleCollection)
if(rule.getName().equals(this.getName()))
{
for (Rule rule : Rule.ruleCollection)
{
if (rule.getName().equals(this.getName()))
{
Toast.makeText(context, context.getResources().getString(R.string.anotherRuleByThatName), Toast.LENGTH_LONG).show();
return false;
}
if(this.getTriggerSet().size()==0)
}
}
if(this.getTriggerSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyTrigger), Toast.LENGTH_LONG).show();
return false;
}
if(this.getActionSet().size()==0)
if(this.getActionSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyAction), Toast.LENGTH_LONG).show();
return false;
@ -331,6 +337,19 @@ public class Rule implements Comparable<Rule>
{
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
return true;
/*
Workaround for repetition in TimeFrame triggers
*/
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
{
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -369,11 +388,12 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}
@ -420,7 +440,9 @@ public class Rule implements Comparable<Rule>
{
AutomationService service = AutomationService.getInstance();
service.speak(messages[0], false);
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
if(Settings.showToasts)
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
super.onProgressUpdate(messages);
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -65,7 +64,8 @@
<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.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<application
android:allowBackup="true"
@ -113,6 +113,7 @@
</intent-filter>
</receiver>
<receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
@ -124,6 +125,7 @@
<receiver
android:name=".DeviceAdmin"
android:exported="true"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
@ -145,14 +147,25 @@
<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=".ActivityMainTabLayout"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -201,6 +214,7 @@
<service
android:name=".receivers.NotificationListener"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>

View File

@ -12,6 +12,7 @@ import android.widget.Toast;
import com.google.android.gms.location.DetectedActivity;
import com.jens.automation2.receivers.ActivityDetectionReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
@ -21,23 +22,23 @@ import java.util.List;
public class Rule implements Comparable<Rule>
{
private static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
protected static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
private static List<Rule> ruleRunHistory = new ArrayList<Rule>();
protected static List<Rule> ruleRunHistory = new ArrayList<Rule>();
public static List<Rule> getRuleRunHistory()
{
return ruleRunHistory;
}
private ArrayList<Trigger> triggerSet;
private ArrayList<Action> actionSet;
private String name;
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
private Calendar lastExecution;
private static Date lastActivatedRuleActivationTime;
protected ArrayList<Trigger> triggerSet;
protected ArrayList<Action> actionSet;
protected String name;
protected boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
protected boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
protected Calendar lastExecution;
protected static Date lastActivatedRuleActivationTime;
public Calendar getLastExecution()
{
@ -106,7 +107,7 @@ public class Rule implements Comparable<Rule>
}
public void setName(String name)
{
this.name = name;
this.name = name.trim();
}
public static void readFromFile()
@ -185,6 +186,7 @@ public class Rule implements Comparable<Rule>
if(this.checkBeforeSaving(context, true))
{
Miscellaneous.logEvent("i", "Rule", "Changing rule: " + this.toString(), 3);
boolean returnValue = XmlFileInterface.writeFile();
if(returnValue)
@ -233,20 +235,24 @@ public class Rule implements Comparable<Rule>
}
if(!changeExistingRule)
for(Rule rule : Rule.ruleCollection)
if(rule.getName().equals(this.getName()))
{
for (Rule rule : Rule.ruleCollection)
{
if (rule.getName().equals(this.getName()))
{
Toast.makeText(context, context.getResources().getString(R.string.anotherRuleByThatName), Toast.LENGTH_LONG).show();
return false;
}
if(this.getTriggerSet().size()==0)
}
}
if(this.getTriggerSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyTrigger), Toast.LENGTH_LONG).show();
return false;
}
if(this.getActionSet().size()==0)
if(this.getActionSet().size() == 0)
{
Toast.makeText(context, context.getResources().getString(R.string.pleaseSpecifiyAction), Toast.LENGTH_LONG).show();
return false;
@ -334,6 +340,19 @@ public class Rule implements Comparable<Rule>
{
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
return true;
/*
Workaround for repetition in TimeFrame triggers
*/
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
{
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -372,11 +391,12 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}
@ -447,7 +467,9 @@ public class Rule implements Comparable<Rule>
{
AutomationService service = AutomationService.getInstance();
service.speak(messages[0], false);
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
if(Settings.showToasts)
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
super.onProgressUpdate(messages);
}

View File

@ -1,6 +1,4 @@
<?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>

View File

@ -21,108 +21,130 @@ public class Action
public static final String intentPairSeparator = "intPairSplit";
public static final String vibrateSeparator = ",";
public enum Action_Enum {
setWifi,
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl,
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
playMusic,
controlMediaPlayback,
setScreenBrightness,
playSound,
vibrate,
createNotification,
closeNotification,
sendTextMessage;
public String getFullName(Context context)
{
switch(this)
{
case setWifi:
return context.getResources().getString(R.string.actionSetWifi);
case setBluetooth:
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation);
case turnWifiOn:
return context.getResources().getString(R.string.actionTurnWifiOn);
case turnWifiOff:
return context.getResources().getString(R.string.actionTurnWifiOff);
case turnBluetoothOn:
return context.getResources().getString(R.string.actionTurnBluetoothOn);
case turnBluetoothOff:
return context.getResources().getString(R.string.actionTurnBluetoothOff);
case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile:
return context.getResources().getString(R.string.actionChangeSoundProfile);
case turnUsbTetheringOn:
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
case turnWifiTetheringOn:
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
case turnWifiTetheringOff:
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
case enableScreenRotation:
return context.getResources().getString(R.string.actionEnableScreenRotation);
case disableScreenRotation:
return context.getResources().getString(R.string.actionDisableScreenRotation);
case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
return context.getResources().getString(R.string.airplaneMode);
case setDataConnection:
return context.getResources().getString(R.string.actionDataConnection);
case speakText:
return context.getResources().getString(R.string.actionSpeakText);
case playMusic:
return context.getResources().getString(R.string.actionPlayMusic);
case controlMediaPlayback:
return context.getResources().getString(R.string.actionMediaControl);
case playSound:
return context.getResources().getString(R.string.playSound);
case sendTextMessage:
return context.getResources().getString(R.string.sendTextMessage);
case setScreenBrightness:
return context.getResources().getString(R.string.setScreenBrightness);
case createNotification:
return context.getResources().getString(R.string.createNotification);
case closeNotification:
return context.getResources().getString(R.string.closeNotifications);
default:
return "Unknown";
}
}
};
public enum Action_Enum
{
setWifi,
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl,
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
playMusic,
controlMediaPlayback,
setScreenBrightness,
playSound,
vibrate,
createNotification,
closeNotification,
sendBroadcast,
runExecutable,
wakelock,
setVariable,
startPhoneCall,
stopPhoneCall,
copyToClipboard,
sendTextMessage;
public String getFullName(Context context)
{
switch(this)
{
case setWifi:
return context.getResources().getString(R.string.actionSetWifi);
case setBluetooth:
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation);
case turnWifiOn:
return context.getResources().getString(R.string.actionTurnWifiOn);
case turnWifiOff:
return context.getResources().getString(R.string.actionTurnWifiOff);
case turnBluetoothOn:
return context.getResources().getString(R.string.actionTurnBluetoothOn);
case turnBluetoothOff:
return context.getResources().getString(R.string.actionTurnBluetoothOff);
case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile:
return context.getResources().getString(R.string.actionChangeSoundProfile);
case turnUsbTetheringOn:
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
case turnWifiTetheringOn:
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
case turnWifiTetheringOff:
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
case enableScreenRotation:
return context.getResources().getString(R.string.actionEnableScreenRotation);
case disableScreenRotation:
return context.getResources().getString(R.string.actionDisableScreenRotation);
case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
return context.getResources().getString(R.string.airplaneMode);
case setDataConnection:
return context.getResources().getString(R.string.actionDataConnection);
case speakText:
return context.getResources().getString(R.string.actionSpeakText);
case playMusic:
return context.getResources().getString(R.string.actionPlayMusic);
case controlMediaPlayback:
return context.getResources().getString(R.string.actionMediaControl);
case playSound:
return context.getResources().getString(R.string.playSound);
case sendTextMessage:
return context.getResources().getString(R.string.sendTextMessage);
case setScreenBrightness:
return context.getResources().getString(R.string.setScreenBrightness);
case createNotification:
return context.getResources().getString(R.string.createNotification);
case closeNotification:
return context.getResources().getString(R.string.closeNotifications);
case sendBroadcast:
return context.getResources().getString(R.string.sendBroadcast);
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);
default:
return "Unknown";
}
}
};
private Action_Enum action;
private boolean parameter1 = false;
@ -258,6 +280,33 @@ public class Action
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));
default:
returnString.append(action.toString());
}
@ -316,8 +365,24 @@ public class Action
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.controlMediaPlayback))
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(": ");
@ -345,6 +410,12 @@ public class Action
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))
; // it's completed further above already
else if (parameter2 != null && parameter2.length() > 0)
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
}
@ -430,7 +501,7 @@ public class Action
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
}
public void run(Context context, boolean toggleActionIfPossible)
{
try
@ -458,7 +529,7 @@ public class Action
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setWifi:
Actions.WifiStuff.setWifi(context, getParameter1(), toggleActionIfPossible);
Actions.WifiStuff.setWifi(context, getParameter1(), getParameter2(), toggleActionIfPossible);
break;
case setWifiTethering:
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
@ -533,6 +604,34 @@ public class Action
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;
default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break;
@ -636,7 +735,7 @@ public class Action
//Do something with result
//Toast.makeText(context, text, duration) result;
Miscellaneous.logEvent("i", "HTTP RESULT", result, 3);
Actions myAction=new Actions();
Actions myAction = new Actions();
myAction.useDownloadedWebpage(result);
}
}

View File

@ -10,13 +10,12 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
@ -26,8 +25,8 @@ import android.os.PowerManager.WakeLock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.telecom.TelecomManager;
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@ -52,7 +51,12 @@ import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@ -62,8 +66,12 @@ import java.net.NetworkInterface;
import java.security.KeyStore;
import java.util.Calendar;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
@ -74,10 +82,6 @@ public class Actions
public static AutomationService automationServerRef;
public static Context context;
private static Intent playMusicIntent;
private static boolean suAvailable = false;
private static String suVersion = null;
private static String suVersionInternal = null;
private static List<String> suResult = null;
public final static String smsSeparator = "&sms&";
public final static String dummyPackageString = "dummyPkg239asd";
@ -119,11 +123,14 @@ public class Actions
String myTitleDir = params[1];
String requiredTitle = params[2];
String myTextDir = params[3];
String requiredText;
if (params.length >= 5)
String requiredText = "";
String method = ActivityManageActionCloseNotification.dismissRegularString;
if(params.length >= 5)
requiredText = params[4];
else
requiredText = "";
if(params.length >= 6 && !params[5].equals(ActivityManageActionCloseNotification.dismissRegularString))
method = params[5];
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
{
@ -177,7 +184,12 @@ public class Actions
Miscellaneous.logEvent("i", "NotificationCloseCheck", "All criteria matches. Closing notification: " + sbn.getNotification().toString(), 3);
if(NotificationListener.getInstance() != null)
NotificationListener.getInstance().dismissNotification(sbn);
{
if(method == ActivityManageActionCloseNotification.dismissRegularString)
NotificationListener.getInstance().dismissNotification(sbn);
else
NotificationListener.getInstance().clickNotificationButton(sbn, method);
}
else
Miscellaneous.logEvent("i", "NotificationCloseCheck", "NotificationListener instance is null. Can\'t close notification.", 3);
}
@ -185,11 +197,69 @@ public class Actions
}
}
public static void sendBroadcast(Context context, String action)
{
Miscellaneous.logEvent("i", "sendBroadcast", "Sending broadcast with action " + action, 5);
Intent broadcastIntent = new Intent();
if(action.contains(Action.actionParameter2Split))
{
String[] parts = action.split(Action.actionParameter2Split);
broadcastIntent.setAction(parts[0]);
String[] intentparts = parts[1].split(";");
broadcastIntent = packParametersIntoIntent(broadcastIntent, intentparts, 0);
}
else
broadcastIntent.setAction(action);
context.sendBroadcast(broadcastIntent);
}
public static void setVariable(String parameter2)
{
String[] parts = parameter2.split(Action.actionParameter2Split);
if(AutomationService.isMyServiceRunning(Miscellaneous.getAnyContext()))
{
Map<String,String> map = AutomationService.getInstance().getVariableMap();
if(parts.length > 1)
map.put(parts[0], parts[1]);
else
map.remove(parts[0]);
}
Miscellaneous.logEvent("i", "Variable", "Checking for applicable rules after variable has been set or deleted.", 2);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.checkVariable);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
{
Miscellaneous.logEvent("i", "Variable", "Rule " + ruleCandidates.get(i).getName() + " applies after variable has been set or deleted.", 2);
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
Miscellaneous.logEvent("i", "Variable", "Done checking for applicable rules after variable has been set or deleted.", 2);
}
public static class WifiStuff
{
public static Boolean setWifi(Context context, Boolean desiredState, boolean toggleActionIfPossible)
public static Boolean setWifi(Context context, Boolean desiredState, String parameter2, boolean toggleActionIfPossible)
{
if(context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
boolean forceUseRoot = false;
try
{
forceUseRoot = Boolean.parseBoolean(parameter2);
}
catch(Exception e)
{
}
if(context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q || forceUseRoot)
return setWifiWithRoot(context, desiredState, toggleActionIfPossible);
else
return setWifiOldFashioned(context, desiredState, toggleActionIfPossible);
@ -225,8 +295,15 @@ public class Actions
{
Miscellaneous.logEvent("i", "Wifi", "Changing wifi to " + String.valueOf(desiredState), 4);
if (desiredState && Settings.useWifiForPositioning)
WifiBroadcastReceiver.startWifiReceiver(automationServerRef.getLocationProvider());
try
{
if (desiredState && Settings.useWifiForPositioning)
WifiBroadcastReceiver.startWifiReceiver(automationServerRef.getLocationProvider());
}
catch(Exception e)
{
Miscellaneous.logEvent("w", "setWifiOldFashioned()", Log.getStackTraceString(e), 4);
}
WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@ -754,29 +831,21 @@ public class Actions
return false;
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static void setDoNotDisturb(Context context, int desiredSetting)
public static void setDoNotDisturb(Context context, int desiredDndMode)
{
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Check if the notification policy access has been granted for the app.
/* if (!notificationManager.isNotificationPolicyAccessGranted())
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
return;
}*/
/*
if (!notificationManager.isNotificationPolicyAccessGranted())
--> done externally
*/
notificationManager.setInterruptionFilter(desiredSetting);
/*if (notificationManager.getCurrentInterruptionFilter() == NotificationManager.INTERRUPTION_FILTER_ALL)
{
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing DND to " + String.valueOf(desiredDndMode), 4);
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.setInterruptionFilter(desiredDndMode);
}
else
{
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
}*/
Miscellaneous.logEvent("w", context.getResources().getString(R.string.soundSettings), "Cannot change DND to " + String.valueOf(desiredDndMode) + ". This Android version is too and doesn\'t have that feature, yet.", 4);
}
@RequiresApi(api = Build.VERSION_CODES.M)
@ -913,18 +982,6 @@ public class Actions
}
}
public static void setDND(Context context, int desiredDndMode)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing DND to " + String.valueOf(desiredDndMode), 4);
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.setInterruptionFilter(desiredDndMode);
}
else
Miscellaneous.logEvent("w", context.getResources().getString(R.string.soundSettings), "Cannot change DND to " + String.valueOf(desiredDndMode) + ". This Android version is too and doesn\'t have that feature, yet.", 4);
}
public void useDownloadedWebpage(String result)
{
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
@ -992,8 +1049,6 @@ public class Actions
{
Intent externalActivityIntent;
int paramsStartIndex;
if (!startByAction)
{
// selected by activity
@ -1005,8 +1060,6 @@ public class Actions
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by activity: " + packageName + " " + className, 3);
paramsStartIndex = 2;
externalActivityIntent = new Intent(Intent.ACTION_MAIN);
externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
@ -1034,9 +1087,27 @@ public class Actions
externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Pack intents
for (int i = 3; i < params.length; i++)
{
String[] singleParam = params[i].split(Action.intentPairSeparator);
externalActivityIntent = packParametersIntoIntent(externalActivityIntent, params, 3);
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
automationServerRef.startActivity(externalActivityIntent);
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
automationServerRef.startService(externalActivityIntent);
else
automationServerRef.sendBroadcast(externalActivityIntent);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "StartOtherApp", automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
Toast.makeText(automationServerRef, automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public static Intent packParametersIntoIntent(Intent intent, String[] params, int startIndex)
{
for (int i = startIndex; i < params.length; i++)
{
String[] singleParam = params[i].split(Action.intentPairSeparator);
/*Class c = Class.forName(singleParam[0]);
for(Method m : c.getMethods())
@ -1048,83 +1119,74 @@ public class Actions
}
}*/
if (singleParam[0].equals("boolean"))
if (singleParam[0].equals("boolean"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Boolean.parseBoolean(singleParam[2]));
}
else if (singleParam[0].equals("byte"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Byte.parseByte(singleParam[2]));
}
else if (singleParam[0].equals("char"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], singleParam[2].charAt(0));
}
else if (singleParam[0].equals("CharSequence"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], (CharSequence) singleParam[2]);
}
else if (singleParam[0].equals("double"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Double.parseDouble(singleParam[2]));
}
else if (singleParam[0].equals("float"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Float.parseFloat(singleParam[2]));
}
else if (singleParam[0].equals("int"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Integer.parseInt(singleParam[2]));
}
else if (singleParam[0].equals("long"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Long.parseLong(singleParam[2]));
}
else if (singleParam[0].equals("short"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Short.parseShort(singleParam[2]));
}
else if (singleParam[0].equals("Uri"))
{
if (singleParam[1].equalsIgnoreCase("IntentData"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Boolean.parseBoolean(singleParam[2]));
}
else if (singleParam[0].equals("byte"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Byte.parseByte(singleParam[2]));
}
else if (singleParam[0].equals("char"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], singleParam[2].charAt(0));
}
else if (singleParam[0].equals("CharSequence"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], (CharSequence) singleParam[2]);
}
else if (singleParam[0].equals("double"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Double.parseDouble(singleParam[2]));
}
else if (singleParam[0].equals("float"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Float.parseFloat(singleParam[2]));
}
else if (singleParam[0].equals("int"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Integer.parseInt(singleParam[2]));
}
else if (singleParam[0].equals("long"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Long.parseLong(singleParam[2]));
}
else if (singleParam[0].equals("short"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Short.parseShort(singleParam[2]));
}
else if (singleParam[0].equals("Uri"))
{
if (singleParam[1].equalsIgnoreCase("IntentData"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
externalActivityIntent.setData(Uri.parse(singleParam[2]));
}
else
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], Uri.parse(singleParam[2]));
}
}
else if (singleParam[0].equals("String"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
externalActivityIntent.putExtra(singleParam[1], singleParam[2]);
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
intent.setData(Uri.parse(singleParam[2]));
}
else
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Uri.parse(singleParam[2]));
}
}
else if (singleParam[0].equals("String"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], singleParam[2]);
}
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
automationServerRef.startActivity(externalActivityIntent);
else
automationServerRef.sendBroadcast(externalActivityIntent);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "StartOtherApp", automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
Toast.makeText(automationServerRef, automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
}
return intent;
}
public static void waitBeforeNextAction(Long waitTime)
@ -1163,21 +1225,37 @@ public class Actions
public static void sendTextMessage(Context context, String[] parametersArray)
{
String phoneNumber, message;
String phoneNumber, message, messageType = ActivityManageActionSendTextMessage.messageTypeSms, filePath = null;
phoneNumber = parametersArray[0];
message = parametersArray[1];
if(parametersArray.length > 2)
{
messageType = parametersArray[2];
if(parametersArray.length > 3)
filePath = parametersArray[3];
}
try
{
String textToSend = Miscellaneous.replaceVariablesInText(message, context);
if(messageType.equals("sms"))
sendSmsMessage(phoneNumber, textToSend);
else
sendMmsMessage(phoneNumber, textToSend, filePath);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", Miscellaneous.getAnyContext().getString(R.string.sendTextMessage), "Error in sendTextMessage: " + Log.getStackTraceString(e), 3);
}
}
/*
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + phoneNumber));
intent.putExtra("sms_body", message);
AutomationService.getInstance().startActivity(intent);
*/
private static void sendSmsMessage(String phoneNumber, String textToSend)
{
try
{
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, Actions.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, textToSend, pi, null);
@ -1188,6 +1266,26 @@ public class Actions
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static void sendMmsMessage(String phoneNumber, String textToSend, String fileToBeAttached)
{
try
{
Miscellaneous.logEvent("i", "sendMmsMessage()", "Sending MMS message...", 2);
// Uri contentUri = Uri.fromFile(new File(fileToBeAttached));
String str2 = "send." + String.valueOf(Math.abs(new Random().nextLong())) + ".dat";
Uri contentUri = new Uri.Builder().authority(context.getPackageName() + ".MmsFileProvider").path(str2).scheme("content").build();
// Bundle a3 = C3326a.m16196a(new C8792q("enableGroupMms", true), new C8792q("maxMessageSize", Integer.valueOf(C3664a.m17428d())));
SmsManager.getDefault().sendMultimediaMessage(context, contentUri, phoneNumber, null, null);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "sendMmsMessage()", "Error in sendMmsMessage(): " + Log.getStackTraceString(e), 3);
}
}
private static class WakeUpDeviceClass implements Runnable
{
private long awakeTime;
@ -1854,6 +1952,12 @@ public class Actions
protected static boolean executeCommandViaSu(String[] commands)
{
boolean suAvailable = false;
String suVersion = null;
String suVersionInternal = null;
// List<String> suResult = null;
int suResult;
boolean success = false;
try
@ -1863,17 +1967,30 @@ public class Actions
{
suVersion = Shell.SU.version(false);
suVersionInternal = Shell.SU.version(true);
suResult = Shell.SU.run(commands);
if (suResult != null)
Miscellaneous.logEvent("i", "executeCommandViaSu()", "suVersion: " + suVersion + ", suVersionInternal: " + suVersionInternal, 5);
// suResult = Shell.SU.run(commands);
suResult = Shell.Pool.SU.run(commands);
// if (suResult != null)
// success = true;
Miscellaneous.logEvent("i", "executeCommandViaSu()", "RC=" + String.valueOf(suResult), 3);
if(suResult == 0)
success = true;
}
else
Miscellaneous.logEvent("w", "executeCommandViaSu()", "su not available.", 4);
}
catch (Exception e)
{
success = false;
}
Miscellaneous.logEvent("i", "executeCommandViaSu()", "Returning " + String.valueOf(success), 4);
return success;
}
@ -1899,4 +2016,300 @@ public class Actions
return android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
public static boolean runExecutable(Context context, boolean runAsRoot, String path, String parameters)
{
if(runAsRoot)
{
if(!StringUtils.isEmpty(parameters))
return executeCommandViaSu(new String[] { path + " " + parameters });
else
return executeCommandViaSu(new String[] { path });
}
else
{
Object[] result;
File executable = new File(path);
File workingDir = new File(executable.getParent());
if(!StringUtils.isEmpty(parameters))
result = runExternalApplication(path, 0, workingDir, parameters);
else
result = runExternalApplication(path, 0, workingDir, null);
boolean execResult = (boolean) result[0];
return execResult;
}
}
/**
*
* @param commandToExecute
* @param timeout
* @param params
* @return Returns an array: 0=exit code, 1=cmdline output
*/
public static Object[] runExternalApplication(String commandToExecute, long timeout, File workingDirectory, String params)
{
/*
* Classes stolen from https://github.com/stleary/JSON-java
*/
String fullCommand;
if(!StringUtils.isEmpty(params))
fullCommand = commandToExecute + " " + params;
else
fullCommand = commandToExecute;
Miscellaneous.logEvent("i", "Running executable", "Running external application " + fullCommand, 4);
Object[] returnObject = new Object[2];
StringBuilder output = new StringBuilder();
String line = null;
OutputStream stdin = null;
InputStream stderr = null;
InputStream stdout = null;
try
{
Process process = null;
if(workingDirectory != null)
process = Runtime.getRuntime().exec(fullCommand, null, workingDirectory);
else
process = Runtime.getRuntime().exec(fullCommand);
stdin = process.getOutputStream ();
stderr = process.getErrorStream ();
stdout = process.getInputStream ();
// "write" the parms into stdin
/*line = "param1" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param2" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param3" + "\n";
stdin.write(line.getBytes() );
stdin.flush();*/
stdin.close();
// clean up if any output in stdout
BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stdout] " + line, 4);
output.append(line);
}
brCleanUp.close();
// clean up if any output in stderr
brCleanUp = new BufferedReader (new InputStreamReader(stderr));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stderr] " + line, 4);
output.append(line);
}
brCleanUp.close();
try
{
// Wait for the process to exit, we want the return code
if(timeout > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
try
{
if(!process.waitFor(timeout, TimeUnit.MILLISECONDS))
{
Miscellaneous.logEvent("i", "Running executable", "Timeout of " + String.valueOf(timeout) + " ms reached. Killing check attempt.", 3);
process.destroyForcibly();
}
}
catch(NoSuchMethodError e)
{
process.waitFor();
}
}
else
process.waitFor();
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("i", "Running executable", "Waiting for process failed: " + Log.getStackTraceString(e), 4);
Miscellaneous.logEvent("i", "Running executable", Log.getStackTraceString(e), 1);
}
if(process.exitValue() == 0)
Miscellaneous.logEvent("i", "Running executable", "ReturnCode: " + String.valueOf(process.exitValue()), 4);
else
Miscellaneous.logEvent("i", "Running executable", "External execution (RC=" + String.valueOf(process.exitValue()) + ") returned error: " + output.toString(), 3);
returnObject[0] = process.exitValue();
returnObject[1] = output.toString();
return returnObject;
}
catch (IOException e)
{
Miscellaneous.logEvent("e", "Running executable", Log.getStackTraceString(e), 1);
}
Miscellaneous.logEvent("i", "Running executable", "Error running external application.", 1);
// if(slotMap != null)
// for(String key : slotMap.keySet())
// System.clearProperty(key);
return null;
}
public static boolean isTetheringActive1(Context context)
{
try
{
for(Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
{
NetworkInterface intf = en.nextElement();
for(Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
{
InetAddress inetAddress = enumIpAddr.nextElement();
if(!intf.isLoopback())
{
if(intf.getName().contains("rndis"))
{
return true;
}
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "isTetheringActive()", Log.getStackTraceString(e), 3);
}
return false;
}
public final static int wakeLockTimeoutDisabled = -1;
static boolean wakeLockStopRequested = false;
public static void wakeLockStart(Context context, long duration)
{
Thread lockThread = new Thread(new Runnable()
{
@Override
public void run()
{
wakeLockStopRequested = false;
long waited = 0;
int step = 2000;
try
{
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK");
fullWakeLock.acquire(); // turn on
do
{
try
{
Thread.sleep(step); // turn on duration
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(duration > 0)
waited += step;
if(wakeLockStopRequested) //stop requested
Miscellaneous.logEvent("i", "WakeLockStart", "Stop requested.", 4);
}
while(!wakeLockStopRequested && (duration < 0 || waited <= duration));
fullWakeLock.release();
}
catch (Exception e)
{
}
}
});
lockThread.start();
}
public static void wakeLockStop()
{
Miscellaneous.logEvent("i", "WakeLockStart", "Requesting stop.", 4);
wakeLockStopRequested = true;
}
public static void startPhoneCall(Context context, String phoneNumber)
{
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
// intent.setClassName("com.android.phone","com.android.phone.OutgoingCallBroadcaster");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);
}
public static void endPhoneCall(Context context)
{
if(Build.VERSION.SDK_INT < 21)
{
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try
{
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm);
c = Class.forName(telephonyService.getClass().getName());
m = c.getDeclaredMethod("endCall");
m.setAccessible(true);
m.invoke(telephonyService);
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
TelecomManager mgr = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE);
mgr.endCall();
}
}
public static void copyToClipboard(Context context, String text)
{
Miscellaneous.logEvent("i", "Clipboard", "Copying data to clipboard: " + text, 4);
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(text);
}
else
{
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("Data-from-Automation", text);
clipboard.setPrimaryClip(clip);
}
}
}

View File

@ -222,6 +222,10 @@ public class ActivityControlCenter extends Activity
}
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();
@ -342,15 +346,22 @@ public class ActivityControlCenter extends Activity
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("Flavor: " + BuildConfig.FLAVOR + 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());
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:

View File

@ -13,7 +13,7 @@ public class ActivityHelp extends Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(layout.help_text);
setContentView(layout.activity_help_text);
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());

View File

@ -44,6 +44,7 @@ public class ActivityMainPoi extends ActivityGeneric
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(ActivityMainPoi.this);
setContentView(R.layout.main_poi_layout);
instance = this;
@ -190,8 +191,27 @@ public class ActivityMainPoi extends ActivityGeneric
startActivityForResult(manageSpecificPoiIntent, 2000);
break;
case 1:
if(pointOfInterest.delete(Miscellaneous.getAnyContext()))
updateListView();
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;
}
}

View File

@ -40,6 +40,7 @@ public class ActivityMainProfiles extends ActivityGeneric
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(ActivityMainProfiles.this);
setContentView(R.layout.main_profile_layout);
instance = this;
@ -187,10 +188,29 @@ public class ActivityMainProfiles extends ActivityGeneric
Rule user = profile.isInUseByRules();
if(user == null)
{
if (profile.delete(ActivityMainProfiles.this))
updateListView();
else
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.profileCouldNotBeDeleted), Toast.LENGTH_LONG).show();
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();

View File

@ -18,6 +18,7 @@ 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.DateTimeListener;
@ -25,6 +26,7 @@ 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;
@ -45,7 +47,8 @@ public class ActivityMainRules extends ActivityGeneric
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(ActivityMainRules.this);
setContentView(R.layout.main_rule_layout);
instance = this;
@ -207,16 +210,35 @@ public class ActivityMainRules extends ActivityGeneric
Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.serviceHasToRunForThat), Toast.LENGTH_LONG).show();
break;
case 1:
ruleToEdit = ruleThisIsAbout;
Intent manageSpecificRuleIntent = new Intent (ActivityMainRules.this, ActivityManageRule.class);
manageSpecificRuleIntent.putExtra(intentNameRuleName, ruleThisIsAbout.getName());
startActivityForResult(manageSpecificRuleIntent, requestCodeChangeRule);
break;
case 2:
if(ruleThisIsAbout.delete())
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()
{
ruleToEdit = null; //clear cache
updateListView();
}
@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;
@ -251,15 +273,5 @@ public class ActivityMainRules extends ActivityGeneric
}
catch(NullPointerException e)
{}
try
{
if(AutomationService.isMyServiceRunning(this))
DateTimeListener.reloadAlarms();
}
catch(NullPointerException e)
{
// AlarmManager instance not prepared, yet.
}
}
}

View File

@ -6,9 +6,12 @@ import android.app.AlertDialog;
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.view.MotionEvent;
import android.view.View;
@ -31,6 +34,7 @@ import com.jens.automation2.location.LocationProvider;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
@SuppressLint("NewApi")
public class ActivityMainScreen extends ActivityGeneric
@ -51,6 +55,7 @@ public class ActivityMainScreen extends ActivityGeneric
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(ActivityMainScreen.this);
setContentView(R.layout.main_overview_layout);
activityMainScreenInstance = this;
@ -77,10 +82,9 @@ public class ActivityMainScreen extends ActivityGeneric
tvLockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
if(!BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
bDonate.setVisibility(View.VISIBLE);
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
@ -271,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
@ -284,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()
@ -316,8 +317,7 @@ public class ActivityMainScreen extends ActivityGeneric
uiUpdateRunning = true;
activityMainScreenInstance.toggleService.setChecked(true);
uiUpdateRunning = false;
// if(activityMainScreenInstance.hasWindowFocus())
// {
try
{
PointOfInterest activePoi = PointOfInterest.getActivePoi();

View File

@ -3,12 +3,17 @@ 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
@ -17,8 +22,8 @@ public class ActivityMainTabLayout extends TabActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
Miscellaneous.setDisplayLanguage(ActivityMainTabLayout.this);
if(Settings.tabsPlacement == 1)
setContentView(R.layout.main_tab_layout_tabs_at_bottom);

View File

@ -1,7 +1,5 @@
package com.jens.automation2;
import static com.jens.automation2.Trigger.triggerParameter2Split;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@ -18,11 +16,12 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
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;
@ -43,13 +42,15 @@ public class ActivityManageActionCloseNotification extends Activity
boolean edit = false;
ProgressDialog progressDialog = null;
EditText etNotificationTitle, etNotificationText;
EditText etNotificationTitle, etNotificationText, etNotificationDismissalButtonText;
Button bSelectApp, bSaveActionCloseNotification;
Spinner spinnerTitleDirection, spinnerTextDirection;
TextView tvSelectedApplication;
RadioButton rbNotificationDismissSimple, rbNotificationDismissButton;
private static List<PackageInfo> pInfos = null;
public static Trigger resultingTrigger;
final static String dismissRegularString = "p0815DismissString";
private static String[] directions;
@ -267,10 +268,14 @@ public class ActivityManageActionCloseNotification extends Activity
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)
@ -298,7 +303,7 @@ public class ActivityManageActionCloseNotification extends Activity
public void onClick(View v)
{
String app;
if(tvSelectedApplication.getText().toString().equalsIgnoreCase(getResources().getString(R.string.anyApp)))
if (tvSelectedApplication.getText().toString().equalsIgnoreCase(getResources().getString(R.string.anyApp)))
app = Trigger.anyAppString;
else
app = tvSelectedApplication.getText().toString();
@ -309,34 +314,44 @@ public class ActivityManageActionCloseNotification extends Activity
String text = etNotificationText.getText().toString();
Intent responseData = new Intent();
if(edit)
{
// editedNotificationAction.setTriggerParameter(chkNotificationDirection.isChecked());
responseData.putExtra(ActivityManageRule.intentNameActionParameter2, app + Action.actionParameter2Split + titleDir + Action.actionParameter2Split + title + Action.actionParameter2Split + textDir + Action.actionParameter2Split + text);
ActivityManageActionCloseNotification.this.setResult(RESULT_OK, responseData);
}
String dismissMethod;
if (rbNotificationDismissSimple.isChecked())
dismissMethod = dismissRegularString;
else
{
// data.putExtra(intentNameNotificationDirection, chkNotificationDirection.isChecked());
responseData.putExtra(ActivityManageRule.intentNameActionParameter2,
app + Action.actionParameter2Split +
titleDir + Action.actionParameter2Split +
title + Action.actionParameter2Split +
textDir + Action.actionParameter2Split +
text
);
// data.putExtra(intentNameNotificationApp, app);
// data.putExtra(intentNameNotificationTitleDir, titleDir);
// data.putExtra(intentNameNotificationTitle, title);
// data.putExtra(intentNameNotificationTextDir, textDir);
// data.putExtra(intentNameNotificationText, text);
ActivityManageActionCloseNotification.this.setResult(RESULT_OK, responseData);
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)))
{
@ -359,6 +374,24 @@ public class ActivityManageActionCloseNotification extends Activity
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);

View File

@ -0,0 +1,52 @@
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);
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);
}
}
}

View File

@ -0,0 +1,54 @@
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);
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();
}
});
}
}

View File

@ -0,0 +1,114 @@
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);
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();
}
});
}
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);
}
}
}
}

View File

@ -0,0 +1,281 @@
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);
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)
{
// TODO Auto-generated method stub
}
});
}
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;
}
}

View File

@ -9,26 +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;
// private String existingUrl = "";
protected final static int requestCodeGetMMSattachment = 3236;
public static final String messageTypeSms = "sms";
public static final String messageTypeMms = "mms";
public static boolean edit = false;
public static Action resultingAction = null;
@ -43,6 +54,10 @@ public class ActivityManageActionSendTextMessage extends Activity
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()
{
@ -51,13 +66,29 @@ public class ActivityManageActionSendTextMessage extends Activity
{
if(etSendTextMessage.getText().toString().length() > 0 && etPhoneNumber.getText().toString().length() > 0)
{
if(resultingAction == null)
if(rbMessageTypeMms.isChecked() && StringUtils.isEmpty(tvSendMmsFileAttachment.getText().toString()))
Toast.makeText(getBaseContext(), getResources().getString(R.string.chooseFile), Toast.LENGTH_LONG).show();
else
{
resultingAction = new Action();
resultingAction.setAction(Action_Enum.sendTextMessage);
resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
if (resultingAction == null)
{
resultingAction = new Action();
resultingAction.setAction(Action_Enum.sendTextMessage);
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();
}
backToRuleManager();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
@ -78,6 +109,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)
{
@ -144,10 +197,10 @@ public class ActivityManageActionSendTextMessage extends Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == requestCodeGetContact)
{
if(resultCode == Activity.RESULT_OK)
{
if(resultCode == Activity.RESULT_OK)
{
if(requestCode == requestCodeGetContact)
{
String phoneNo = null;
String name = null;
@ -165,6 +218,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);
}

View File

@ -0,0 +1,64 @@
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);
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]);
}
}
}

View File

@ -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;
@ -27,7 +25,7 @@ public class ActivityManageActionSpeakText extends Activity
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

View File

@ -53,13 +53,260 @@ public class ActivityManageActionStartActivity extends Activity
Spinner spinnerParameterType;
boolean edit = false;
ProgressDialog progressDialog = null;
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast;
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService;
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
final static String startByActivityString = "0";
final static String startByBroadcastString = "1";
final static String startByServiceString = "2";
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
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);
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);
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)
{
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() + ";" + etActivityOrActionPath.getText().toString();
else {
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
else
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
}
if (rbStartAppByActivity.isChecked())
parameter2 += ";" + startByActivityString;
else if(rbStartAppByService.isChecked())
parameter2 += ";" + startByServiceString;
else
parameter2 += ";" + startByBroadcastString;
for (String s : intentPairList)
parameter2 += ";" + 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)
{
// TODO Auto-generated method stub
}
});
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);
}
});
Intent i = getIntent();
if(i.hasExtra(ActivityManageRule.intentNameActionParameter1))
loadValuesIntoGui(i);
}
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
{
@ -82,11 +329,9 @@ 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", "Uri" };
private ArrayList<String> intentPairList = new ArrayList<String>();
@ -343,208 +588,18 @@ public class ActivityManageActionStartActivity extends Activity
getActivityListTask.execute();
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
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);
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);
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)
{
int targetSdkVersion = getApplicationContext().getApplicationInfo().targetSdkVersion;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && targetSdkVersion >= 30)
{
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;
}
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(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);
else
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
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);
}
});
Intent i = getIntent();
if(i.getBooleanExtra("edit", false) == true)
{
edit = true;
loadValuesIntoGui();
}
}
private void loadValuesIntoGui()
private void loadValuesIntoGui(Intent input)
{
boolean selectionByAction = resultingAction.getParameter1();
boolean selectionByAction = input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true);
rbStartAppSelectByActivity.setChecked(!selectionByAction);
rbStartAppSelectByAction.setChecked(selectionByAction);
String[] params = resultingAction.getParameter2().split(";");
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";");
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
rbStartAppByService.setChecked(params[2].equals(startByServiceString));
int startIndex = -1;
@ -587,8 +642,8 @@ public class ActivityManageActionStartActivity extends Activity
intentPairAdapter.notifyDataSetChanged();
}
private boolean saveAction()
boolean checkInput()
{
if(rbStartAppSelectByActivity.isChecked())
{
@ -611,36 +666,7 @@ public class ActivityManageActionStartActivity extends Activity
return false;
}
}
if(resultingAction == null)
resultingAction = new Action();
resultingAction.setParameter1(rbStartAppSelectByAction.isChecked());
resultingAction.setAction(Action_Enum.startOtherActivity);
String parameter2 = "";
if(rbStartAppSelectByActivity.isChecked())
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
else
{
if(etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
else
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
}
if(rbStartAppByActivity.isChecked())
parameter2 += ";" + startByActivityString;
else
parameter2 += ";" + startByBroadcastString;
for(String s : intentPairList)
parameter2 += ";" + s;
resultingAction.setParameter2(parameter2);
return true;
}

View File

@ -47,7 +47,7 @@ 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);
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
{
@Override

View File

@ -0,0 +1,99 @@
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);
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();
}
});
}
}

View File

@ -0,0 +1,63 @@
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);
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();
}
});
}
}

View File

@ -34,7 +34,6 @@ public class ActivityManagePoi extends Activity
public LocationManager myLocationManager;
MyLocationListenerGps myLocationListenerGps = new MyLocationListenerGps();
Location locationGps = null, locationNetwork = null;
// Location locationWifi = null;
MyLocationListenerNetwork myLocationListenerNetwork = new MyLocationListenerNetwork();
Button bGetPosition, bSavePoi;
ImageButton ibShowOnMap;

View File

@ -47,37 +47,37 @@ public class ActivityManageProfile extends Activity
boolean guiUpdate = false;
File incomingCallsRingtone = null, notificationsRingtone = null;
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;
}
@ -284,26 +284,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()
@ -324,7 +324,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);
}
@ -495,15 +495,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
@ -511,15 +516,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:

View File

@ -70,12 +70,13 @@ public class ActivityManageRule extends Activity
static int triggerBattery;
static double triggerSpeed;
static double triggerNoise;
static Rule ruleToEdit;
static boolean newRule;
static Trigger newTrigger;
static Action newAction;
Rule ruleToEdit = null;
ArrayAdapter<Trigger> triggerListViewAdapter;
ArrayAdapter<Action> actionListViewAdapter;
@ -118,7 +119,29 @@ public class ActivityManageRule extends Activity
final static int requestCodeActionCloseNotificationEdit = 806;
final static int requestCodeActionControlMediaAdd = 807;
final static int requestCodeActionControlMediaEdit = 808;
final static int requestCodeTriggerBroadcastReceivedAdd = 809;
final static int requestCodeTriggerBroadcastReceivedEdit = 810;
final static int requestCodeActionSendBroadcastAdd = 811;
final static int requestCodeActionSendBroadcastEdit = 812;
final static int requestCodeActionRunExecutableAdd = 813;
final static int requestCodeActionRunExecutableEdit = 814;
final static int requestCodeActionSetWifiAdd = 815;
final static int requestCodeActionSetWifiEdit = 816;
final static int requestCodeTriggerTetheringAdd = 817;
final static int requestCodeTriggerTetheringEdit = 818;
final static int requestCodeActionWakeLockAdd = 819;
final static int requestCodeActionWakeLockEdit = 820;
final static int requestCodeTriggerSubSystemStateAdd = 821;
final static int requestCodeTriggerSubSystemStateEdit = 822;
final static int requestCodeActionMakePhoneCallAdd = 823;
final static int requestCodeActionMakePhoneCallEdit = 824;
final static int requestCodeActionSetVariableAdd = 825;
final static int requestCodeActionSetVariableEdit = 826;
final static int requestCodeTriggerCheckVariableAdd = 827;
final static int requestCodeTriggerCheckVariableEdit = 828;
final static int requestCodeActionCopyTextToClipboardAdd = 829;
final static int requestCodeActionCopyTextToClipboardEdit = 830;
public static ActivityManageRule getInstance()
{
if(instance == null)
@ -130,10 +153,10 @@ public class ActivityManageRule extends Activity
@Override
protected void onCreate(Bundle savedInstanceState)
{
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_specific_rule);
context = this;
instance = this;
cmdTriggerAdd = (Button)findViewById(R.id.cmdTriggerAdd);
@ -147,7 +170,17 @@ public class ActivityManageRule extends Activity
imageHelpButton = (ImageView)findViewById(R.id.imageHelpButton);
//decide if it will be created anew or loaded to edit an existing one
if(ActivityMainRules.ruleToEdit == null)
if(getIntent().hasExtra(ActivityMainRules.intentNameRuleName))
{
// change existing rule
Miscellaneous.logEvent("i", "Rule", "Cache not empty, assuming change request.", 3);
newRule = false;
ruleToEdit = Rule.getByName(getIntent().getStringExtra(ActivityMainRules.intentNameRuleName));
triggerListViewAdapter = new ArrayAdapter<Trigger>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getTriggerSet());
actionListViewAdapter = new ArrayAdapter<Action>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getActionSet());
loadVariablesIntoGui();
}
else
{
// new rule
Miscellaneous.logEvent("i", "Rule", "Cache empty, assuming create request.", 3);
@ -158,16 +191,6 @@ public class ActivityManageRule extends Activity
triggerListViewAdapter = new ArrayAdapter<Trigger>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getTriggerSet());
actionListViewAdapter = new ArrayAdapter<Action>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getActionSet());
}
else
{
// change existing rule
Miscellaneous.logEvent("i", "Rule", "Cache not empty, assuming change request.", 3);
newRule = false;
ruleToEdit = ActivityMainRules.ruleToEdit;
triggerListViewAdapter = new ArrayAdapter<Trigger>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getTriggerSet());
actionListViewAdapter = new ArrayAdapter<Action>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ruleToEdit.getActionSet());
loadVariablesIntoGui();
}
cmdTriggerAdd.setOnClickListener(new OnClickListener()
{
@ -256,8 +279,9 @@ public class ActivityManageRule extends Activity
switch(selectedTrigger.getTriggerType())
{
case timeFrame:
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = selectedTrigger;
Intent timeFrameEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerTimeFrame.class);
timeFrameEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
timeFrameEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeEdit);
break;
case bluetoothConnection:
@ -296,6 +320,30 @@ public class ActivityManageRule extends Activity
devicePositionEditor.putExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName, selectedTrigger.getTriggerParameter2());
startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit);
break;
case broadcastReceived:
Intent broadcastEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerBroadcast.class);
broadcastEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
broadcastEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(broadcastEditor, requestCodeTriggerBroadcastReceivedEdit);
break;
case tethering:
Intent tetheringEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerTethering.class);
tetheringEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
tetheringEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(tetheringEditor, requestCodeTriggerTetheringEdit);
break;
case subSystemState:
Intent subSystemStateEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerSubSystemState.class);
subSystemStateEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
subSystemStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(subSystemStateEditor, requestCodeTriggerSubSystemStateEdit);
break;
case checkVariable:
Intent variableStateEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerCheckVariable.class);
variableStateEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
variableStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(variableStateEditor, requestCodeTriggerCheckVariableEdit);
break;
default:
break;
}
@ -331,8 +379,8 @@ public class ActivityManageRule extends Activity
{
case startOtherActivity:
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
ActivityManageActionStartActivity.resultingAction = a;
intent.putExtra("edit", true);
intent.putExtra(intentNameActionParameter1, a.getParameter1());
intent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(intent, requestCodeActionStartActivityEdit);
break;
case triggerUrl:
@ -365,6 +413,40 @@ public class ActivityManageRule extends Activity
activityEditVibrateIntent.putExtra("vibratePattern", a.getParameter2());
startActivityForResult(activityEditVibrateIntent, requestCodeActionVibrateEdit);
break;
case sendBroadcast:
Intent activityEditSendBroadcastIntent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
activityEditSendBroadcastIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSendBroadcastIntent, requestCodeActionSendBroadcastEdit);
break;
case wakelock:
Intent activityEditWakeLockIntent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
activityEditWakeLockIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditWakeLockIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditWakeLockIntent, requestCodeActionWakeLockEdit);
break;
case runExecutable:
Intent activityEditRunExecutableIntent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
activityEditRunExecutableIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditRunExecutableIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditRunExecutableIntent, requestCodeActionRunExecutableEdit);
break;
case startPhoneCall:
Intent activityEditMakePhoneCallIntent = new Intent(ActivityManageRule.this, ActivityManageActionMakePhoneCall.class);
activityEditMakePhoneCallIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditMakePhoneCallIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditMakePhoneCallIntent, requestCodeActionMakePhoneCallEdit);
break;
case setVariable:
Intent activityEditSetVariableIntent = new Intent(ActivityManageRule.this, ActivityManageActionSetVariable.class);
activityEditSetVariableIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSetVariableIntent, requestCodeActionSetVariableEdit);
break;
case setWifi:
Intent activityEditSetWifiIntent = new Intent(ActivityManageRule.this, ActivityManageActionWifi.class);
activityEditSetWifiIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditSetWifiIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSetWifiIntent, requestCodeActionSetWifiEdit);
break;
case controlMediaPlayback:
Intent activityEditControlMediaIntent = new Intent(ActivityManageRule.this, ActivityManageActionControlMedia.class);
activityEditControlMediaIntent.putExtra(ActivityManageRule.intentNameActionParameter2, a.getParameter2());
@ -389,6 +471,12 @@ public class ActivityManageRule extends Activity
actionPlaySoundIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit);
break;
case copyToClipboard:
Intent actionCopyToClipboardIntent = new Intent(context, ActivityManageActionCopyToClipboard.class);
actionCopyToClipboardIntent.putExtra(intentNameActionParameter1, a.getParameter1());
actionCopyToClipboardIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionCopyToClipboardIntent, requestCodeActionCopyTextToClipboardEdit);
break;
default:
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
break;
@ -506,6 +594,8 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.plane));
else if(types[i].toString().equals(Trigger_Enum.roaming.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.roaming));
else if(types[i].toString().equals(Trigger_Enum.broadcastReceived.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Trigger_Enum.phoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS"))
@ -529,6 +619,14 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
else if(types[i].toString().equals(Trigger_Enum.screenState.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else if(types[i].toString().equals(Trigger_Enum.deviceStarts.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm));
else if(types[i].toString().equals(Trigger_Enum.serviceStarts.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm));
else if(types[i].toString().equals(Trigger_Enum.tethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Trigger_Enum.subSystemState.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.subsystemstate));
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@ -593,7 +691,7 @@ public class ActivityManageRule extends Activity
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel)
else if(triggerType == Trigger_Enum.speed || triggerType == Trigger_Enum.noiseLevel || triggerType == Trigger_Enum.batteryLevel)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
@ -683,21 +781,41 @@ public class ActivityManageRule extends Activity
}
else if(triggerType == Trigger_Enum.bluetoothConnection)
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
// if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
// //Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();
// Toast.makeText(ActivityManageRule.this, getResources().getString(R.string.deviceDoesNotHaveBluetooth), Toast.LENGTH_LONG).show();
newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
ActivityManageTriggerBluetooth.editedBluetoothTrigger = newTrigger;
Intent bluetoothEditor = new Intent(myContext, ActivityManageTriggerBluetooth.class);
startActivityForResult(bluetoothEditor, requestCodeTriggerBluetoothAdd);
return;
}
else if(triggerType == Trigger_Enum.screenState)
{
newTrigger.setTriggerType(Trigger_Enum.screenState);
getTriggerScreenStateDialog().show();
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.lockedCommentScreenMustBeOff), ActivityManageRule.this).show();
return;
}
/*else if(triggerType == Trigger_Enum.deviceStarts)
{
newTrigger.setTriggerType(Trigger_Enum.deviceStarts);
ruleToEdit.getTriggerSet().add(newTrigger);
refreshTriggerList();
return;
}*/
else if(triggerType == Trigger_Enum.deviceStarts || triggerType == Trigger_Enum.serviceStarts)
{
// newTrigger.setTriggerType(Trigger_Enum.serviceStarts);
// ruleToEdit.getTriggerSet().add(newTrigger);
booleanChoices = new String[]{getResources().getString(R.string.yes), getResources().getString(R.string.no)};
// refreshTriggerList();
// return;
}
else if(triggerType == Trigger_Enum.headsetPlugged)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
@ -706,6 +824,34 @@ public class ActivityManageRule extends Activity
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show();
}
else if(triggerType == Trigger_Enum.broadcastReceived)
{
newTrigger.setTriggerType(Trigger_Enum.broadcastReceived);
Intent broadcastTriggerEditor = new Intent(myContext, ActivityManageTriggerBroadcast.class);
startActivityForResult(broadcastTriggerEditor, requestCodeTriggerBroadcastReceivedAdd);
return;
}
else if(triggerType == Trigger_Enum.tethering)
{
newTrigger.setTriggerType(Trigger_Enum.tethering);
Intent tetheringTriggerEditor = new Intent(myContext, ActivityManageTriggerTethering.class);
startActivityForResult(tetheringTriggerEditor, requestCodeTriggerTetheringAdd);
return;
}
else if(triggerType == Trigger_Enum.subSystemState)
{
newTrigger.setTriggerType(Trigger_Enum.subSystemState);
Intent subSystemStateTriggerEditor = new Intent(myContext, ActivityManageTriggerSubSystemState.class);
startActivityForResult(subSystemStateTriggerEditor, requestCodeTriggerSubSystemStateAdd);
return;
}
else if(triggerType == Trigger_Enum.checkVariable)
{
newTrigger.setTriggerType(Trigger_Enum.checkVariable);
Intent variableTriggerEditor = new Intent(myContext, ActivityManageTriggerCheckVariable.class);
startActivityForResult(variableTriggerEditor, requestCodeTriggerCheckVariableAdd);
return;
}
else
getTriggerParameterDialog(context, booleanChoices).show();
@ -797,6 +943,7 @@ public class ActivityManageRule extends Activity
return alertDialog;
}
private AlertDialog getTriggerBatteryDialog(final Context myContext, final String[] choices)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
@ -811,6 +958,7 @@ public class ActivityManageRule extends Activity
triggerBattery = (which+1);
newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
newTrigger.setBatteryLevel(triggerBattery);
newTrigger.setTriggerParameter2(String.valueOf(triggerBattery));
// Log.i("test", newTrigger.toString());
// Log.i("test", String.valueOf(newTrigger.getBatteryLevel()));
ruleToEdit.getTriggerSet().add(newTrigger);
@ -945,7 +1093,7 @@ public class ActivityManageRule extends Activity
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle(myContext.getResources().getString(R.string.phoneNumber));
alertDialog.setMessage(myContext.getResources().getString(R.string.enterPhoneNumber));
alertDialog.setMessage(myContext.getResources().getString(R.string.enterPhoneNumberBlankForAny));
// Set an EditText view to get user input
final EditText input = new EditText(this);
@ -1042,7 +1190,9 @@ public class ActivityManageRule extends Activity
String[] choices = {
Miscellaneous.getAnyContext().getResources().getString(R.string.off),
Miscellaneous.getAnyContext().getResources().getString(R.string.on),
Miscellaneous.getAnyContext().getResources().getString(R.string.unlocked)
Miscellaneous.getAnyContext().getResources().getString(R.string.unlocked),
Miscellaneous.getAnyContext().getResources().getString(R.string.lockedWithoutSecurity),
Miscellaneous.getAnyContext().getResources().getString(R.string.lockedWithSecurity)
};
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
@ -1050,6 +1200,7 @@ public class ActivityManageRule extends Activity
@Override
public void onClick(DialogInterface dialog, int which)
{
newTrigger.setTriggerParameter(true);
newTrigger.setTriggerParameter2(String.valueOf(which));
ruleToEdit.getTriggerSet().add(newTrigger);
refreshTriggerList();
@ -1232,9 +1383,15 @@ public class ActivityManageRule extends Activity
else if(requestCode == requestCodeTriggerTimeframeEdit)
{
//edit TimeFrame
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
if(resultCode == RESULT_OK && data.hasExtra(intentNameTriggerParameter2))
{
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger.setParentRule(ruleToEdit);
Trigger responseTimeFrame = new Trigger();
responseTimeFrame.setTriggerType(Trigger_Enum.timeFrame);
responseTimeFrame.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
responseTimeFrame.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
responseTimeFrame.setTimeFrame(new TimeFrame(data.getStringExtra(intentNameTriggerParameter2)));
responseTimeFrame.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, responseTimeFrame);
this.refreshTriggerList();
}
else
@ -1269,8 +1426,10 @@ public class ActivityManageRule extends Activity
// manage start of other activity
if(resultCode == RESULT_OK)
{
newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
newAction.setAction(Action_Enum.startOtherActivity);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
@ -1280,9 +1439,14 @@ public class ActivityManageRule extends Activity
// manage start of other activity
if(resultCode == RESULT_OK)
{
newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
// ruleToEdit.getActionSet().add(newAction);
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
@ -1322,8 +1486,18 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newTrigger = ActivityManageTriggerNotification.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.notification);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageTriggerNotification.intentNameNotificationDirection, false));
editedTrigger.setTriggerParameter2(
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationApp) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTitleDir) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTitle) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTextDir) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationText)
);
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
@ -1333,7 +1507,7 @@ public class ActivityManageRule extends Activity
{
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2"));
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
this.refreshTriggerList();
}
}
@ -1404,11 +1578,11 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
if(data.hasExtra("autoBrightness"))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra("autoBrightness", false));
if(data.hasExtra(ActivityManageActionBrightnessSetting.intentNameAutoBrightness))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(ActivityManageActionBrightnessSetting.intentNameAutoBrightness, false));
if(data.hasExtra("brightnessValue"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0)));
if(data.hasExtra(ActivityManageActionBrightnessSetting.intentNameBrightnessValue))
ruleToEdit.getActionSet().get(editIndex).setParameter2(String.valueOf(data.getIntExtra(ActivityManageActionBrightnessSetting.intentNameBrightnessValue, 0)));
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
@ -1425,6 +1599,59 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSendBroadcastAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionRunExecutableAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionMakePhoneCallAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetVariableAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionWakeLockAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionControlMediaAdd)
{
if(resultCode == RESULT_OK)
@ -1435,6 +1662,17 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetWifiAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
newAction.setParameter2(data.getStringExtra(ActivityManageRule.intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionCreateNotificationAdd)
{
if(resultCode == RESULT_OK)
@ -1471,6 +1709,92 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSendBroadcastEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionWakeLockEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionRunExecutableEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionMakePhoneCallEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetVariableEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetWifiEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionControlMediaEdit)
{
if(resultCode == RESULT_OK)
@ -1604,6 +1928,127 @@ public class ActivityManageRule extends Activity
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerBroadcastReceivedAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerBroadcastReceivedEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.broadcastReceived);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerTetheringAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerSubSystemStateAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerCheckVariableAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerTetheringEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.tethering);
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerSubSystemStateEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.subSystemState);
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerCheckVariableEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.checkVariable);
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeActionCopyTextToClipboardAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionCopyTextToClipboardEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
}
protected AlertDialog getActionTypeDialog()
@ -1657,12 +2102,29 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Action_Enum.closeNotification.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Action_Enum.sendBroadcast.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Action_Enum.wakelock.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.coffee));
else if(types[i].toString().equals(Action_Enum.runExecutable.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.script));
else if(types[i].toString().equals(Action_Enum.startPhoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.CALL_PHONE))
items.add(new Item(typesLong[i].toString(), R.drawable.phone));
}
else if(types[i].toString().equals(Action_Enum.stopPhoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.ANSWER_PHONE_CALLS))
items.add(new Item(typesLong[i].toString(), R.drawable.phone));
}
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
{
// if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageSpecificRule.this, "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(ActivityManageSpecificRule.this))
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
items.add(new Item(typesLong[i].toString(), R.drawable.message));
}
else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.clipboard));
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@ -1706,10 +2168,8 @@ public class ActivityManageRule extends Activity
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifi.toString()))
{
newAction.setAction(Action_Enum.setWifi);
getActionParameter1Dialog(ActivityManageRule.this).show();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
Miscellaneous.messageBox(context.getResources().getString(R.string.app_name), context.getResources().getString(R.string.android10WifiToggleNotice), context).show();
Intent editSetWifiIntent = new Intent(context, ActivityManageActionWifi.class);
startActivityForResult(editSetWifiIntent, requestCodeActionSetWifiAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetooth.toString()))
{
@ -1819,6 +2279,42 @@ public class ActivityManageRule extends Activity
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
startActivityForResult(intent, requestCodeActionVibrateAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendBroadcast.toString()))
{
newAction.setAction(Action_Enum.sendBroadcast);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
startActivityForResult(intent, requestCodeActionSendBroadcastAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.runExecutable.toString()))
{
newAction.setAction(Action_Enum.runExecutable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
startActivityForResult(intent, requestCodeActionRunExecutableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.startPhoneCall.toString()))
{
newAction.setAction(Action_Enum.startPhoneCall);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionMakePhoneCall.class);
startActivityForResult(intent, requestCodeActionMakePhoneCallAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setVariable.toString()))
{
newAction.setAction(Action_Enum.setVariable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSetVariable.class);
startActivityForResult(intent, requestCodeActionSetVariableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.stopPhoneCall.toString()))
{
newAction.setAction(Action_Enum.stopPhoneCall);
ruleToEdit.getActionSet().add(newAction);
refreshActionList();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.wakelock.toString()))
{
newAction.setAction(Action_Enum.wakelock);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
startActivityForResult(intent, requestCodeActionWakeLockAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.controlMediaPlayback.toString()))
{
newAction.setAction(Action_Enum.controlMediaPlayback);
@ -1849,6 +2345,12 @@ public class ActivityManageRule extends Activity
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.copyToClipboard.toString()))
{
newAction.setAction(Action_Enum.copyToClipboard);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd);
}
}
});

View File

@ -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;
@ -40,9 +43,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

View File

@ -0,0 +1,421 @@
package com.jens.automation2;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerBroadcast extends Activity
{
RadioButton rbBroadcastReceived, rbBroadcastNotReceived;
EditText etBroadcastTriggerAction;
Button bBroadcastShowSuggestions, bSaveTriggerBroadcast;
TextView tvBroadcastUrl;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_broadcasts);
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
bSaveTriggerBroadcast = findViewById(R.id.bSaveTriggerBroadcast);
etBroadcastTriggerAction = findViewById(R.id.etBroadcastTriggerAction);
rbBroadcastReceived = findViewById(R.id.rbBroadcastReceived);
rbBroadcastNotReceived = findViewById(R.id.rbBroadcastNotReceived);
tvBroadcastUrl = findViewById(R.id.tvBroadcastUrl);
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter1) && getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{
if(getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true))
rbBroadcastReceived.setChecked(true);
else
rbBroadcastNotReceived.setChecked(true);
etBroadcastTriggerAction.setText(getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
}
tvBroadcastUrl.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getResources().getString(R.string.broadcastListUrl)));
startActivity(browserIntent);
}
});
bBroadcastShowSuggestions.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerBroadcast.this);
builder.setTitle(getResources().getString(R.string.selectBroadcast));
builder.setItems(broadcastSuggestions, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int which)
{
etBroadcastTriggerAction.setText(broadcastSuggestions[which]);
}
});
builder.create().show();
}
});
bSaveTriggerBroadcast.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(etBroadcastTriggerAction.getText() != null && !StringUtils.isEmpty(etBroadcastTriggerAction.getText().toString()))
{
Intent data = new Intent();
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbBroadcastReceived.isChecked());
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, etBroadcastTriggerAction.getText().toString());
ActivityManageTriggerBroadcast.this.setResult(RESULT_OK, data);
finish();
}
else
Toast.makeText(ActivityManageTriggerBroadcast.this, getResources().getString(R.string.enterText), Toast.LENGTH_SHORT).show();
}
});
}
public static String[] broadcastSuggestions = {
"android.accounts.LOGIN_ACCOUNTS_CHANGED",
"android.accounts.action.ACCOUNT_REMOVED",
"android.app.action.ACTION_PASSWORD_CHANGED",
"android.app.action.ACTION_PASSWORD_EXPIRING",
"android.app.action.ACTION_PASSWORD_FAILED",
"android.app.action.ACTION_PASSWORD_SUCCEEDED",
"android.app.action.AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE",
"android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED",
"android.app.action.APP_BLOCK_STATE_CHANGED",
"android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED",
"android.app.action.BUGREPORT_FAILED",
"android.app.action.BUGREPORT_SHARE",
"android.app.action.BUGREPORT_SHARING_DECLINED",
"android.app.action.DATA_SHARING_RESTRICTION_APPLIED",
"android.app.action.DATA_SHARING_RESTRICTION_CHANGED",
"android.app.action.DEVICE_ADMIN_DISABLED",
"android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED",
"android.app.action.DEVICE_ADMIN_ENABLED",
"android.app.action.DEVICE_OWNER_CHANGED",
"android.app.action.INTERRUPTION_FILTER_CHANGED",
"android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL",
"android.app.action.LOCK_TASK_ENTERING",
"android.app.action.LOCK_TASK_EXITING",
"android.app.action.MANAGED_USER_CREATED",
"android.app.action.NETWORK_LOGS_AVAILABLE",
"android.app.action.NEXT_ALARM_CLOCK_CHANGED",
"android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED",
"android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED",
"android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED",
"android.app.action.NOTIFICATION_POLICY_CHANGED",
"android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE",
"android.app.action.PROFILE_OWNER_CHANGED",
"android.app.action.PROFILE_PROVISIONING_COMPLETE",
"android.app.action.SECURITY_LOGS_AVAILABLE",
"android.app.action.SYSTEM_UPDATE_POLICY_CHANGED",
"android.app.action.TRANSFER_OWNERSHIP_COMPLETE",
"android.app.action.USER_ADDED",
"android.app.action.USER_REMOVED",
"android.app.action.USER_STARTED",
"android.app.action.USER_STOPPED",
"android.app.action.USER_SWITCHED",
"android.appwidget.action.APPWIDGET_DELETED",
"android.appwidget.action.APPWIDGET_DISABLED",
"android.appwidget.action.APPWIDGET_ENABLED",
"android.appwidget.action.APPWIDGET_HOST_RESTORED",
"android.appwidget.action.APPWIDGET_RESTORED",
"android.appwidget.action.APPWIDGET_UPDATE",
"android.appwidget.action.APPWIDGET_UPDATE_OPTIONS",
"android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED",
"android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED",
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED",
"android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED",
"android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.adapter.action.DISCOVERY_FINISHED",
"android.bluetooth.adapter.action.DISCOVERY_STARTED",
"android.bluetooth.adapter.action.LOCAL_NAME_CHANGED",
"android.bluetooth.adapter.action.SCAN_MODE_CHANGED",
"android.bluetooth.adapter.action.STATE_CHANGED",
"android.bluetooth.device.action.ACL_CONNECTED",
"android.bluetooth.device.action.ACL_DISCONNECTED",
"android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED",
"android.bluetooth.device.action.ALIAS_CHANGED",
"android.bluetooth.device.action.BATTERY_LEVEL_CHANGED",
"android.bluetooth.device.action.BOND_STATE_CHANGED",
"android.bluetooth.device.action.CLASS_CHANGED",
"android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL",
"android.bluetooth.device.action.CONNECTION_ACCESS_REPLY",
"android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST",
"android.bluetooth.device.action.FOUND",
"android.bluetooth.device.action.MAS_INSTANCE",
"android.bluetooth.device.action.NAME_CHANGED",
"android.bluetooth.device.action.NAME_FAILED",
"android.bluetooth.device.action.PAIRING_CANCEL",
"android.bluetooth.device.action.PAIRING_REQUEST",
"android.bluetooth.device.action.SDP_RECORD",
"android.bluetooth.device.action.SILENCE_MODE_CHANGED",
"android.bluetooth.device.action.UUID",
"android.bluetooth.devicepicker.action.DEVICE_SELECTED",
"android.bluetooth.devicepicker.action.LAUNCH",
"android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT",
"android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED",
"android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED",
"android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED",
"android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.input.profile.action.HANDSHAKE",
"android.bluetooth.input.profile.action.IDLE_TIME_CHANGED",
"android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED",
"android.bluetooth.input.profile.action.REPORT",
"android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS",
"android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED",
"android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED",
"android.content.pm.action.SESSION_COMMITTED",
"android.content.pm.action.SESSION_UPDATED",
"android.hardware.action.NEW_PICTURE",
"android.hardware.action.NEW_VIDEO",
"android.hardware.hdmi.action.OSD_MESSAGE",
"android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS",
"android.hardware.usb.action.USB_ACCESSORY_ATTACHED",
"android.hardware.usb.action.USB_ACCESSORY_DETACHED",
"android.hardware.usb.action.USB_DEVICE_ATTACHED",
"android.hardware.usb.action.USB_DEVICE_DETACHED",
"android.intent.action.ACTION_IDLE_MAINTENANCE_END",
"android.intent.action.ACTION_IDLE_MAINTENANCE_START",
"android.intent.action.ACTION_POWER_CONNECTED",
"android.intent.action.ACTION_POWER_DISCONNECTED",
"android.intent.action.ACTION_PREFERRED_ACTIVITY_CHANGED",
"android.intent.action.ACTION_SHUTDOWN",
"android.intent.action.AIRPLANE_MODE",
"android.intent.action.ALARM_CHANGED",
"android.intent.action.APPLICATION_RESTRICTIONS_CHANGED",
"android.intent.action.BATTERY_CHANGED",
"android.intent.action.BATTERY_LOW",
"android.intent.action.BATTERY_OKAY",
"android.intent.action.BOOT_COMPLETED",
"android.intent.action.CALL_DISCONNECT_CAUSE",
"android.intent.action.CAMERA_BUTTON",
"android.intent.action.CANCEL_ENABLE_ROLLBACK",
"android.intent.action.CLEAR_DNS_CACHE",
"android.intent.action.CLOSE_SYSTEM_DIALOGS",
"android.intent.action.CONFIGURATION_CHANGED",
"android.intent.action.CONTENT_CHANGED",
"android.intent.action.DATA_SMS_RECEIVED",
"android.intent.action.DATA_STALL_DETECTED",
"android.intent.action.DATE_CHANGED",
"android.intent.action.DEVICE_STORAGE_FULL",
"android.intent.action.DEVICE_STORAGE_LOW",
"android.intent.action.DEVICE_STORAGE_NOT_FULL",
"android.intent.action.DEVICE_STORAGE_OK",
"android.intent.action.DISTRACTING_PACKAGES_CHANGED",
"android.intent.action.DOCK_EVENT",
"android.intent.action.DOWNLOAD_COMPLETE",
"android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED",
"android.intent.action.DREAMING_STARTED",
"android.intent.action.DREAMING_STOPPED",
"android.intent.action.DROPBOX_ENTRY_ADDED",
"android.intent.action.DYNAMIC_SENSOR_CHANGED",
"android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED",
"android.intent.action.EMERGENCY_CALL_STATE_CHANGED",
"android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE",
"android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE",
"android.intent.action.FACTORY_RESET",
"android.intent.action.FETCH_VOICEMAIL",
"android.intent.action.GTALK_CONNECTED",
"android.intent.action.GTALK_DISCONNECTED",
"android.intent.action.HEADSET_PLUG",
"android.intent.action.HEADSET_PLUG",
"android.intent.action.INPUT_METHOD_CHANGED",
"android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION",
"android.intent.action.LOCALE_CHANGED",
"android.intent.action.LOCKED_BOOT_COMPLETED",
"android.intent.action.MANAGE_PACKAGE_STORAGE",
"android.intent.action.MASTER_CLEAR_NOTIFICATION",
"android.intent.action.MEDIA_BAD_REMOVAL",
"android.intent.action.MEDIA_BUTTON",
"android.intent.action.MEDIA_CHECKING",
"android.intent.action.MEDIA_EJECT",
"android.intent.action.MEDIA_MOUNTED",
"android.intent.action.MEDIA_NOFS",
"android.intent.action.MEDIA_REMOVED",
"android.intent.action.MEDIA_SCANNER_FINISHED",
"android.intent.action.MEDIA_SCANNER_SCAN_FILE",
"android.intent.action.MEDIA_SCANNER_STARTED",
"android.intent.action.MEDIA_SHARED",
"android.intent.action.MEDIA_UNMOUNTABLE",
"android.intent.action.MEDIA_UNMOUNTED",
"android.intent.action.MY_PACKAGE_REPLACED",
"android.intent.action.MY_PACKAGE_SUSPENDED",
"android.intent.action.MY_PACKAGE_UNSUSPENDED",
"android.intent.action.NEW_OUTGOING_CALL",
"android.intent.action.NEW_VOICEMAIL",
"android.intent.action.PACKAGES_SUSPENDED",
"android.intent.action.PACKAGES_UNSUSPENDED",
"android.intent.action.PACKAGE_ADDED",
"android.intent.action.PACKAGE_CHANGED",
"android.intent.action.PACKAGE_DATA_CLEARED",
"android.intent.action.PACKAGE_ENABLE_ROLLBACK",
"android.intent.action.PACKAGE_FIRST_LAUNCH",
"android.intent.action.PACKAGE_FULLY_REMOVED",
"android.intent.action.PACKAGE_INSTALL",
"android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION",
"android.intent.action.PACKAGE_NEEDS_VERIFICATION",
"android.intent.action.PACKAGE_REMOVED",
"android.intent.action.PACKAGE_REPLACED",
"android.intent.action.PACKAGE_RESTARTED",
"android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY",
"android.intent.action.PACKAGE_VERIFIED",
"android.intent.action.PHONE_STATE",
"android.intent.action.PROVIDER_CHANGED",
"android.intent.action.PROXY_CHANGE",
"android.intent.action.QUERY_PACKAGE_RESTART",
"android.intent.action.REBOOT",
"android.intent.action.ROLLBACK_COMMITTED",
"android.intent.action.SCREEN_OFF",
"android.intent.action.SCREEN_ON",
"android.intent.action.SERVICE_STATE",
"android.intent.action.SIM_STATE_CHANGED",
"android.intent.action.SPLIT_CONFIGURATION_CHANGED",
"android.intent.action.SUB_DEFAULT_CHANGED",
"android.intent.action.TIMEZONE_CHANGED",
"android.intent.action.TIME_SET",
"android.intent.action.TIME_TICK",
"android.intent.action.UID_REMOVED",
"android.intent.action.UMS_CONNECTED",
"android.intent.action.UMS_DISCONNECTED",
"android.intent.action.USER_PRESENT",
"android.intent.action.USER_UNLOCKED",
"android.intent.action.WALLPAPER_CHANGED",
"android.media.ACTION_SCO_AUDIO_STATE_UPDATED",
"android.media.AUDIO_BECOMING_NOISY",
"android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION",
"android.media.MASTER_MUTE_CHANGED_ACTION",
"android.media.RINGER_MODE_CHANGED",
"android.media.SCO_AUDIO_STATE_CHANGED",
"android.media.STREAM_DEVICES_CHANGED_ACTION",
"android.media.STREAM_MUTE_CHANGED_ACTION",
"android.media.VIBRATE_SETTING_CHANGED",
"android.media.VOLUME_CHANGED_ACTION",
"android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION",
"android.media.action.HDMI_AUDIO_PLUG",
"android.media.action.MICROPHONE_MUTE_CHANGED",
"android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION",
"android.media.action.SPEAKERPHONE_STATE_CHANGED",
"android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED",
"android.media.tv.action.INITIALIZE_PROGRAMS",
"android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT",
"android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED",
"android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED",
"android.net.conn.BACKGROUND_DATA_SETTING_CHANGED",
"android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
"android.net.conn.CONNECTIVITY_CHANGE",
"android.net.conn.DATA_ACTIVITY_CHANGE",
"android.net.conn.INET_CONDITION_ACTION",
"android.net.conn.RESTRICT_BACKGROUND_CHANGED",
"android.net.conn.TETHER_STATE_CHANGED",
"android.net.nsd.STATE_CHANGED",
"android.net.scoring.SCORER_CHANGED",
"android.net.scoring.SCORE_NETWORKS",
"android.net.sip.action.SIP_CALL_OPTION_CHANGED",
"android.net.sip.action.SIP_INCOMING_CALL",
"android.net.sip.action.SIP_REMOVE_PROFILE",
"android.net.sip.action.SIP_SERVICE_UP",
"android.net.sip.action.START_SIP",
"android.net.wifi.BATCHED_RESULTS",
"android.net.wifi.NETWORK_IDS_CHANGED",
"android.net.wifi.RSSI_CHANGED",
"android.net.wifi.SCAN_RESULTS",
"android.net.wifi.STATE_CHANGE",
"android.net.wifi.WIFI_STATE_CHANGED",
"android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION",
"android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED",
"android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED",
"android.net.wifi.p2p.CONNECTION_STATE_CHANGE",
"android.net.wifi.p2p.DISCOVERY_STATE_CHANGE",
"android.net.wifi.p2p.PEERS_CHANGED",
"android.net.wifi.p2p.STATE_CHANGED",
"android.net.wifi.p2p.THIS_DEVICE_CHANGED",
"android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED",
"android.net.wifi.supplicant.CONNECTION_CHANGE",
"android.net.wifi.supplicant.STATE_CHANGE",
"android.nfc.action.ADAPTER_STATE_CHANGED",
"android.nfc.action.PREFERRED_PAYMENT_CHANGED",
"android.nfc.action.TRANSACTION_DETECTED",
"android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED",
"android.os.action.DEVICE_IDLE_MODE_CHANGED",
"android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED",
"android.os.action.POWER_SAVE_MODE_CHANGED",
"android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL",
"android.os.action.POWER_SAVE_MODE_CHANGING",
"android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED",
"android.os.action.POWER_SAVE_WHITELIST_CHANGED",
"android.os.action.UPDATE_EMERGENCY_NUMBER_DB",
"android.provider.Telephony.MMS_DOWNLOADED",
"android.provider.Telephony.SECRET_CODE",
"android.provider.Telephony.SIM_FULL",
"android.provider.Telephony.SMS_CARRIER_PROVISION",
"android.provider.Telephony.SMS_CB_RECEIVED",
"android.provider.Telephony.SMS_DELIVER",
"android.provider.Telephony.SMS_RECEIVED",
"android.provider.Telephony.SMS_REJECTED",
"android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED",
"android.provider.Telephony.WAP_PUSH_DELIVER",
"android.provider.Telephony.WAP_PUSH_RECEIVED",
"android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED",
"android.provider.action.EXTERNAL_PROVIDER_CHANGE",
"android.provider.action.SMS_EMERGENCY_CB_RECEIVED",
"android.provider.action.SMS_MMS_DB_CREATED",
"android.provider.action.SMS_MMS_DB_LOST",
"android.provider.action.SYNC_VOICEMAIL",
"android.security.STORAGE_CHANGED",
"android.security.action.KEYCHAIN_CHANGED",
"android.security.action.KEY_ACCESS_CHANGED",
"android.security.action.TRUST_STORE_CHANGED",
"android.service.controls.action.ADD_CONTROL",
"android.settings.ENABLE_MMS_DATA_REQUEST",
"android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED",
"android.speech.tts.engine.TTS_DATA_INSTALLED",
"android.telephony.action.AREA_INFO_UPDATED",
"android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED",
"android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED",
"android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED",
"android.telephony.action.REFRESH_SUBSCRIPTION_PLANS",
"android.telephony.action.SECRET_CODE",
"android.telephony.action.SERVICE_PROVIDERS_UPDATED",
"android.telephony.action.SIM_APPLICATION_STATE_CHANGED",
"android.telephony.action.SIM_CARD_STATE_CHANGED",
"android.telephony.action.SIM_SLOT_STATUS_CHANGED",
"android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
"android.telephony.action.SUBSCRIPTION_PLANS_CHANGED",
"android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED",
"android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE",
"android.telephony.euicc.action.OTA_STATUS_CHANGED",
"android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR",
"com.android.intent.action.DISMISS_KEYBOARD_SHORTCUTS",
"com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS",
"com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
"com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED"
};
}

View File

@ -0,0 +1,56 @@
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);
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();
}
});
}
}

View File

@ -272,6 +272,7 @@ public class ActivityManageTriggerNotification extends Activity
directions = new String[] {
getResources().getString(R.string.directionStringEquals),
getResources().getString(R.string.directionStringContains),
getResources().getString(R.string.directionStringDoesNotContain),
getResources().getString(R.string.directionStringStartsWith),
getResources().getString(R.string.directionStringEndsWith),
getResources().getString(R.string.directionStringNotEquals)
@ -321,23 +322,14 @@ public class ActivityManageTriggerNotification extends Activity
String textDir = Trigger.getMatchCode(spinnerTextDirection.getSelectedItem().toString());
String text = etNotificationText.getText().toString();
if(edit)
{
editedNotificationTrigger.setTriggerParameter(chkNotificationDirection.isChecked());
editedNotificationTrigger.setTriggerParameter2(app + triggerParameter2Split + titleDir + triggerParameter2Split + title + triggerParameter2Split + textDir + triggerParameter2Split + text);
ActivityManageTriggerNotification.this.setResult(RESULT_OK);
}
else
{
Intent data = new Intent();
data.putExtra(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);
}
Intent data = new Intent();
data.putExtra(intentNameNotificationDirection, chkNotificationDirection.isChecked());
data.putExtra(intentNameNotificationApp, app);
data.putExtra(intentNameNotificationTitleDir, titleDir);
data.putExtra(intentNameNotificationTitle, title);
data.putExtra(intentNameNotificationTextDir, textDir);
data.putExtra(intentNameNotificationText, text);
ActivityManageTriggerNotification.this.setResult(RESULT_OK, data);
finish();
}

View File

@ -86,8 +86,8 @@ public class ActivityManageTriggerPhoneCall extends Activity
else
{
Intent data = new Intent();
data.putExtra("triggerParameter", false);
data.putExtra("triggerParameter2", tp2Result);
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, false);
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, tp2Result);
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK, data);
}

View File

@ -0,0 +1,72 @@
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);
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();
}
});
}
}

View File

@ -0,0 +1,101 @@
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);
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();
}
});
}
}

View File

@ -1,6 +1,7 @@
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;
@ -9,13 +10,13 @@ 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.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@ -26,8 +27,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
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)
@ -52,17 +54,18 @@ public class ActivityManageTriggerTimeFrame extends Activity
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());
@ -152,8 +155,13 @@ public class ActivityManageTriggerTimeFrame extends Activity
}
editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked());
setResult(RESULT_OK);
editedTimeFrameTrigger.setTriggerParameter2(editedTimeFrameTrigger.getTimeFrame().toTriggerParameter2String());
Intent response = new Intent();
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, editedTimeFrameTrigger.getTriggerParameter());
response.putExtra(ActivityManageRule.intentNameTriggerParameter2, editedTimeFrameTrigger.getTriggerParameter2());
setResult(RESULT_OK, response);
finish();
}
});
@ -166,9 +174,40 @@ public class ActivityManageTriggerTimeFrame extends Activity
etRepeatEvery.setEnabled(isChecked);
}
});
if(editedTimeFrameTrigger.getTimeFrame() != null)
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()
@ -219,5 +258,4 @@ public class ActivityManageTriggerTimeFrame extends Activity
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
}
}
}
}

View File

@ -20,15 +20,13 @@ import android.widget.Button;
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 com.jens.automation2.receivers.BluetoothReceiver;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -41,10 +39,11 @@ public class ActivityManageTriggerWifi extends Activity
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
EditText etTriggerWifiName;
Spinner spinnerWifiList;
Button btriggerWifiSave, bLoadWifiList;
Button bTriggerWifiSave, bLoadWifiList;
List<String> wifiList = new ArrayList<>();
ArrayAdapter<String> wifiSpinnerAdapter;
private final static int requestCodeLocationPermission = 124;
TextView tvWifiTriggerNameLocationNotice;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
@ -56,13 +55,21 @@ public class ActivityManageTriggerWifi extends Activity
rbTriggerWifiDisconnected = (RadioButton) findViewById(R.id.rbTriggerWifiDisconnected);
etTriggerWifiName = (EditText) findViewById(R.id.etTriggerWifiName);
spinnerWifiList = (Spinner) findViewById(R.id.spinnerWifiList);
btriggerWifiSave = (Button) findViewById(R.id.btriggerWifiSave);
bTriggerWifiSave = (Button) findViewById(R.id.bTriggerWifiSave);
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
tvWifiTriggerNameLocationNotice = (TextView)findViewById(R.id.tvWifiTriggerNameLocationNotice);
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);
@ -74,7 +81,7 @@ public class ActivityManageTriggerWifi extends Activity
etTriggerWifiName.setText(wifiName);
}
btriggerWifiSave.setOnClickListener(new View.OnClickListener()
bTriggerWifiSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)

View File

@ -25,6 +25,8 @@ import android.widget.TextView;
import com.jens.automation2.receivers.NotificationListener;
import org.w3c.dom.DOMImplementationSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -47,6 +49,8 @@ public class ActivityPermissions extends Activity
private static final int requestCodeForPermissionsNotifications = 12046;
private static final int requestCodeForPermissionsDeviceAdmin = 12047;
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
private static final int requestCodeForPermissionNotificationAccessAndroid13 = 12049;
private static final int requestCodeForPermissionsManageOverlay = 12050;
protected String[] specificPermissionsToRequest = null;
public static String intentExtraName = "permissionsToBeRequested";
@ -224,7 +228,7 @@ public class ActivityPermissions extends Activity
}
}
protected static void addToArrayListUnique(String value, ArrayList<String> list)
public static void addToArrayListUnique(String value, List<String> list)
{
if (!list.contains(value))
list.add(value);
@ -248,14 +252,17 @@ public class ActivityPermissions extends Activity
if (!havePermission(s, context))
return true;
}
else if((s.equalsIgnoreCase(Manifest.permission.CALL_PHONE) || s.equalsIgnoreCase(Manifest.permission.ANSWER_PHONE_CALLS)) && BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
{
return false;
}
else if(s.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || s.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
if (!havePermission(s, context))
return true;
}
else
if (!havePermission(s, context))
else if (!havePermission(s, context))
return true;
}
}
@ -293,6 +300,10 @@ public class ActivityPermissions extends Activity
String packageName = context.getApplicationContext().getPackageName();
return pm.isIgnoringBatteryOptimizations(packageName);
}
else if (s.equals(Manifest.permission.SYSTEM_ALERT_WINDOW))
{
return android.provider.Settings.canDrawOverlays(Miscellaneous.getAnyContext());
}
else
{
int res = context.checkCallingOrSelfPermission(s);
@ -311,6 +322,11 @@ public class ActivityPermissions extends Activity
return active;
}
public static void requestOverlay()
{
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsManageOverlay);
}
public static void requestDeviceAdmin()
{
if(!haveDeviceAdmin())
@ -381,7 +397,7 @@ public class ActivityPermissions extends Activity
}
else if (singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if (!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if (!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
addToArrayListUnique(singlePermission, requiredPermissions);
}
else
@ -469,6 +485,7 @@ public class ActivityPermissions extends Activity
case phoneCall:
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.PROCESS_OUTGOING_CALLS, requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_CALL_LOG, requiredPermissions);
break;
case pointOfInterest:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
@ -509,6 +526,16 @@ public class ActivityPermissions extends Activity
case wifiConnection:
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, requiredPermissions);
if(
(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
&&
isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
||
Build.VERSION.SDK_INT >= 33
)
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, requiredPermissions);
break;
case notification:
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
@ -620,6 +647,8 @@ public class ActivityPermissions extends Activity
// action.getParameter2().contains("eu.faircode.netguard.STOP_PORT_FORWARD")
// )
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
if(Build.VERSION.SDK_INT >= 29)
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
break;
case triggerUrl:
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
@ -673,6 +702,13 @@ public class ActivityPermissions extends Activity
else
addToArrayListUnique(Manifest.permission.BIND_DEVICE_ADMIN, requiredPermissions);
break;
case startPhoneCall:
addToArrayListUnique(Manifest.permission.CALL_PHONE, requiredPermissions);
// addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
break;
case stopPhoneCall:
addToArrayListUnique(Manifest.permission.ANSWER_PHONE_CALLS, requiredPermissions);
break;
default:
break;
}
@ -757,6 +793,7 @@ public class ActivityPermissions extends Activity
break;
case Manifest.permission.ACCESS_BACKGROUND_LOCATION:
usingElements.add(getResources().getString(R.string.googleLocationChicanery));
usingElements.add(getResources().getString(R.string.wifiMonitoringAlsoRequiresThis));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
@ -841,6 +878,7 @@ public class ActivityPermissions extends Activity
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.PROCESS_OUTGOING_CALLS:
case Manifest.permission.READ_CALL_LOG:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.phoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
@ -864,6 +902,18 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.sendTextMessage))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.CALL_PHONE:
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.SYSTEM_ALERT_WINDOW:
for(String ruleName : getRulesUsing(Action.Action_Enum.startOtherActivity))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.ANSWER_PHONE_CALLS:
for(String ruleName : getRulesUsing(Action.Action_Enum.stopPhoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.FOREGROUND_SERVICE:
usingElements.add(getResources().getString(R.string.startAutomationAsService));
break;
@ -904,6 +954,9 @@ public class ActivityPermissions extends Activity
case Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS:
usingElements.add(getResources().getString(R.string.recommendedForBetterReliability));
break;
case Manifest.permission.QUERY_ALL_PACKAGES:
usingElements.add(getResources().getString(R.string.queryAllPackages));
break;
}
return usingElements;
@ -955,6 +1008,10 @@ public class ActivityPermissions extends Activity
if (requestCode == requestCodeForPermissionsBatteryOptimization)
if(havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
if (requestCode == requestCodeForPermissionsManageOverlay)
if(havePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
}
}
@ -1005,7 +1062,7 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
return;
}
if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
else if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
@ -1020,12 +1077,46 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.SYSTEM_ALERT_WINDOW))
{
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.overlayPermissionHint), ActivityPermissions.this);
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialogInterface)
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestOverlay();
}
});
diag.show();
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivityForResult(intent, requestCodeForPermissionsNotifications);
if(Build.VERSION.SDK_INT >= 33)
{
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.notificationAccessAndroid13), ActivityPermissions.this);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialogInterface)
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestNotificationAccess();
}
});
dialog.show();
}
else
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestNotificationAccess();
}
return;
}
else if(s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
@ -1100,6 +1191,12 @@ public class ActivityPermissions extends Activity
}
}
void requestNotificationAccess()
{
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivityForResult(intent, requestCodeForPermissionsNotifications);
}
protected void applyChanges()
{
AutomationService service = AutomationService.getInstance();

View File

@ -18,10 +18,10 @@ public class ActivitySettings extends PreferenceActivity
super.onCreate(savedInstanceState);
addPreferencesFromResource(layout.activity_settings);
if(BuildConfig.FLAVOR.equals("apkFlavor"))
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
{
chkPrefUpdateCheck = (CheckBoxPreference) findPreference("automaticUpdateCheck");
chkPrefUpdateCheck.setEnabled(true);
}
}
}
}

View File

@ -12,6 +12,8 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Build;
@ -20,6 +22,7 @@ import android.os.Environment;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
@ -28,19 +31,29 @@ import androidx.core.app.NotificationManagerCompat;
import com.jens.automation2.Trigger.Trigger_Enum;
import com.jens.automation2.location.LocationProvider;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.PackageReplacedReceiver;
import com.jens.automation2.receivers.PhoneStatusListener;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@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;
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";
@ -57,6 +70,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;
@ -85,6 +102,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;
@ -94,8 +116,6 @@ public class AutomationService extends Service implements OnInitListener
return myLocationProvider;
}
protected static AutomationService centralInstance = null;
public static AutomationService getInstance()
{
return centralInstance;
@ -110,6 +130,8 @@ 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;
Miscellaneous.setDisplayLanguage(AutomationService.this);
}
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
@ -192,6 +214,9 @@ 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))
@ -211,12 +236,10 @@ public class AutomationService extends Service implements OnInitListener
ActivityMainScreen.updateMainScreen();
this.isRunning = true;
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
// ********** Test area **********
// Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3);
// Actions.setData(true);
// ********** Test area **********
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.
@ -246,8 +269,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);
@ -287,6 +308,8 @@ public class AutomationService extends Service implements OnInitListener
myLocationProvider.applySettingsAndRules();
ReceiverCoordinator.applySettingsAndRules();
DateTimeListener.reloadAlarms();
}
@Override
@ -296,7 +319,8 @@ public class AutomationService extends Service implements OnInitListener
stopRoutine();
this.isRunning = false;
Toast.makeText(this, getResources().getString(R.string.serviceStopped), Toast.LENGTH_LONG).show();
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);
}
@ -305,8 +329,26 @@ public class AutomationService extends Service implements OnInitListener
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,6 +357,8 @@ public class AutomationService extends Service implements OnInitListener
private void startUpRoutine()
{
Settings.serviceStartDone = false;
checkForTtsEngine();
checkForPermissions();
checkForRestrictedFeatures();
@ -333,6 +377,9 @@ public class AutomationService extends Service implements OnInitListener
if(r.getsGreenLight(AutomationService.this))
r.activate(AutomationService.this, false);
}
Settings.serviceStartDone = true;
Settings.deviceStartDone = true;
}
protected void startLocationProvider()
@ -446,6 +493,10 @@ public class AutomationService extends Service implements OnInitListener
private void stopRoutine()
{
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
// Clear variables for trigger/action with same name
variableMap.clear();
try
{
myLocationProvider.stopLocationService();
@ -460,6 +511,9 @@ public class AutomationService extends Service implements OnInitListener
ttsEngine.shutdown();
PackageReplacedReceiver.setHasServiceBeenRunning(false, this);
centralInstance = null;
Settings.serviceStartDone = false;
}
protected static Builder createDefaultNotificationBuilderOld()
@ -553,11 +607,11 @@ public class AutomationService extends Service implements OnInitListener
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + " " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + " " + activePoi.getName() + lastRuleString;
}
}
catch(NullPointerException e)
@ -649,25 +703,26 @@ 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", "Speaking " + text + " in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
Miscellaneous.logEvent("i", "TextToSpeech", "TTS engine not available after waiting 30 seconds, yet. Aborting.", 3);
}
catch(Exception e)
{
@ -677,14 +732,19 @@ public class AutomationService extends Service implements OnInitListener
}
}
}
public static boolean isMainActivityRunning(Context context)
{
public Map<String, String> getVariableMap()
{
return variableMap;
}
public static boolean isMainActivityRunning(Context context)
{
if(ActivityMainScreen.getActivityMainScreenInstance() == null)
return false;
else
return true;
}
}
public static boolean isMyServiceRunning(Context context)
{

View File

@ -15,6 +15,7 @@ import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
@ -31,6 +32,7 @@ import android.provider.Settings.Secure;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
@ -82,7 +84,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -91,7 +92,6 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@ -113,6 +113,8 @@ import androidx.documentfile.provider.DocumentFile;
public class Miscellaneous extends Service
{
protected static String writeableFolderStringCache = null;
public static Context startupContext;
public static final String lineSeparator = System.getProperty("line.separator");
public static String downloadURL(String url, String username, String password)
@ -275,7 +277,7 @@ public class Miscellaneous extends Service
{
writeToLogFile(type, header, description);
if(!logCleanerRunning && Math.random() < 0.1) // tidy up with 10% probability
if (!logCleanerRunning && Math.random() < 0.1) // tidy up with 10% probability
{
rotateLogFile(getLogFile());
}
@ -476,11 +478,16 @@ public class Miscellaneous extends Service
switch(direction)
{
case Trigger.directionEquals:
return haystack.equalsIgnoreCase(needle);
if(Miscellaneous.isRegularExpression(needle))
return haystack.matches(needle);
else
return haystack.equalsIgnoreCase(needle);
case Trigger.directionNotEquals:
return !haystack.equalsIgnoreCase(needle);
case Trigger.directionContains:
return haystack.toLowerCase().contains(needle.toLowerCase());
case Trigger.directionNotContains:
return !haystack.toLowerCase().contains(needle.toLowerCase());
case Trigger.directionStartsWith:
return haystack.toLowerCase().startsWith(needle.toLowerCase());
case Trigger.directionEndsWith:
@ -490,7 +497,7 @@ public class Miscellaneous extends Service
}
}
public static int compareTimes(Time time1, Time time2)
public static int compareTimes(TimeObject time1, TimeObject time2)
{
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
@ -554,7 +561,10 @@ public class Miscellaneous extends Service
returnContext = ActivityPermissions.getInstance().getApplicationContext();
if(returnContext != null)
return returnContext;
if(startupContext != null)
return startupContext;
return null;
}
@ -606,32 +616,89 @@ public class Miscellaneous extends Service
}
if(source.contains("[serialnr]"))
if(Build.VERSION.SDK_INT > 8)
{
if (Build.VERSION.SDK_INT > 8)
source = source.replace("[serialnr]", Secure.getString(context.getContentResolver(), Build.SERIAL));
else
source = source.replace("[serialnr]", "serialUnknown");
}
if(
source.contains("[d]") |
source.contains("[m]") |
source.contains("[Y]") |
source.contains("[h]") |
source.contains("[H]") |
source.contains("[i]") |
source.contains("[s]") |
source.contains("[d]") ||
source.contains("[m]") ||
source.contains("[Y]") ||
source.contains("[h]") ||
source.contains("[H]") ||
source.contains("[i]") ||
source.contains("[s]") ||
source.contains("[ms]")
)
{
Calendar cal = Calendar.getInstance();
source = source.replace("[d]", String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
source = source.replace("[m]", String.valueOf(cal.get(Calendar.MONTH)));
source = source.replace("[Y]", String.valueOf(cal.get(Calendar.YEAR)));
source = source.replace("[h]", String.valueOf(cal.get(Calendar.HOUR)));
source = source.replace("[H]", String.valueOf(cal.get(Calendar.HOUR_OF_DAY)));
source = source.replace("[i]", String.valueOf(cal.get(Calendar.MINUTE)));
source = source.replace("[s]", String.valueOf(cal.get(Calendar.SECOND)));
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
if(source.contains("[d]"))
{
String result = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
if(result.length() < 2)
result = "0" + result;
source = source.replace("[d]", result);
}
if(source.contains("[m]"))
{
String result = String.valueOf(cal.get(Calendar.MONTH) +1);
if(result.length() < 2)
result = "0" + result;
source = source.replace("[m]", result);
}
if(source.contains("[Y]"))
{
source = source.replace("[Y]", String.valueOf(cal.get(Calendar.YEAR)));
}
if(source.contains("[h]"))
{
String result = String.valueOf(cal.get(Calendar.HOUR));
if(result.length() < 2)
result = "0" + result;
source = source.replace("[h]", result);
}
if(source.contains("[H]"))
{
String result = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
if(result.length() < 2)
result = "0" + result;
source = source.replace("[H]", result);
}
if(source.contains("[i]"))
{
String result = String.valueOf(cal.get(Calendar.MINUTE));
if(result.length() < 2)
result = "0" + result;
source = source.replace("[i]", result);
}
if(source.contains("[s]"))
{
String result = String.valueOf(cal.get(Calendar.SECOND));
if(result.length() < 2)
result = "0" + result;
source = source.replace("[s]", String.valueOf(cal.get(Calendar.SECOND)));
}
if(source.contains("[ms]"))
{
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
}
}
if(source.contains("[notificationTitle]"))
@ -675,6 +742,26 @@ public class Miscellaneous extends Service
Miscellaneous.logEvent("w", "Variable replacement", "lastNotification was empty.", 3);
}
}
while(source.contains("[variable-"))
{
int pos1 = source.indexOf("[variable-");
int pos2 = source.indexOf("]", pos1);
int posA = pos1 + "[variable-".length();
int posB = source.indexOf("]", posA);
String variableName = source.substring(posA, posB);
String replacement;
if(AutomationService.getInstance().variableMap.containsKey(variableName))
replacement = AutomationService.getInstance().variableMap.get(variableName);
else
replacement = "unknownVariable";
source = source.substring(0, pos1) + replacement + source.substring(pos2);
}
// Miscellaneous.logEvent("i", "URL after replace", source);
@ -710,14 +797,6 @@ public class Miscellaneous extends Service
}
});
// alertDialog.setNegativeButton(context.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
// {
// public void onClick(DialogInterface dialog, int whichButton)
// {
// // Canceled.
// }
// });
return alertDialog.create();
}
@ -744,8 +823,8 @@ public class Miscellaneous extends Service
*
* @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
*/
public static boolean isPhoneRooted()
{
public static boolean isPhoneRooted()
{
// if(true)
// return true;
@ -753,30 +832,30 @@ public class Miscellaneous extends Service
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys"))
{
return true;
return true;
}
// check if /system/app/Superuser.apk is present
try
{
File file = new File("/system/app/Superuser.apk");
if (file.exists())
{
return true;
}
}
catch (Exception e1)
{
try
{
File file = new File("/system/app/Superuser.apk");
if (file.exists())
{
return true;
}
}
catch (Exception e1)
{
// ignore
}
}
// try executing commands
return canExecuteCommand("/system/xbin/which su")
return canExecuteCommand("/system/xbin/which su")
||
canExecuteCommand("/system/bin/which su")
||
canExecuteCommand("which su");
}
}
// executes a command on the system
private static boolean canExecuteCommand(String command)
@ -794,19 +873,35 @@ public class Miscellaneous extends Service
return executedSuccesfully;
}
public static boolean isNumericDecimal(String strNum)
{
if (strNum == null)
{
return false;
}
try
{
double d = Double.parseDouble(strNum);
}
catch (NumberFormatException nfe)
{
return false;
}
return true;
}
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
/**
* Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
private static void disableSSLCertificateChecking()
{
try
private static void disableSSLCertificateChecking()
{
try
{
SSLSocketFactory ssf = null;
@ -1379,7 +1474,7 @@ public class Miscellaneous extends Service
return result;
}
public static boolean restrictedFeaturesConfigured()
public static boolean restrictedFeaturesConfiguredFdroid()
{
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
@ -1396,6 +1491,17 @@ public class Miscellaneous extends Service
return false;
}
public static boolean restrictedFeaturesConfiguredGoogle()
{
if(Rule.isAnyRuleUsing(Action.Action_Enum.startPhoneCall) || Rule.isAnyRuleUsing(Action.Action_Enum.stopPhoneCall))
{
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
return true;
}
return false;
}
public static Element getXmlTree(String inputString) throws SAXException, IOException, ParserConfigurationException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@ -1626,7 +1732,7 @@ public class Miscellaneous extends Service
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
if (BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
{
if(checkExistingRules)
{
@ -1759,13 +1865,12 @@ public class Miscellaneous extends Service
public static boolean comparePhoneNumbers(String number1, String number2)
{
/* To be activated when Android S SDK comes out
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
{
TelephonyManager tm = (TelephonyManager)Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
}
else*/
else
return PhoneNumberUtils.compare(number1, number2);
}
@ -1840,7 +1945,8 @@ public class Miscellaneous extends Service
* @param context Context reference to get the TelephonyManager instance from
* @return country code or null
*/
public static String getUserCountry(Context context) {
public static String getUserCountry(Context context)
{
try
{
final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
@ -1898,4 +2004,25 @@ public class Miscellaneous extends Service
return null;
}
public static int getTargetSDK(Context context)
{
return context.getApplicationContext().getApplicationInfo().targetSdkVersion;
}
public static void setDisplayLanguage(Context context)
{
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
{
Locale myLocale = new Locale(Settings.displayLanguage);
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
//Intent refresh = new Intent(this, AndroidLocalize.class);
//finish();
//startActivity(refresh);
}
}
}

View File

@ -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()
@ -421,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()))
{
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();
@ -490,8 +494,10 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Check for change of rule name END
*/
if (plausibilityCheck())
if(plausibilityCheck())
{
Miscellaneous.logEvent("i", "Changing POI", "Old name: " + this.oldName + ", new data: " + this.toStringLong(), 3);
if(PointOfInterest.writePoisToFile())
{
AutomationService service = AutomationService.getInstance();

View File

@ -3,13 +3,12 @@ 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.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
@ -43,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;
@ -64,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()
@ -173,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;
}
@ -209,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;
}
@ -294,53 +293,69 @@ public class Profile implements Comparable<Profile>
return null;
}
private boolean applyRingTone(File ringtoneFile, int ringtoneType, Context context)
private boolean applyRingTone(String ringtoneFile, int ringtoneType, Context context)
{
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile.getAbsolutePath(), 3);
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile, 3);
if(!ringtoneFile.exists() || !ringtoneFile.canRead())
// if(!ringtoneFile.exists() || !ringtoneFile.canRead())
// {
// String message = "Ringtone file does not exist or cannot read it: " + ringtoneFile.getAbsolutePath();
// Miscellaneous.logEvent("i", "Profile", message, 3);
// Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
// return false;
// }
// Set by URI
if(ringtoneFile.contains("//"))
{
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, ringtoneFile.getName());
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.MediaColumns.SIZE, ringtoneFile.length());
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);
try
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
{
Uri newRingTone = null;
ContentValues values = new ContentValues();
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.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);
//TODO: This part needs to be made compatible with Android 11 and above.
if(Build.VERSION.SDK_INT > 30)
try
{
Uri existingRingTone = MediaStore.Audio.Media.getContentUriForPath(ringtoneFile.getAbsolutePath());
Uri newRingTone = null;
if (existingRingTone != null)
context.getContentResolver().delete(existingRingTone, MediaStore.MediaColumns.DATA + "=\"" + ringtoneFile.getAbsolutePath() + "\"", 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);
return true;
RingtoneManager.setActualDefaultRingtoneUri(context, ringtoneType, newRingTone);
Miscellaneous.logEvent("i", "Profile", "Ringtone set to: " + newRingTone.toString(), 1);
return true;
}
catch (Throwable t)
{
String message = "Error setting ringtone: " + Log.getStackTraceString(t);
Miscellaneous.logEvent("e", "Profile", message, 1);
}
}
catch (Throwable t)
{
String message = "Error setting ringtone: " + Log.getStackTraceString(t);
Miscellaneous.logEvent("e", "Profile", message, 1);
}
return false;
}
@ -509,7 +524,7 @@ public class Profile implements Comparable<Profile>
Actions.setSound(context, soundMode);
if(changeDndMode)
Actions.setDND(context, dndMode);
Actions.setDoNotDisturb(context, dndMode);
if(changeVolumeMusicVideoGameMedia)
am.setStreamVolume(AudioManager.STREAM_MUSIC, volumeMusic, AudioManager.FLAG_PLAY_SOUND);
@ -570,17 +585,17 @@ public class Profile implements Comparable<Profile>
}
finally
{
Miscellaneous.logEvent("i", "POI", "Checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
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", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies after " + this.getName() + " has been activated.", 2);
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", "POI", "Done checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
Miscellaneous.logEvent("i", "Profile", "Done checking for applicable rules after profile " + this.getName() + " has been activated.", 2);
}
}
else

View File

@ -5,6 +5,7 @@ import android.util.Log;
import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.AutomationListenerInterface;
import com.jens.automation2.receivers.BatteryReceiver;
@ -17,6 +18,8 @@ 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;
@ -58,7 +61,8 @@ public class ReceiverCoordinator
ProcessListener.class,
MediaPlayerListener.class,
ScreenStateReceiver.class,
TimeZoneListener.class
TimeZoneListener.class,
TetheringReceiver.class
};
}
catch (ClassNotFoundException e)
@ -67,6 +71,7 @@ public class ReceiverCoordinator
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
BroadcastListener.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
@ -75,7 +80,8 @@ public class ReceiverCoordinator
PhoneStatusListener.class,
ProcessListener.class,
ScreenStateReceiver.class,
TimeZoneListener.class
TimeZoneListener.class,
TetheringReceiver.class
};
}
}
@ -163,6 +169,10 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.noiseLevel))
NoiseListener.startNoiseListener(AutomationService.getInstance());
// 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());
@ -170,6 +180,12 @@ public class ReceiverCoordinator
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);
@ -206,16 +222,19 @@ public class ReceiverCoordinator
TimeZoneListener.stopTimeZoneListener();
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);
}
catch(ClassNotFoundException e)
catch(Exception e)
{
// Nothing to do, just not stopping this one.
}
@ -266,6 +285,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);
@ -300,7 +330,7 @@ public class ReceiverCoordinator
MediaPlayerListener.getInstance().stopListener(AutomationService.getInstance());
}
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
{
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
@ -397,6 +427,42 @@ public class ReceiverCoordinator
}
}
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());
}
}
AutomationService.updateNotification();
}
}

View File

@ -12,7 +12,7 @@ import java.util.Set;
public class Settings implements SharedPreferences
{
public static final int rulesThatHaveBeenRanHistorySize = 10;
public final static int lockSoundChangesInterval = 15;
public static final int lockSoundChangesInterval = 15;
public static final int newsPollEveryXDays = 3;
public static final int newsDisplayForXDays = 3;
public static final int updateCheckFrequencyDays = 7;
@ -65,8 +65,10 @@ public class Settings implements SharedPreferences
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;
@ -77,7 +79,13 @@ public class Settings implements SharedPreferences
public static ArrayList<String> whatHasBeenDone;
/*
Generic settings valid for all installations and not changable
Not saved permanently.
*/
public static boolean deviceStartDone = true; // by default assume device has not just been started
public static boolean serviceStartDone = false;
/*
Generic settings valid for all installations and not changeable
*/
public static final String dateFormat = "E dd.MM.yyyy HH:mm:ss:ssss";
@ -124,11 +132,14 @@ public class Settings implements SharedPreferences
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)
@ -264,6 +275,7 @@ public class Settings implements SharedPreferences
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;
@ -271,6 +283,7 @@ public class Settings implements SharedPreferences
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);
@ -466,9 +479,15 @@ public class Settings implements SharedPreferences
if(!prefs.contains("displayNewsOnMainScreen") || force)
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
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);
@ -549,11 +568,14 @@ public class Settings implements SharedPreferences
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);
@ -600,5 +622,4 @@ public class Settings implements SharedPreferences
// TODO Auto-generated method stub
return null;
}
}

View File

@ -6,8 +6,8 @@ import java.util.ArrayList;
public class TimeFrame
{
// Defines a timeframe
protected Time triggerTimeStart;
protected Time triggerTimeStop;
protected TimeObject triggerTimeStart;
protected TimeObject triggerTimeStop;
protected long repetition;
protected final static String separator = "/";
@ -34,20 +34,20 @@ public class TimeFrame
}
}
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;
}
@ -62,7 +62,7 @@ public class TimeFrame
this.repetition = repetition;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2, long repetition)
public TimeFrame (TimeObject timeStart, TimeObject timeEnd, ArrayList<Integer> dayList2, long repetition)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
@ -73,13 +73,36 @@ public class TimeFrame
public TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split(separator); // example: timestart/timestop/days[int]/repetition
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.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()
{

View 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();
}
}

View File

@ -3,7 +3,6 @@ package com.jens.automation2;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.telephony.TelephonyManager;
import android.util.Log;
@ -14,6 +13,7 @@ import com.jens.automation2.location.LocationProvider;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener;
@ -24,22 +24,46 @@ import com.jens.automation2.receivers.NotificationListener;
import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ScreenStateReceiver;
import static com.jens.automation2.Trigger.triggerParameter2Split;
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
import com.jens.automation2.receivers.TetheringReceiver;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
public class Trigger
{
public enum Trigger_Enum {
pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, screenState, musicPlaying, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
public enum Trigger_Enum
{
pointOfInterest,
timeFrame,
charging,
batteryLevel,
usb_host_connection,
speed,
noiseLevel,
wifiConnection,
process_started_stopped,
airplaneMode,
roaming,
nfcTag,
activityDetection,
bluetoothConnection,
headsetPlugged,
notification,
deviceOrientation,
profileActive,
screenState,
musicPlaying,
deviceStarts,
serviceStarts,
broadcastReceived,
tethering,
subSystemState,
checkVariable,
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
public String getFullName(Context context)
{
@ -87,12 +111,26 @@ public class Trigger
return context.getResources().getString(R.string.musicPlaying);
case screenState:
return context.getResources().getString(R.string.screenState);
case deviceStarts:
return context.getResources().getString(R.string.deviceStarts);
case serviceStarts:
return context.getResources().getString(R.string.serviceStarts);
case broadcastReceived:
return context.getResources().getString(R.string.broadcastReceivedTitle);
case tethering:
return context.getResources().getString(R.string.tetheringState);
case subSystemState:
return context.getResources().getString(R.string.subSystemState);
case checkVariable:
return context.getResources().getString(R.string.checkVariable);
default:
return "Unknown";
}
}
};
public static enum subSystemStates { wifi, bluetooth };
Rule parentRule = null;
Calendar lastTimeNotApplied = null;
@ -190,6 +228,30 @@ public class Trigger
if(!checkScreenState())
result = false;
break;
case deviceStarts:
if(!checkDeviceStarts())
result = false;
break;
case serviceStarts:
if(!checkServiceStarts())
result = false;
break;
case broadcastReceived:
if(!checkBroadcastReceived())
result = false;
break;
case tethering:
if(!checkTetheringActive())
result = false;
break;
case subSystemState:
if(!checkSubSystemState())
result = false;
break;
case checkVariable:
if(!checkVariable())
result = false;
break;
default:
break;
}
@ -206,7 +268,19 @@ public class Trigger
return result;
}
boolean checkNotification()
boolean checkBroadcastReceived()
{
/*
We cannot reasonably check the current state for every broadcast event.
We can only hope that when starting the receiver we get an initial broadcast
for every current state. That collection of states will be saved and checked if
it contains the specific event of this trigger.
*/
return triggerParameter == BroadcastListener.getInstance().hasBroadcastOccurred(triggerParameter2);
}
boolean checkNotification()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
@ -343,6 +417,21 @@ public class Trigger
return triggerParameter == MediaPlayerListener.isAudioPlaying(Miscellaneous.getAnyContext());
}
boolean checkDeviceStarts()
{
if(triggerParameter && checkServiceStarts() && !Settings.deviceStartDone)
return true;
else if(!triggerParameter && !checkServiceStarts() && Settings.deviceStartDone)
return true;
else
return false;
}
boolean checkServiceStarts()
{
return !Settings.serviceStartDone == getTriggerParameter();
}
boolean checkProfileActive()
{
String demandedProfileName = getTriggerParameter2().split(Trigger.triggerParameter2Split)[0];
@ -385,13 +474,15 @@ public class Trigger
try
{
int desiredState = Integer.parseInt(getTriggerParameter2());
int currentState = ScreenStateReceiver.getScreenState();
return desiredState == currentState;
if(desiredState == ScreenStateReceiver.SCREEN_STATE_OFF || desiredState == ScreenStateReceiver.SCREEN_STATE_ON)
return desiredState == ScreenStateReceiver.getScreenPowerState();
else
return desiredState == ScreenStateReceiver.getScreenLockState();
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "Trigger", "Error checking profile trigger.", 4);
Miscellaneous.logEvent("w", "Trigger", "Error checking screen state trigger.", 4);
}
return false;
@ -466,6 +557,58 @@ public class Trigger
return true;
}
boolean checkSubSystemState()
{
try
{
subSystemStates state = subSystemStates.valueOf(triggerParameter2);
switch (state)
{
case wifi:
return WifiBroadcastReceiver.isWifiEnabled(Miscellaneous.getAnyContext()) == triggerParameter;
case bluetooth:
return BluetoothReceiver.isBluetoothEnabled() == triggerParameter;
default:
Miscellaneous.logEvent("w", "checkSubSystemState()", "Invalid subSystemState: " + state.name(), 3);
return false;
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "checkSubSystemState()", Log.getStackTraceString(e), 1);
}
return false;
}
boolean checkVariable()
{
try
{
Map<String,String> map = AutomationService.getInstance().getVariableMap();
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
if(conditions.length == 1) // no real condition
return true;
else
{
if (map.containsKey(conditions[0]))
{
if (map.get(conditions[0]).equals(conditions[1]))
return true;
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "checkVariable()", Log.getStackTraceString(e), 1);
}
return false;
}
boolean checkBluetooth()
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Checking for bluetooth...", this.getParentRule().getName()), 4);
@ -659,7 +802,8 @@ public class Trigger
if(this.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name specified, checking that.", this.getParentRule().getName()), 4);
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()))
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()),this.getParentRule().getName()), 3);
return false;
@ -725,9 +869,21 @@ public class Trigger
boolean checkBatteryLevel()
{
/*
-1 means value is not known, yet.
*/
if(BatteryReceiver.getBatteryLevel() == -1)
return false;
if(this.getTriggerParameter())
{
if(BatteryReceiver.getBatteryLevel() <= this.getBatteryLevel())
if(this.getBatteryLevel() == 100)
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), "Rule " + this.getParentRule().getName() + " doesn't apply. Can never exceed 100%.", 3);
return false;
}
if(BatteryReceiver.getBatteryLevel() < this.getBatteryLevel())
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(this.getBatteryLevel()), this.getParentRule().getName()), 3);
return false;
@ -735,7 +891,16 @@ public class Trigger
}
else
{
if(this.getBatteryLevel() >= this.getBatteryLevel())
if(this.getBatteryLevel() == 0)
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), "Rule " + this.getParentRule().getName() + " doesn't apply. Can never drop below 0%.", 3);
return false;
}
if(BatteryReceiver.getBatteryLevel() < 100 && BatteryReceiver.getBatteryLevel() >= this.getBatteryLevel()
||
BatteryReceiver.getBatteryLevel() > this.getBatteryLevel()
)
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(this.getBatteryLevel()), this.getParentRule().getName()), 3);
return false;
@ -857,6 +1022,28 @@ public class Trigger
return true;
}
boolean checkTetheringActive()
{
if(TetheringReceiver.isTetheringActive() == triggerParameter)
{
if(getTriggerParameter2().equals(ActivityManageTriggerTethering.tetheringTypeAny))
return true;
for(String oneOfLastTypes : TetheringReceiver.getLastTetheringTypes())
{
if(oneOfLastTypes.equals(getTriggerParameter2()))
{
if(triggerParameter)
return true;
else
return false;
}
}
}
return false;
}
public boolean checkDateTime(Object triggeringObject, boolean checkifStateChangedSinceLastRuleExecution)
{
/*
@ -872,7 +1059,7 @@ public class Trigger
triggeringTime = new Date();
String timeString = String.valueOf(triggeringTime.getHours()) + ":" + String.valueOf(triggeringTime.getMinutes()) + ":" + String.valueOf(triggeringTime.getSeconds());
Time nowTime = Time.valueOf(timeString);
TimeObject nowTime = TimeObject.valueOf(timeString);
Calendar calNow = Calendar.getInstance();
try
@ -884,20 +1071,24 @@ public class Trigger
if(
// Regular case, start time is lower than end time
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
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
)
|
// 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)
)
)
{
// We are in the timeframe
@ -1023,7 +1214,7 @@ public class Trigger
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
Time setTime;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
@ -1217,9 +1408,9 @@ public class Trigger
return triggerType;
}
public void setTriggerType(Trigger_Enum settriggerType)
public void setTriggerType(Trigger_Enum setTriggerType)
{
this.triggerType = settriggerType;
this.triggerType = setTriggerType;
}
public boolean getTriggerParameter()
@ -1239,7 +1430,7 @@ public class Trigger
public void setTriggerParameter2(String triggerParameter2)
{
this.triggerParameter2 = triggerParameter2;
this.triggerParameter2 = triggerParameter2.trim();
}
public TimeFrame getTimeFrame()
@ -1262,7 +1453,7 @@ public class Trigger
switch(this.getTriggerType())
{
case charging:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.starting) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.stopping) + " ");
@ -1270,14 +1461,14 @@ public class Trigger
break;
case batteryLevel:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.batteryLevel));
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.exceeds) + " ");
else
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.dropsBelow) + " ");
returnString.append(String.valueOf(this.getBatteryLevel()) + " %");
break;
case usb_host_connection:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.connecting) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.disconnecting) + " ");
@ -1285,9 +1476,9 @@ public class Trigger
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.triggerUsb_host_connection));
break;
case pointOfInterest:
if(this.getPointOfInterest() != null)
if (this.getPointOfInterest() != null)
{
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.entering) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.leaving) + " ");
@ -1296,33 +1487,33 @@ public class Trigger
}
else
{
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.leaving) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.anyLocation));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.entering) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.anyLocation));
}
break;
case timeFrame:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.entering) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.leaving) + " ");
String repeat = ", " + Miscellaneous.getAnyContext().getResources().getString(R.string.noRepetition);
if(this.getTimeFrame().getRepetition() > 0)
if (this.getTimeFrame().getRepetition() > 0)
repeat = ", " + String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.repeatEveryXsecondsWithVariable), String.valueOf(this.getTimeFrame().getRepetition()));
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.triggerTimeFrame) + ": " + this.getTimeFrame().getTriggerTimeStart().toString() + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.until) + " " + this.getTimeFrame().getTriggerTimeStop().toString() + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.onDays) + " " + this.getTimeFrame().getDayList().toString() + repeat);
break;
case speed:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.exceeding) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.droppingBelow) + " ");
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.triggerSpeed) + ": " + String.valueOf(this.getSpeed()) + " km/h");
break;
case noiseLevel:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.exceeding) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.droppingBelow) + " ");
@ -1330,27 +1521,27 @@ public class Trigger
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.triggerNoiseLevel) + ": " + String.valueOf(this.getNoiseLevelDb()) + " dB");
break;
case wifiConnection:
String wifiDisplayName = "";
if(this.getTriggerParameter2().length() == 0)
String wifiDisplayName = "";
if (this.getTriggerParameter2().length() == 0)
wifiDisplayName += Miscellaneous.getAnyContext().getResources().getString(R.string.anyWifi);
else
wifiDisplayName += this.getTriggerParameter2();
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.connectedToWifi), wifiDisplayName));
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.disconnectedFromWifi), wifiDisplayName));
break;
case process_started_stopped:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.application) + " " + this.getProcessName() + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.is) + " ");
if(this.triggerParameter)
if (this.triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.started));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.stopped));
break;
case airplaneMode:
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.activated) + " ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deactivated) + " ");
@ -1358,7 +1549,7 @@ public class Trigger
break;
case roaming:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.roaming));
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.activated));
else
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.deactivated));
@ -1370,27 +1561,27 @@ public class Trigger
returnString.append(" ");
if(elements[1].equals(triggerPhoneCallDirectionAny))
if (elements[1].equals(triggerPhoneCallDirectionAny))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.with));
else if(elements[1].equals(triggerPhoneCallDirectionIncoming))
else if (elements[1].equals(triggerPhoneCallDirectionIncoming))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.from));
else if(elements[1].equals(triggerPhoneCallDirectionOutgoing))
else if (elements[1].equals(triggerPhoneCallDirectionOutgoing))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.to));
returnString.append(" ");
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny))
if (elements[2].equals(Trigger.triggerPhoneCallNumberAny))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.any) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.number));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.number) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.matching) + " " + elements[2]);
returnString.append(" ");
if(elements[0].equals(Trigger.triggerPhoneCallStateRinging))
if (elements[0].equals(Trigger.triggerPhoneCallStateRinging))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.ringing));
else if(elements[0].equals(Trigger.triggerPhoneCallStateStarted))
else if (elements[0].equals(Trigger.triggerPhoneCallStateStarted))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.started));
else if(elements[0].equals(Trigger.triggerPhoneCallStateStopped))
else if (elements[0].equals(Trigger.triggerPhoneCallStateStopped))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.stopped));
break;
@ -1410,18 +1601,18 @@ public class Trigger
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.featureNotInFdroidVersion));
}
catch(ClassNotFoundException e)
catch (ClassNotFoundException e)
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.featureNotInFdroidVersion));
}
break;
case bluetoothConnection:
String device = Miscellaneous.getAnyContext().getResources().getString(R.string.anyDevice);
if(bluetoothDeviceAddress.equals("<any>"))
if (bluetoothDeviceAddress.equals("<any>"))
{
device = Miscellaneous.getAnyContext().getResources().getString(R.string.any);
}
else if(bluetoothDeviceAddress.equals("<none>"))
else if (bluetoothDeviceAddress.equals("<none>"))
{
device = Miscellaneous.getAnyContext().getResources().getString(R.string.noDevice);
}
@ -1431,21 +1622,21 @@ public class Trigger
{
device = BluetoothReceiver.getDeviceByAddress(bluetoothDeviceAddress).getName() + " (" + this.bluetoothDeviceAddress + ")";
}
catch(NullPointerException e)
catch (NullPointerException e)
{
device = Miscellaneous.getAnyContext().getResources().getString(R.string.invalidDevice) + ": " + this.bluetoothDeviceAddress;
Miscellaneous.logEvent("w", "Trigger", device, 3);
}
}
if(bluetoothEvent.equals(BluetoothDevice.ACTION_ACL_CONNECTED) || bluetoothEvent.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))
if (bluetoothEvent.equals(BluetoothDevice.ACTION_ACL_CONNECTED) || bluetoothEvent.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))
{
if (this.triggerParameter)
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.bluetoothConnectionTo), device));
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.bluetoothDisconnectFrom), device));
}
else if(bluetoothEvent.equals(BluetoothDevice.ACTION_FOUND))
else if (bluetoothEvent.equals(BluetoothDevice.ACTION_FOUND))
{
if (this.triggerParameter)
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.bluetoothDeviceInRange), device));
@ -1455,7 +1646,7 @@ public class Trigger
break;
case headsetPlugged:
String type;
switch(headphoneType)
switch (headphoneType)
{
case 0:
type = Miscellaneous.getAnyContext().getResources().getString(R.string.headphoneSimple);
@ -1470,13 +1661,13 @@ public class Trigger
type = Miscellaneous.getAnyContext().getResources().getString(R.string.notSet);
break;
}
if(getTriggerParameter())
if (getTriggerParameter())
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.headsetConnected), type));
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.headsetDisconnected), type));
break;
case notification:
if(this.getTriggerParameter2().contains(triggerParameter2Split))
if (this.getTriggerParameter2().contains(triggerParameter2Split))
{
String[] params = getTriggerParameter2().split(triggerParameter2Split);
@ -1497,7 +1688,7 @@ public class Trigger
else
appString = "app " + app;
if(triggerParameter)
if (triggerParameter)
triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.postsNotification), appString));
else
triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.removedNotification), appString));
@ -1519,20 +1710,20 @@ public class Trigger
returnString.append(Miscellaneous.getAnyContext().getString(R.string.deviceIsInCertainOrientation));
break;
case profileActive:
if(triggerParameter)
if (triggerParameter)
returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.profileActive), getTriggerParameter2().split(Trigger.triggerParameter2Split)[0]));
else
returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.profileNotActive), getTriggerParameter2().split(Trigger.triggerParameter2Split)[0]));
break;
case musicPlaying:
if(triggerParameter)
if (triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getString(R.string.musicIsPlaying));
else
returnString.append(Miscellaneous.getAnyContext().getString(R.string.musicIsNotPlaying));
break;
case screenState:
String state;
switch(triggerParameter2)
switch (triggerParameter2)
{
case "0":
state = Miscellaneous.getAnyContext().getString(R.string.off);
@ -1543,11 +1734,68 @@ public class Trigger
case "2":
state = Miscellaneous.getAnyContext().getString(R.string.unlocked);
break;
case "3":
state = Miscellaneous.getAnyContext().getString(R.string.lockedWithoutSecurity);
break;
case "4":
state = Miscellaneous.getAnyContext().getString(R.string.lockedWithSecurity);
break;
default:
state = Miscellaneous.getAnyContext().getString(R.string.unknown);
}
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.screenIs), state));
break;
case deviceStarts:
// This type doesn't have an activate/deactivate equivalent
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deviceIsStarting) + ": " + String.valueOf(triggerParameter));
break;
case serviceStarts:
// This type doesn't have an activate/deactivate equivalent
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.serviceIsStarting) + ": " + String.valueOf(triggerParameter));
break;
case broadcastReceived:
if (triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.broadcastReceived));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.broadcastNotReceived));
returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.screenIs), state));
returnString.append(": " + triggerParameter2);
break;
case tethering:
if (triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.tetheringActive));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.tetheringNotActive));
returnString.append(" (" + Miscellaneous.getAnyContext().getResources().getString(R.string.type) + ": " + triggerParameter2 + ")");
break;
case subSystemState:
Trigger.subSystemStates desiredState = subSystemStates.valueOf(triggerParameter2);
switch (desiredState)
{
case wifi:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wifi));
break;
case bluetooth:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.bluetooth));
break;
}
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.is) + " ");
if (triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.activated));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deactivated));
break;
case checkVariable:
if (triggerParameter2.contains(triggerParameter2Split))
{
String[] parts = triggerParameter2.split(triggerParameter2Split);
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckString), parts[0], parts[1]));
}
else
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2));
break;
default:
returnString.append("error");
@ -1559,6 +1807,7 @@ public class Trigger
public static final String directionEquals = "eq";
public static final String directionContains = "ct";
public static final String directionNotContains = "nc";
public static final String directionStartsWith = "sw";
public static final String directionEndsWith = "ew";
public static final String directionNotEquals = "ne";
@ -1571,6 +1820,8 @@ public class Trigger
return Miscellaneous.getAnyContext().getString(R.string.directionStringEquals);
case directionContains:
return Miscellaneous.getAnyContext().getString(R.string.directionStringContains);
case directionNotContains:
return Miscellaneous.getAnyContext().getString(R.string.directionStringDoesNotContain);
case directionStartsWith:
return Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith);
case directionEndsWith:
@ -1588,6 +1839,8 @@ public class Trigger
return directionEquals;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringContains)))
return directionContains;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringDoesNotContain)))
return directionNotContains;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith)))
return directionStartsWith;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringEndsWith)))
@ -1612,11 +1865,7 @@ public class Trigger
public static String[] getTriggerTypesStringAsArray(Context context)
{
ArrayList<String> triggerTypesList = new ArrayList<String>();
/*for(int i=0; i<Trigger_Enum.values().length; i++)
{
triggerTypesList.add(Trigger_Enum.values()[i].getFullName(context));
}*/
for(Trigger_Enum triggerType : Trigger_Enum.values())
triggerTypesList.add(triggerType.getFullName(context));

View File

@ -160,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");
@ -178,9 +178,9 @@ public class XmlFileInterface
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");
@ -254,8 +254,6 @@ public class XmlFileInterface
else
serializer.text("null");
}
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.timeFrame)
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTimeFrame().toString());
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.speed)
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getSpeed()));
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.noiseLevel)
@ -633,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);
}
@ -645,7 +643,7 @@ public class XmlFileInterface
{
String path = readTag(parser, "notificationRingtone");
if(!path.equals("null"))
newProfile.setNotificationRingtone(new File(path));
newProfile.setNotificationRingtone(path);
else
newProfile.setNotificationRingtone(null);
}
@ -838,7 +836,6 @@ public class XmlFileInterface
private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException
{
/* FILE EXAMPE:
* *****************
* <Automation>

View File

@ -7,7 +7,6 @@ import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.jens.automation2.ActivityMainScreen;
@ -485,7 +484,6 @@ public class LocationProvider
}
}
public static void resetSpeedTimer(Calendar timeOfForcedLocationCheck)
{
if(speedTimerActive)

View File

@ -26,7 +26,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static Boolean wasConnected = false;
protected static String lastWifiSsid = "";
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;
@ -40,8 +40,9 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
if(newWifiSsid.length() > 0)
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
}
public static boolean isWifiListenerActive()
@ -51,7 +52,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static boolean mayCellLocationReceiverBeActivated()
{
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi;
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView;
}
@Override
@ -62,18 +63,12 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
// int state = -1;
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);
@ -94,8 +89,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 receiver a "wifi has been connected"-event.
This is technically wrong and not really any changed to when the screen was off. It has
to be filtered.
*/
}
else
{
@ -109,7 +110,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
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();
@ -125,7 +126,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
wasConnected = false;
Miscellaneous.logEvent("i", "WifiReceiver", String.format(context.getResources().getString(R.string.disconnectedFromWifi), getLastWifiSsid()) + " Switching to CellLocationChangedReceiver.", 3);
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
CellLocationChangedReceiver.startCellLocationChangedReceiver();
lastConnectedState = false;
findRules(AutomationService.getInstance());

View File

@ -19,14 +19,13 @@ 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;
private static boolean batteryReceiverActive = false;
private static IntentFilter batteryIntentFilter = null;
private static Intent batteryStatus = null;
private static BroadcastReceiver batteryInfoReceiverInstance = null;
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;
static BroadcastReceiver batteryInfoReceiverInstance = null;
public static void startBatteryReceiver(final AutomationService automationServiceRef)
{
@ -90,7 +89,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
@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;
@ -99,54 +98,49 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
if(intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
{
Log.i("Battery", "Low battery event");
Miscellaneous.logEvent("i", "Battery", "Low battery event", 5);
}
else
{
try
{
// Miscellaneous.logEvent("i", "BatteryReceiver", "Received battery event.");
// if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))
// {
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
// int scale = -1;
// int voltage = -1;
// int temp = -1;
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
this.actionBatteryLevel(context);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
// Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged));
switch(statusPlugged)
{
case BatteryManager.BATTERY_PLUGGED_AC:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
// Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.");
this.actionCharging(context);
break;
case BatteryManager.BATTERY_PLUGGED_USB:
this.actionUsbConnected(context);
break;
}
switch(status)
{
// case BatteryManager.BATTERY_STATUS_CHARGING:
// break;
case BatteryManager.BATTERY_STATUS_FULL:
// Toast.makeText(context, "Regular charging full", Toast.LENGTH_LONG).show();
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.");
this.actionCharging(context);
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
this.actionDischarging(context);
break;
}
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
// int scale = -1;
// int voltage = -1;
// int temp = -1;
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
this.actionBatteryLevel(context);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int statusPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
Miscellaneous.logEvent("i", "BatteryReceiver", "Status: " + String.valueOf(statusPlugged), 5);
switch(statusPlugged)
{
case BatteryManager.BATTERY_PLUGGED_AC:
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
this.actionCharging(context);
break;
case BatteryManager.BATTERY_PLUGGED_USB:
this.actionUsbConnected(context);
break;
}
switch(status)
{
case BatteryManager.BATTERY_STATUS_CHARGING:
case BatteryManager.BATTERY_STATUS_FULL:
Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
this.actionCharging(context);
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
this.actionDischarging(context);
break;
}
}
catch(Exception e)
{
@ -264,11 +258,13 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
}
}
}
@Override
public void startListener(AutomationService automationService)
{
BatteryReceiver.startBatteryReceiver(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
@ -292,4 +288,4 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
// actually monitores several
return new Trigger_Enum[] { Trigger_Enum.batteryLevel, Trigger_Enum.charging, Trigger_Enum.usb_host_connection };
}
}
}

View File

@ -300,4 +300,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;
}
}

View File

@ -0,0 +1,168 @@
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()));
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 };
}
}

View File

@ -14,6 +14,7 @@ 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;
@ -27,12 +28,10 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
{
private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance;
// private static Intent alarmIntent;
// private static PendingIntent alarmPendingIntent;
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)
{
@ -52,13 +51,9 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
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.findRuleCandidates(Trigger_Enum.timeFrame);
// ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
for(int i=0; i < allRulesWithNowInTimeFrame.size(); i++)
{
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
@ -77,23 +72,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
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);
int i=0;
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
@ -118,7 +97,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
Calendar calSet;
Time setTime;
TimeObject setTime;
if(oneTrigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
@ -161,7 +140,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
}
i++;
i=(int)System.currentTimeMillis();
i = (int)System.currentTimeMillis();
sdf.format(calSetWorkingCopy.getTime());
String.valueOf(i);
@ -264,11 +243,10 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
}
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
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);
@ -280,7 +258,8 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
for(int requestCode : requestCodeList)
{
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
if(alarmPendingIntent == null)
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent);
}
@ -316,7 +295,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
{
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false;
}
else
@ -387,7 +366,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
Time setTime;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
@ -403,8 +382,6 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// if(this.applies(null))
// {
// If the starting time is a day ahead remove 1 day.
if(calSet.getTimeInMillis() > now.getTimeInMillis())
calSet.add(Calendar.DAY_OF_MONTH, -1);
@ -419,11 +396,8 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
* Das war mal aktiviert. Allerdings: Die ganze Funktion liefert zurück, wenn die Regel NOCH nicht
* zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten.
*/
// if(trigger.checkDateTime(calSchedule.getTime(), false))
// {
return calSchedule;
// }
// }
}
else
Miscellaneous.logEvent("i", "DateTimeListener", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5);

View File

@ -34,17 +34,18 @@ public class DeviceOrientationListener implements SensorEventListener, Automatio
static int sensorValueCounter = 0;
// Gravity rotational data
private float gravity[];
float gravity[];
// Magnetic rotational data
private float magnetic[]; //for magnetic rotational data
private float accels[] = new float[3];
private float mags[] = new float[3];
private float[] values = new float[3];
float magnetic[]; //for magnetic rotational data
float accels[] = new float[3];
float mags[] = new float[3];
float[] values = new float[3];
boolean hasMagneticSensor=false;
// azimuth, pitch and roll
private float azimuth;
private float pitch;
private float roll;
float azimuth;
float pitch;
float roll;
boolean applies = false;
boolean flipped = false;
@ -91,7 +92,7 @@ public class DeviceOrientationListener implements SensorEventListener, Automatio
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);
hasMagneticSensor = sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
}
}
@ -129,6 +130,9 @@ public class DeviceOrientationListener implements SensorEventListener, Automatio
break;
}
if (!hasMagneticSensor)
mags=new float[]{1f,1f,1f};
if (mags != null && accels != null)
{
gravity = new float[9];

View File

@ -76,7 +76,6 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.headsetPlugged);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).getsGreenLight(context))
@ -104,7 +103,6 @@ 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);
}
}
@ -122,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;
}
@ -150,5 +147,4 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
{
return new Trigger_Enum[] { Trigger_Enum.headsetPlugged };
}
}
}

View File

@ -2,11 +2,10 @@ package com.jens.automation2.receivers;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.bluetooth.BluetoothDevice;
import android.app.PendingIntent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
@ -89,6 +88,11 @@ public class NotificationListener extends NotificationListenerService// implemen
{
lastNotification = convertNotificationToSimpleNotification(created, sbn);
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++)
{
@ -144,51 +148,6 @@ public class NotificationListener extends NotificationListenerService// implemen
return returnNotification;
}
/*@Override
public void startListener(AutomationService automationService)
{
if(instance == null)
instance = new NotificationListener();
if(notificationReceiverIntentFilter == null)
{
notificationReceiverIntentFilter = new IntentFilter();
notificationReceiverIntentFilter.addAction("android.service.notification.NotificationListenerService");
}
try
{
if(!listenerRunning)
{
Miscellaneous.logEvent("i", "NotificationListener", "Starting NotificationListener", 4);
listenerRunning = true;
AutomationService.getInstance().registerReceiver(instance, notificationReceiverIntentFilter);
}
}
catch(Exception ex)
{
Miscellaneous.logEvent("e", "BluetoothReceiver", "Error starting BluetoothReceiver: " + Log.getStackTraceString(ex), 3);
}
}
@Override
public void stopListener(AutomationService automationService)
{
}
@Override
public boolean isListenerRunning()
{
return false;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[0];
}*/
public static class SimpleNotification
{
boolean created;
@ -278,4 +237,35 @@ public class NotificationListener extends NotificationListenerService// implemen
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);
}
}

View File

@ -6,10 +6,15 @@ 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;
@ -22,8 +27,7 @@ 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;
@ -72,7 +76,76 @@ public class PhoneStatusListener implements AutomationListenerInterface
return currentState;
}
public static class IncomingCallsReceiver extends PhoneStateListener
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);
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.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)
@ -88,67 +161,42 @@ public class PhoneStatusListener implements AutomationListenerInterface
If the last call was outgoing the state has not changed to idle this is kind of a fake alert.
*/
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
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))
{
// This status update is actually for an outgoing call
setCurrentState(state);
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
int state = 99;
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
setLastPhoneNumber(incomingNumber);
switch(state)
switch(stateStr)
{
case TelephonyManager.CALL_STATE_IDLE:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
case "RINGING":
state = TelephonyManager.CALL_STATE_RINGING;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
case "IDLE":
state = TelephonyManager.CALL_STATE_IDLE;
break;
case TelephonyManager.CALL_STATE_RINGING:
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
case "OFFHOOK":
state = TelephonyManager.CALL_STATE_OFFHOOK;
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
{
// state != TelephonyManager.CALL_STATE_IDLE &&
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);
}
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.i("test", "test");
}
}
}
@ -175,12 +223,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
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++)
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);
ruleCandidates.get(i).activate(asInstance, false);
}
}
}
@ -205,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();
@ -215,8 +268,17 @@ public class PhoneStatusListener implements AutomationListenerInterface
if(!incomingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->incomingCallsReceiver", 4);
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
// 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((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
// }
incomingCallsReceiverActive = true;
}
@ -240,8 +302,15 @@ public class PhoneStatusListener implements AutomationListenerInterface
if(incomingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Stopping phoneStatusListener", 4);
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
// if(Build.VERSION.SDK_INT >= 31)
// {
// automationService.unregisterReceiver((IncomingCallsReceiverNew)incomingCallsReceiverInstance);
// }
// else
// {
TelephonyManager tm = (TelephonyManager) automationService.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
// }
incomingCallsReceiverActive = false;
}
@ -289,4 +358,4 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
return new Trigger_Enum[] { Trigger_Enum.phoneCall };
}
}
}

View File

@ -1,14 +1,18 @@
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.BatteryManager;
import android.util.Log;
import android.widget.Toast;
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;
@ -16,10 +20,13 @@ 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 screenState = -1; // initialize with a better value than this
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;
@ -27,9 +34,18 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
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)
if (screenStateReceiverInstance == null)
screenStateReceiverInstance = new ScreenStateReceiver();
return screenStateReceiverInstance;
@ -37,58 +53,60 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
public static void startScreenStateReceiver(final AutomationService automationServiceRef)
{
if(!screenStateReceiverActive)
if (!screenStateReceiverActive)
{
ScreenStateReceiver.automationServiceRef = automationServiceRef;
if(screenStateReceiverInstance == null)
if (screenStateReceiverInstance == null)
screenStateReceiverInstance = new ScreenStateReceiver();
if(screenStateIntentFilter == null)
if (screenStateIntentFilter == null)
{
screenStateIntentFilter = new IntentFilter();
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateIntentFilter.addAction(Intent.ACTION_USER_PRESENT);
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 (screenStateReceiverActive)
{
if(screenStateReceiverInstance != null)
if (screenStateReceiverInstance != null)
{
automationServiceRef.unregisterReceiver(screenStateReceiverInstance);
screenStateReceiverInstance = null;
}
screenStateReceiverActive = false;
}
}
public static boolean isScreenStateReceiverActive()
{
return screenStateReceiverActive;
}
public static int getScreenState()
public static int getScreenPowerState()
{
return screenState;
return screenPowerState;
}
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
public static int getCurrentChargingState()
public static int getScreenLockState()
{
return currentChargingState;
return screenLockState;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
@Override
public void onReceive(Context context, Intent intent)
{
@ -101,32 +119,65 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
try
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
ScreenStateReceiver.screenState = 0;
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))
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
ScreenStateReceiver.screenState = 1;
ScreenStateReceiver.screenPowerState = SCREEN_STATE_ON;
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT))
else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT))
{
ScreenStateReceiver.screenState = 2;
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)
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++)
for (int i = 0; i < ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).getsGreenLight(context))
if (ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@ -136,6 +187,7 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
{
ScreenStateReceiver.startScreenStateReceiver(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
@ -145,7 +197,7 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
public static boolean haveAllPermission()
{
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
}
@Override
@ -157,6 +209,66 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.screenState };
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);
}
}
}

View File

@ -11,12 +11,13 @@ import com.jens.automation2.Settings;
public class StartupIntentReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Settings.readFromPersistentStorage(context);
Miscellaneous.startupContext = context;
// Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
if(Settings.startServiceAtSystemBoot)

View File

@ -0,0 +1,151 @@
package com.jens.automation2.receivers;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
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.HashMap;
import java.util.Map;
public class SubSystemStateReceiver extends BroadcastReceiver implements AutomationListenerInterface
{
public static AutomationService automationServiceRef = null;
private static IntentFilter subSystemStateIntentFilter = null;
private static BroadcastReceiver subSystemStateReceiverInstance = null;
private static Intent subSystemStatusIntent = null;
private static boolean subSystemStateReceiverActive = false;
static SubSystemStateReceiver instance;
final static String stateBluetooth = "android.bluetooth.adapter.action.STATE_CHANGED";
final static String stateWifi = "android.net.wifi.STATE_CHANGE";
final static String connectivityBroadcast = "android.net.conn.CONNECTIVITY_CHANGE";
static Map<String, Boolean> stateMap = null;
@Override
public void onReceive(Context context, Intent intent)
{
if (intent == null)
return;
if (context == null)
return;
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Received: " + intent.getAction(), 3);
if(stateMap == null)
stateMap = new HashMap<>();
try
{
/*if (intent.getAction().equals(stateWifi) || intent.getAction().equals(connectivityBroadcast))
{
if(intent.hasExtra(WifiManager.EXTRA_WIFI_STATE))
{
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
if (wifiState == WifiManager.WIFI_STATE_ENABLED)
stateMap.put("wifi", true);
else if (wifiState == WifiManager.WIFI_STATE_DISABLED)
stateMap.put("wifi", false);
}
}
else if (intent.getAction().equals(stateBluetooth))
{
if(intent.hasExtra(BluetoothAdapter.EXTRA_STATE))
{
int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (bluetoothState == BluetoothAdapter.STATE_ON)
stateMap.put("bluetooth", true);
else if (bluetoothState == BluetoothAdapter.STATE_OFF)
stateMap.put("bluetooth", false);
}
}*/
if (intent.getAction().equals(stateWifi) || intent.getAction().equals(connectivityBroadcast) || intent.getAction().equals(stateBluetooth))
{
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.subSystemState);
for (int i = 0; i < ruleCandidates.size(); i++)
{
if (ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
else
{
Miscellaneous.logEvent("e", "SubSystemStateReceiver", "Unknown state received: " + intent.getAction(), 3);
}
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "SubSystemStateReceiver", "Error receiving screen state: " + e.getMessage(), 3);
}
}
public static SubSystemStateReceiver getInstance()
{
if(instance == null)
instance = new SubSystemStateReceiver();
return instance;
}
@Override
public void startListener(AutomationService automationService)
{
if (!subSystemStateReceiverActive)
{
automationServiceRef = automationService;
if (subSystemStateReceiverInstance == null)
subSystemStateReceiverInstance = new SubSystemStateReceiver();
if (subSystemStateIntentFilter == null)
{
subSystemStateIntentFilter = new IntentFilter();
subSystemStateIntentFilter.addAction(stateWifi);
subSystemStateIntentFilter.addAction(connectivityBroadcast);
subSystemStateIntentFilter.addAction(stateBluetooth);
}
subSystemStatusIntent = automationServiceRef.registerReceiver(subSystemStateReceiverInstance, subSystemStateIntentFilter);
subSystemStateReceiverActive = true;
}
}
@Override
public void stopListener(AutomationService automationService)
{
if (subSystemStateReceiverActive)
{
if (subSystemStateReceiverInstance != null)
{
automationServiceRef.unregisterReceiver(subSystemStateReceiverInstance);
subSystemStateReceiverInstance = null;
}
subSystemStateReceiverActive = false;
}
}
@Override
public boolean isListenerRunning()
{
return subSystemStateReceiverActive;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[]{Trigger.Trigger_Enum.subSystemState};
}
}

View File

@ -0,0 +1,205 @@
package com.jens.automation2.receivers;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;
import com.jens.automation2.ActivityManageTriggerTethering;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class TetheringReceiver extends android.content.BroadcastReceiver implements AutomationListenerInterface
{
public static AutomationService automationServiceRef = null;
private static boolean receiverActive = false;
private static TetheringReceiver receiverInstance = null;
private static IntentFilter intentFilter = null;
private static List<String> lastTetheringTypes = null;
private static boolean tetheringActive = false;
public static List<String> getLastTetheringTypes()
{
return lastTetheringTypes;
}
public static TetheringReceiver getInstance()
{
if(receiverInstance == null)
receiverInstance = new TetheringReceiver();
return receiverInstance;
}
public static boolean isTetheringActive()
{
return tetheringActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "TetheringReceiver", "Received " + intent.getAction(), 5);
/*
DETECT BY DATA DELIVERED IN INTENT
*/
// if(intent.getAction().equals("android.net.conn.TETHER_STATE_CHANGED"))
// {
String searchArray = null;
if (Build.VERSION.SDK_INT >= 26)
searchArray = "tetherArray";
else
searchArray = "activeArray";
for (String key : intent.getExtras().keySet())
{
// Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
Object ob = intent.getExtras().get(key);
if (key.equals(searchArray) && ob instanceof ArrayList)
{
if (((ArrayList<String>) ob).size() > 0)
{
tetheringActive = true;
if (lastTetheringTypes == null)
lastTetheringTypes = new ArrayList<>();
else
lastTetheringTypes.clear();
for (String adapterName : (ArrayList<String>) ob)
{
if (adapterName.contains("wlan"))
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeWifi);
else if (adapterName.contains("bluetooth"))
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeBluetooth);
else if (adapterName.contains("rndis"))
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeUsb);
else if (adapterName.contains("ndis"))
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeCable);
}
}
else
tetheringActive = false;
}
// Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
}
// }
// else if(intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE"))
/*
DETECT BY CHECKING ALL NETWORK INTERFACES
*/
// {
/*try
{
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); )
{
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); )
{
InetAddress inetAddress = enumIpAddr.nextElement();
if (!intf.isLoopback())
{
if (intf.getName().contains("rndis"))
{
Miscellaneous.logEvent("i", "TetheringReceiver", "Tethering on interface " + intf.getName() + " seems to be active.", 4);
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeUsb);
tetheringActive = true;
}
else if (intf.getName().contains("ndis"))
{
Miscellaneous.logEvent("i", "TetheringReceiver", "Tethering on interface " + intf.getName() + " seems to be active.", 4);
lastTetheringTypes.add(ActivityManageTriggerTethering.tetheringTypeCable);
tetheringActive = true;
}
}
}
}
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "TetheringReceiver", Log.getStackTraceString(e), 1);
}*/
// }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.tethering);
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)
{
if(!receiverActive)
{
TetheringReceiver.automationServiceRef = automationService;
if(receiverInstance == null)
receiverInstance = new TetheringReceiver();
if(intentFilter == null)
{
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.TETHER_STATE_CHANGED");
// intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
}
try
{
automationServiceRef.registerReceiver(receiverInstance, intentFilter);
receiverActive = true;
}
catch(Exception e)
{
/*
We might be confronted with permission issues here.
*/
Miscellaneous.logEvent("e", "TetheringReceiver", Log.getStackTraceString(e), 1);
receiverActive = false;
}
}
}
@Override
public void stopListener(AutomationService automationService)
{
if(receiverActive)
{
if(receiverInstance != null)
{
automationServiceRef.unregisterReceiver(receiverInstance);
receiverInstance = null;
}
receiverActive = false;
}
}
@Override
public boolean isListenerRunning()
{
return receiverActive;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.tethering};
}
}

View File

@ -14,14 +14,13 @@ import com.jens.automation2.Trigger.Trigger_Enum;
public class TimeZoneListener extends BroadcastReceiver implements AutomationListenerInterface
{
private static TimeZoneListener timeZoneListenerInstance = null;
protected static boolean timeZoneListenerActive = false;
protected static boolean timezoneListenerActive = false;
protected static AutomationService automationServiceRef = null;
protected static IntentFilter timeZoneListenerIntentFilter = null;
protected static IntentFilter timezoneListenerIntentFilter = null;
public static boolean isTimeZoneListenerActive()
public static boolean isTimezoneListenerActive()
{
return timeZoneListenerActive;
return timezoneListenerActive;
}
public static void startTimeZoneListener(AutomationService automationService)
@ -33,19 +32,19 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
try
{
if(!timeZoneListenerActive && Rule.isAnyRuleUsing(Trigger_Enum.timeFrame))
if(!timezoneListenerActive && Rule.isAnyRuleUsing(Trigger_Enum.timeFrame))
{
Miscellaneous.logEvent("i", "TimeZoneListener", "Starting TimeZoneListener", 4);
timeZoneListenerActive = true;
timezoneListenerActive = true;
if(timeZoneListenerIntentFilter == null)
if(timezoneListenerIntentFilter == null)
{
timeZoneListenerIntentFilter = new IntentFilter();
timeZoneListenerIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
timeZoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
timezoneListenerIntentFilter = new IntentFilter();
timezoneListenerIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
timezoneListenerIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
}
automationService.registerReceiver(timeZoneListenerInstance, timeZoneListenerIntentFilter);
automationService.registerReceiver(timeZoneListenerInstance, timezoneListenerIntentFilter);
}
}
catch(Exception ex)
@ -57,11 +56,11 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
{
try
{
if(timeZoneListenerActive)
if(timezoneListenerActive)
{
Miscellaneous.logEvent("i", "TimeZoneListener", "Stopping TimeZoneListener", 4);
automationServiceRef.unregisterReceiver(timeZoneListenerInstance);
timeZoneListenerActive = false;
timezoneListenerActive = false;
}
}
catch(Exception ex)
@ -81,7 +80,7 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
}
else if(action.equals(Intent.ACTION_TIME_CHANGED))
{
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 4);
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 3);
DateTimeListener.reloadAlarms();
}
}
@ -104,7 +103,7 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
@Override
public boolean isListenerRunning()
{
return TimeZoneListener.isTimeZoneListenerActive();
return TimeZoneListener.isTimezoneListenerActive();
}
@Override
public Trigger_Enum[] getMonitoredTrigger()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -83,6 +83,12 @@
android:layout_margin="@dimen/default_margin"
android:background="#aa000000" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/emailPretext" />
<CheckBox
android:id="@+id/chkShareConfigAndLog"
android:layout_width="wrap_content"
@ -94,8 +100,14 @@
android:id="@+id/bSendEmailToDev"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/sendEmailToDev" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/logsExplanation" />
<ImageView
android:layout_width="match_parent"
android:layout_span="2"

View File

@ -37,6 +37,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/generalText" />
</LinearLayout>
<LinearLayout

View File

@ -76,6 +76,14 @@
android:text="@string/comparisonCaseInsensitive"
android:layout_marginBottom="@dimen/default_margin"/>
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/regularExpressionsIfEquals"
android:layout_marginBottom="@dimen/default_margin"/>
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">
@ -111,6 +119,22 @@
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/comparisonCaseInsensitive"
android:layout_marginBottom="@dimen/default_margin"/>
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/regularExpressionsIfEquals"
android:layout_marginBottom="@dimen/default_margin"/>
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">
@ -141,6 +165,69 @@
</TableRow>>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<TableRow>
<RadioGroup>
<RadioButton
android:id="@+id/rbNotificationDismissSimple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/simplyDismissNotification" />
<RadioButton
android:id="@+id/rbNotificationDismissButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clickNotificationButton" />
</RadioGroup>
<EditText
android:layout_gravity="bottom"
android:id="@+id/etNotificationDismissalButtonText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:inputType="text" />
</TableRow>
<TableRow>
<TextView />
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/comparisonCaseInsensitive"
android:layout_marginBottom="@dimen/default_margin"/>
</TableRow>
<TableRow>
<TextView />
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/mayUseRegularExpressions"
android:layout_marginBottom="@dimen/default_margin"/>
</TableRow>
</TableLayout>
<Button

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textToCopy" />
<EditText
android:id="@+id/etCopyToClipboard"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textShortMessage|textMultiLine" >
</EditText>
<TextView
android:id="@+id/tvTextMessageAnnotations"
android:layout_width="match_parent"
android:layout_height="0dip"
android:text="@string/textMessageAnnotations" />
<TextView
android:id="@+id/tvLegend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/urlLegend" />
<Button
android:id="@+id/bSaveCopyToClipboard"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/startPhoneCall"/>
<TextView
android:id="@+id/tvMakePhoneCallExplanation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/makePhoneCallExplanation1" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/phoneNumber" />
<EditText
android:id="@+id/etTargetPhoneNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone"/>
</TableRow>
</TableLayout>
<Button
android:id="@+id/bActionMakePhoneCallSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/runExecutable" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/runExecutableExplanation" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="1">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/runAsRoot" />
<CheckBox
android:id="@+id/chkRunExecAsRoot"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</CheckBox>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/path" />
<EditText
android:id="@+id/etRunExecutablePath"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri" >
</EditText>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/parameters" />
<EditText
android:id="@+id/etRunExecutableParameters"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text" >
</EditText>
</TableRow>
</TableLayout>
<Button
android:id="@+id/bChooseExecutable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chooseExecutable" />
<ScrollView
android:layout_marginTop="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvLegend"
android:layout_width="match_parent"
android:layout_height="0dip"
android:text="@string/urlLegend" />
</ScrollView>
<Button
android:id="@+id/bSaveActionRunExec"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/sendBroadcast" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/broadcastExplanation" />
<TextView
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Broadcast:" />
<EditText
android:id="@+id/etBroadcastToSend"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/bBroadcastSendShowSuggestions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/broadcastsShowSuggestions" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/addParameters" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_span="2"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/intentDataComment" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/parameterType" />
<Spinner
android:id="@+id/spinnerParameterType"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvCurrentNfcIdValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/parameterName" />
<EditText
android:id="@+id/etParameterName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/parameterValue" />
<EditText
android:id="@+id/etParameterValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/bAddIntentPair"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/addIntentValue" />
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
<ListView
android:id="@+id/lvIntentPairs"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="115dp"
android:layout_marginBottom="@dimen/default_margin" />
<Button
android:id="@+id/bSaveSendBroadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -41,6 +41,32 @@
<requestFocus />
</EditText>
<TextView
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/messageType" />
<RadioGroup
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbMessageTypeSms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/sms" />
<RadioButton
android:id="@+id/rbMessageTypeMms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mms" />
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -67,6 +93,23 @@
android:layout_height="wrap_content"
android:text="@string/urlLegend" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attachment" />
<TextView
android:id="@+id/tvSendMmsFileAttachment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bMmsAttachment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="@string/chooseFile" />
<Button
android:id="@+id/bSaveSendTextMessage"
android:layout_marginTop="15dp"

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/setVariable"
android:textSize="25dp"
android:layout_marginBottom="@dimen/default_margin" />
<TableLayout
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow>
<TextView
android:text="@string/VariableKey"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/etVariableSetKey"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text" />
</TableRow>
<TableRow>
<TextView
android:text="@string/variableValue"
android:layout_marginRight="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/etVariableSetValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/setVariableExplanation" />
<Button
android:id="@+id/bSaveVariable"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -2,13 +2,22 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="10dp" >
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/actionSpeakText" />
<TextView
android:id="@+id/tvRuleTitle"
android:layout_width="wrap_content"
@ -40,7 +49,7 @@
</ScrollView>
<Button
android:id="@+id/bSaveTriggerUrl"
android:id="@+id/bSaveSpeakText"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -129,6 +129,12 @@
android:layout_height="wrap_content"
android:text="@string/startAppBySendBroadcast" />
<RadioButton
android:id="@+id/rbStartAppByService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/startAppByStartService" />
</RadioGroup>
</TableRow>

View File

@ -110,7 +110,7 @@
</ScrollView>
<Button
android:id="@+id/bSaveTriggerUrl"
android:id="@+id/bSaveSpeakText"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/keepDeviceAwake" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/direction" />
<RadioGroup>
<RadioButton
android:id="@+id/rbWakeLockActivate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/activate" />
<RadioButton
android:id="@+id/rbWakeLockDeactivate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/deactivate" />
</RadioGroup>
</TableRow>
<TableRow>
<TextView
android:text="@string/wakeLockExplanation"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_span="2"
android:layout_marginVertical="@dimen/default_margin" />
</TableRow>
<TableRow>
<TextView
android:text="@string/wakeLockTimeout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/chkWakeLockTimeout"
android:text=""
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/duration" />
<EditText
android:id="@+id/etWakeLockDuration"
android:inputType="number"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/bSaveWakelock"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/actionSetWifi"/>
<TextView
android:id="@+id/tvWifiExplanation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wifiExplanation1" />
<TextView
android:id="@+id/tvWifiExplanation2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/wifiExplanation2" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/runAsRoot" />
<CheckBox
android:id="@+id/chkWifiRunAsRoot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/runAsRoot" />
</TableRow>
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/state" />
<RadioGroup
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbActionWifiOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/on" />
<RadioButton
android:id="@+id/rbActionWifiOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/off" />
</RadioGroup>
</TableRow>
</TableLayout>
<Button
android:id="@+id/bActionWifiSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -57,7 +57,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberSigned" />
android:inputType="text" />
</TableRow>
@ -78,7 +78,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberSigned" />
android:inputType="text" />
</TableRow>
<TableRow

View File

@ -29,6 +29,14 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="10dp" >
<TextView
android:id="@+id/tvBluetoothNotPresentNotice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/deviceDoesNotHaveBluetooth" />
<RadioGroup
android:layout_width="match_parent"

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/broadcastReceivedTitle" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/explanationBroadcastTrigger" />
<TextView
android:id="@+id/tvBroadcastUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin"
android:text="@string/broadcastListUrl" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbBroadcastReceived"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/broadcastReceived" />
<RadioButton
android:id="@+id/rbBroadcastNotReceived"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/broadcastNotReceived" />
</RadioGroup>
<EditText
android:id="@+id/etBroadcastTriggerAction"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bBroadcastShowSuggestions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/broadcastsShowSuggestions" />
<Button
android:id="@+id/bSaveTriggerBroadcast"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/checkVariable"/>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/VariableKey" />
<EditText
android:id="@+id/etVariableKeyTrigger"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/variableValue" />
<EditText
android:id="@+id/etVariableValueTrigger"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/checkVariableExplanation" />
<Button
android:id="@+id/bTriggerVariableSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -96,6 +96,7 @@
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<TextView
android:gravity="center"
android:layout_width="match_parent"
@ -104,6 +105,14 @@
android:text="@string/comparisonCaseInsensitive"
android:layout_marginBottom="@dimen/default_margin"/>
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/regularExpressionsIfEquals"
android:layout_marginBottom="@dimen/default_margin"/>
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/subSystemState" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/rbSubSystemStateWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/wifi" />
<RadioButton
android:id="@+id/rbSubSystemStateBluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bluetooth" />
</RadioGroup>
<ImageView
android:layout_width="match_parent"
android:layout_span="2"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/rbSubSystemStateEnabled"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activated" />
<RadioButton
android:id="@+id/rbSubSystemStateDisabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/deactivated" />
</RadioGroup>
<Button
android:id="@+id/bSubSystemStateSave"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/tetheringState"/>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/state" />
<RadioGroup
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbTetheringOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/on" />
<RadioButton
android:id="@+id/rbTetheringOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/off" />
</RadioGroup>
</TableRow>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
<TableRow>
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/type" />
<RadioGroup>
<RadioButton
android:id="@+id/rbTetheringTypeAny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/any" />
<RadioButton
android:id="@+id/rbTetheringTypeWifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wifi" />
<RadioButton
android:visibility="gone"
android:id="@+id/rbTetheringTypeBluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bluetooth" />
<RadioButton
android:id="@+id/rbTetheringTypeUsb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/usb" />
<RadioButton
android:id="@+id/rbTetheringTypeCable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cable" />
</RadioGroup>
</TableRow>
</TableLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/tetheringBluetoothNotPossible" />
<Button
android:id="@+id/bTriggerTetheringSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -71,13 +71,20 @@
android:layout_margin="10dp"
android:background="#aa000000" />
<TextView
android:id="@+id/tvCurrentNfcIdValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/timeFrameWhichDays"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvCurrentNfcIdValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/timeFrameWhichDays"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvDaysHint"
android:layout_marginVertical="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/red" />
<CheckBox
android:id="@+id/checkMonday"
android:layout_width="wrap_content"

View File

@ -47,6 +47,19 @@
</TableRow>
<TableRow>
<TextView
android:id="@+id/tvWifiTriggerNameLocationNotice"
android:layout_span="2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="@color/red"
android:text="@string/locationRequiredToDetermineWifiName"
android:layout_marginVertical="@dimen/default_margin"
android:visibility="gone" />
</TableRow>
<TableRow>
<TextView
@ -62,6 +75,16 @@
</TableRow>
<TableRow>
<TextView />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mayUseRegularExpressions"/>
</TableRow>
<TableRow>
<Button
@ -81,7 +104,7 @@
</TableLayout>
<Button
android:id="@+id/btriggerWifiSave"
android:id="@+id/bTriggerWifiSave"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -59,6 +59,13 @@
android:entries="@array/tabsPlacementOptions"
android:entryValues="@array/tabsPlacementOptionsValues" />
<ListPreference
android:key="displayLanguage"
android:title="@string/displayLanguage"
android:summary="@string/displayLanguageSummary"
android:entries="@array/displayLanguageOptions"
android:entryValues="@array/displayLanguageValues" />
<CheckBoxPreference
android:key="executeRulesAndProfilesWithSingleClick"
android:title="@string/executeRulesAndProfilesWithSingleClickTitle" />
@ -74,7 +81,12 @@
android:title="@string/displayNewsOnMainScreen"
android:summary="@string/displayNewsOnMainScreenDescription" />
</PreferenceCategory>
<CheckBoxPreference
android:key="showToasts"
android:title="@string/showToastsForEvents"
android:summary="@string/showToastsForEventsSummary" />
</PreferenceCategory>
<PreferenceCategory
android:summary="@string/soundSettings"

View File

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="languageSystemDefault">System Standard</string>
<string name="languageEnglish">Englisch</string>
<string name="languageGerman">Deutsch</string>
<string name="languageItalian">Italienisch</string>
<string name="languageSpanish">Spanisch</string>
<string name="languageDutch">Niederländisch</string>
<string name="languageRussian">Russisch</string>
<string name="languageFrench">Französisch</string>
<string name="ruleActivate">Aktiviere Regel %1$s</string>
<string name="profileActivate">Aktiviere Profil %1$s</string>
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umkehrmodus</string>
@ -57,7 +65,7 @@
<string name="end">Ende</string>
<string name="save">Speichern</string>
<string name="urlToTrigger">URL, die ausgelöst werden soll:</string>
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (&lt; Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung</string>
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (&lt; Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
<string name="wifi">WLAN</string>
<string name="activating">Aktiviere</string>
<string name="deactivating">Deaktiviere</string>
@ -112,7 +120,7 @@
<string name="soundSettings">Ton Einstellungen</string>
<string name="showHelp">Hilfe</string>
<string name="rules">Regeln</string>
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.</string>
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.\nDie Begriffe Auslöser und Bedingung werden synonym verwendet. Alle von ihnen sind Bedingungen, aber die letzte, die ihren erforderlichen Wert erfüllt, könnte als Auslöser bezeichnet werden, da sie das letzte Teil des Puzzles ist, um eine Regel auszuführen.</string>
<string name="timeframes">Zeiträume</string>
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
@ -270,7 +278,8 @@
<string name="phoneCall">Telefongespräch</string>
<string name="with">mit</string>
<string name="phoneNumber">Telefonnummer</string>
<string name="enterPhoneNumber">Geben Sie eine Telefonnummer ein. Leer lassen für irgendeine Nummer.</string>
<string name="enterPhoneNumberBlankForAny">Geben Sie eine Telefonnummer ein. Leer lassen für irgendeine Nummer.</string>
<string name="enterPhoneNumber">Geben Sie eine Telefonnummer ein.</string>
<string name="phoneDirection">Wählen Sie die\nGesprächsrichtung</string>
<string name="any">egal</string>
<string name="incoming">eingehend</string>
@ -413,7 +422,7 @@
<string name="volumeTest">Lautstärkekalibrierung</string>
<string name="volumeCalibrationExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
<string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie die Regel manuell ausführen, um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken "immer erlauben" setzen. Ansonsten wird die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen.</string>
<string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string>
<string name="phoneNrReplacementError">Die letzte Telefonnummer konnte nicht in die Variable integriert werden. Sie liegt mir nicht vor.</string>
<string name="username">Benutzername</string>
@ -511,7 +520,7 @@
<string name="googleLocationChicaneryOld">Diese Anwendung sammelt Positionsdaten, um festzustellen, ob Sie sich gerade an einem der Orte aufhalten, die Sie definiert haben. Außerdem wird es benutzt, um Ihre Geschwindigkeit zu ermitteln, falls Sie diese in Regeln verwenden. Das wird auch dann gemacht, wenn das Programm nicht im Vordergrund ist (aber nur, wenn der Dienst aktiv ist).</string>
<string name="error">Fehler</string>
<string name="featureNotInFdroidVersion">Diese Funktion basiert auf nicht-freier Software (Google Bibliotheken). Daher ist sie in der F-Droid Version nicht verfügbar.</string>
<string name="settingsReferringToRestrictedFeatures">Ihre Einstellungen und Regeln verwenden derzeit nicht-freie Funktionen (Google Bibliotheken). Diese sind in der F-Droid Version nicht funktionsfähig. Das schließt die Erkennung Ihrer gegenwärtigen körperlichen Aktivität ein.</string>
<string name="settingsReferringToRestrictedFeaturesInFdroid">Ihre Einstellungen und Regeln verwenden derzeit nicht-freie Funktionen (Google Bibliotheken). Diese sind in der F-Droid Version nicht funktionsfähig. Das schließt die Erkennung Ihrer gegenwärtigen körperlichen Aktivität ein.</string>
<string name="displayNewsOnMainScreen">Nachrichten auf dem Hauptbildschirm anzeigen</string>
<string name="displayNewsOnMainScreenDescription">Nachrichten ausschließlich über diese Anwendung, wir sprechen von 1-2 pro Jahr, nicht mehr.</string>
<string name="newsOptIn">Möchten Sie wichtige Nachrichten über diese Anwendung auf dem Hauptbildschirm angezeigt bekommen? Diese werden von der Webseite des Entwicklers heruntergeladen. Es gibt keine aufdringliche Benachrichtigung, etc., lediglich eine stille Anzeige auf dem Hauptbildschirm.</string>
@ -519,7 +528,7 @@
<string name="notification">Benachrichtigung</string>
<string name="title">Titel</string>
<string name="text">Text</string>
<string name="anyApp">Irgendeine Anwendung</string>
<string name="anyApp">irgendeine Anwendung</string>
<string name="postsNotification">%1$s zeigt eine Benachrichtung an</string>
<string name="removedNotification">Benachrichtigung von %1$s wurde entfernt</string>
<string name="notificationAppears">Benachrichtigung wird angezeigt</string>
@ -557,7 +566,7 @@
<string name="noFilesImported">Keine Dateien konnten importiert werden.</string>
<string name="notAllFilesImported">Nicht alle passenden Dateien konnten importiert werden.</string>
<string name="openExamplesPage">Webseite mit Beispielen öffnen</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben, aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben (des Anrufpartners), aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
<string name="prefsImportError">Fehler beim Importieren der Einstellungen.</string>
<string name="rulesImportedSuccessfully">Regeln und Orte wurden erfolgreich importiert.</string>
<string name="rulesImportError">Fehler beim Importieren der Regeln.</string>
@ -667,7 +676,7 @@
<string name="closeNotifications">Benachrichtigung(en) schließen</string>
<string name="comparisonCaseInsensitive">Groß-/Kleinschreibung ist egal.</string>
<string name="notificationCloseActionExplanation">Wenn Sie keine Kriterien angeben, werden ALLE Benachrichtigungen geschlossen. Es wird also empfohlen, zumindest eine Anwendung zu spezifizieren und/oder Titel oder Text anzugeben.</string>
<string name="profileWarning">Die Einstellungen, die Sie hier vornehmen, können dazu führen, dass Sie bestimmte Dinge auf Ihrem Telefon nicht mehr mitbekommen. Sie können sogar Ihren Wecker zum Schweigen bringen. Was auch immer Sie hier einstellen - es wird empfohlen, es zu testen.</string>
<string name="profileWarning">Die Einstellungen, die Sie hier vornehmen, können dazu führen, dass Sie bestimmte Dinge auf Ihrem Telefon nicht mehr mitbekommen. Sie können sogar Ihren Wecker zum Schweigen bringen. Was auch immer Sie hier einstellen - es wird empfohlen, daß Sie es testen - auch nach Android Updates.</string>
<string name="ifString">falls</string>
<string name="pleaseSelectActionValue">Bitte wählen Sie eine Aktion!</string>
<string name="android.permission.MEDIA_CONTENT_CONTROL">Medien steuern</string>
@ -688,7 +697,7 @@
<string name="screenIs">Bildschirm ist %1$s</string>
<string name="sendEmailToDev">Email an Entwickler schicken</string>
<string name="controlCenter">Steuerungszentrale</string>
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.</string>
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.\nViele Fragen können nicht einfach gleich beantwortet werden, sondern erfordern eine technische Prüfung. Haben Sie also bitte etwas Geduld.</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Aufgrund Google\'s unendlicher Weisheit, ist die letzte Android Version, mit der diese Funktion noch funktioniert, die Version %1$s. Sie können es hier einrichten, aber vermutlich wird es keine Auswirkung haben.</string>
<string name="musicPlaying">Musik läuft</string>
<string name="selectParameters">Wählen Sie die Parameter</string>
@ -700,4 +709,91 @@
<string name="locationNotWorkingOn12">Das Abrufen des Standorts scheint unter Android 12 derzeit nicht zu funktionieren. Wenn es bei Ihnen nicht klappt, tut mir das leid. Ich werde versuchen die Ursache zu beheben, sobald mir die Ursache bekannt ist. Wenn der Donut bei Ihnen also nicht aufhört sich zu drehen, wissen Sie warum.</string>
<string name="profileXrequiresThis">Profil \"%1$s\" benötigt dies.</string>
<string name="lastProfile">Letztes Profil:</string>
<string name="queryAllPackages">Liste von installierten Anwendungen auslesen</string>
<string name="timeFrameDaysHint">Wenn Sie ein Zeitfenster verwenden, das sich über Mitternacht erstreckt, müssen Sie auch den Folgetag auswählen, wenn der Auslöser auch nach Mitternacht noch auslösen soll.</string>
<string name="featureNotInGooglePlayVersion">Diese Funktion ist in der Google Play-Version nicht mehr verfügbar.\n\nHin und wieder schikaniert Google Entwickler. Wenn Sie bestimmte Funktionen weiterhin verwenden möchten, müssen Sie Unterlagen einreichen. Leider besteht eine 99% ige Chance, dass der Papierkram abgelehnt wird. Es ist so ziemlich wie im Asterix-Comic/Film.\n\nIch habe in der Vergangenheit Wochen damit verbracht, mit ihnen über solche Fälle zu streiten, aber ich bekam immer wieder Ablehnungen - entweder von Bots oder von Leuten, die ungefähr so intelligent sind wie Bots. Ich kann mich dann nur entscheiden, ob die App vollständig aus dem Play Store fliegen soll oder die Funktion aus der Play Store Version entfernen.\n\nBitte erwägen Sie, die APK-Version von meiner Website oder die von F-Droid zu verwenden, wenn Sie diese Funktionen benötigen.</string>
<string name="startActivityInsertManually">Diese Einschränkung betrifft nur die Auswahl einer App, nicht den eigentlichen Start. So können Sie den Namen einer Anwendung immer noch manuell eingeben, falls Sie ihn kennen.</string>
<string name="serviceStarts">Dienst startet</string>
<string name="deviceStarts">Gerät startet</string>
<string name="deviceIsStarting">Gerät startet gerade</string>
<string name="serviceIsStarting">Dienst startet gerade</string>
<string name="broadcastReceived">Broadcast empfangen</string>
<string name="broadcastNotReceived">Broadcast nicht empfangen</string>
<string name="broadcastReceivedTitle">Broadcast empfangen</string>
<string name="broadcastsShowSuggestions">Vorschläge anzeigen</string>
<string name="selectBroadcast">Broadcast auswählen</string>
<string name="lockedWithoutSecurity">gesperrt (nur wischen, keine PIN, etc.)</string>
<string name="lockedWithSecurity">gesperrt (mit PIN, etc.)</string>
<string name="lockedCommentScreenMustBeOff">Jeglicher Sperrzustand wird nur erkannt werden, wenn gleichzeitig der Bildschirm aus ist.</string>
<string name="emailPretext">Wenn Sie ein Problem, einen Vorschlag oder eine Frage haben, schreiben Sie bitte auch etwas in die Email. Senden Sie mir nicht einfach die Dateien mit dem Standard-Mailtext. Ich werde solche Nachrichten ignorieren, sollten wir nicht bereits in einer Konversation sein.</string>
<string name="sendBroadcast">Broadcast verschicken</string>
<string name="enterBroadcast">Geben Sie eine Aktion für den Broadcast ein.</string>
<string name="broadcastExplanation">Diese Aktion erlaubt es, einen Broadcast über das Nachrichtensystem von Android zu verschicken. Das ist für den Benutzer nicht sichtbar, aber Anwendungen, die sich für bestimmte Broadcasts registriert haben, können darauf reagieren.</string>
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
<string name="logsExplanation">Um eine unnötige Abnutzung Ihres Speichers zu vermeiden, werden Protokolle standardmäßig nicht gespeichert. Wenn Sie also ein Problem haben, aktivieren Sie bitte zuerst die Protokollierungseinstellungen und setzen Sie den Protokollpegel auf 5. Reproduzieren Sie dann das Problem. Erst dann können Protokolle angehängt werden.</string>
<string name="directionStringDoesNotContain">enthält nicht</string>
<string name="path">Pfad</string>
<string name="runExecutable">Programm/Script ausführen</string>
<string name="parameters">Parameter</string>
<string name="chooseExecutable">Datei auswählen</string>
<string name="runAsRoot">Als root ausführen</string>
<string name="selectValidExecutable">Wählen Sie eine gültige ausführbare Datei aus.</string>
<string name="fileNotExecutable">Diese Datei ist nicht ausführbar.</string>
<string name="usingRoot">als root</string>
<string name="tetheringActive">Tethering ist aktiv</string>
<string name="tetheringNotActive">Tethering ist nicht aktiv</string>
<string name="tetheringState">Tethering Status</string>
<string name="wifiExplanation2">Während der Flugmodus aktiv ist, kann WLAN nur von Anwendungen ein- oder ausgeschaltet werden, wenn root-Rechte dafür verwendet werden.</string>
<string name="wifiExplanation1">Anwendungen, die auf Android Q oder höher ausgerichtet sind, können WLAN nicht mehr ein- oder ausschalten. Daran ist Google schuld, nicht ich.\n\nSie können diese Einschränkung umgehen, indem Sie Ihr Gerät rooten und die Checkbox unten aktivieren. Alternativ laden Sie sich diese Anwendung von F-Droid oder meiner Webseite herunter. In diesen Versionen bin ich nicht gezwungen, die Anwendungen auf die neuesten API Level zu unterstützen.</string>
<string name="runExecutableExplanation">Sie können hier ein Skript oder eine ausführbare Datei auswählen, die als Aktion ausgeführt wird.\n\nEs gibt aber einige Voraussetzungen, mit denen Sie sich selbst auseinandersetzen müssen. Google hat es sehr schwierig gemacht, etwas anderes als normale Android-Anwendungen auszuführen.\n\n1. Das Skript muss als ausführbar markiert sein. Auf einem normalen Android-System (ohne root) ist dies eigentlich der schwierige Teil.\n\n2. Das bedeutet auch, dass Automation in der Lage sein muß, die Datei auszuführen, nicht nur der Besitzer oder die Gruppe.\n\n3. Falls es sich um ein Skript handelt, muß im Header des Scripts eine gültige Shell angegeben sein.\n\nFalls Sie die oben genannten Anforderungen nicht erfüllen können, können Sie alternativ versuchen, eine Shell als tatsächliche ausführbare Datei (z. B. /system/bin/sh) und Ihr Skript als Parameter anzugeben. Das hat für mindestens einen Benutzer funktioniert.</string>
<string name="regularExpressionsIfEquals">Falls \"ist gleich\" ausgewählt ist, können Sie reguläre Ausdrücke eingeben.</string>
<string name="enter_a_number">Geben Sie eine Zahl ein.</string>
<string name="duration">Dauer [ms]</string>
<string name="keepDeviceAwake">Gerät wach halten</string>
<string name="wakeLockTimeout">Zeitlimit angeben</string>
<string name="wakeLockExplanation">Aktivieren wird den Bildschirm anbehalten, während deaktivieren dem Bildschirm erlaubt, auszugehen. Um ihn anzubehalten, können Sie entweder eine Dauer angeben, nach der er ausgehen darf, oder Sie können Sie unendlich lange anlassen. Im letzteren Fall müßten Sie eine neue Gerät wach halten-Aktion definieren, in der Sie \"deaktivieren\" auswählen.</string>
<string name="mayUseRegularExpressions">Sie können hier auch einen regulären Ausdruck eingeben.</string>
<string name="locationRequiredToDetermineWifiName">Um die SSID auslesen zu können, benötigt die Anwendung das Recht Ihren Standort zu erkennen. Weil die Google-Version das nicht kann, können Sie in diesem Auslöser keine SSID spezifizieren. Sie können ihn nur wenden, um zu erkennen, ob WLAN verbunden ist oder nicht.</string>
<string name="withButton">mit der Schaltfläche %1$s</string>
<string name="bluetooth">Bluetooth</string>
<string name="subSystemState">Subsystem Status</string>
<string name="clickNotificationButton">Eine Schaltfläche klicken</string>
<string name="simplyDismissNotification">Regulär schließen</string>
<string name="usb">USB</string>
<string name="cable">Kabel</string>
<string name="tetheringBluetoothNotPossible">Bluetooth tethering kann gegenwärtig nicht detektiert werden. Nur die anderen Verbindungsarten werden diesen Auslöser aktivieren.</string>
<string name="type">Art</string>
<string name="startPhoneCall">Telefonnummer anrufen</string>
<string name="android.permission.CALL_PHONE">Telefonnummer anrufen</string>
<string name="makePhoneCallExplanation1">Hier können Sie eine Telefonnummer eingeben, die ohne weitere Aufforderung angerufen wird. Sie können dies verwenden, um Einstellungen vorzunehmen, z. B. Anpassungen an der Anrufweiterleitung usw. vorzunehmen. Bitte suchen Sie selbst nach den dafür benötigten Codes.</string>
<string name="endPhoneCall">Telefonanruf beenden</string>
<string name="android.permission.ANSWER_PHONE_CALLS">Telefonanruf beenden</string>
<string name="settingsReferringToRestrictedFeaturesInGoogle">Ihre Einstellungen und/oder Regeln verweisen derzeit auf Funktionen, die in der Google Play-Version nicht bereitgestellt werden können. Dazu gehört unter anderem alles, was mit Telefonaten und Textnachrichten zu tun hat.</string>
<string name="setVariable">Variable festlegen</string>
<string name="deleteVariable">Variable löschen</string>
<string name="VariableKey">Variablenname</string>
<string name="variableValue">Variablenwert</string>
<string name="setVariableExplanation">Wenn Sie für eine Variable einen leeren Wert angeben, wird sie gelöscht.</string>
<string name="enterVariableKey">Geben Sie einen Namen für die Variable an.</string>
<string name="checkVariable">Variable prüfen</string>
<string name="checkVariableExplanation">Wenn Sie den Wert der Variablen leer lassen, darf sie nicht gesetzt sein, damit die Bedingung als erfüllt gilt.</string>
<string name="variableCheckString">wenn Variable %1$s den Wert %2$s hat</string>
<string name="variableCheckStringDeleted">wenn Variable %1$s nicht gesetzt ist</string>
<string name="messageType">Nachrichtentyp</string>
<string name="sms">SMS</string>
<string name="mms">MMS</string>
<string name="attachment">Dateianhang</string>
<string name="chooseFile">Datei wählen</string>
<string name="startAppByStartService">via startService()</string>
<string name="showToastsForEvents">Toasts anzeigen</string>
<string name="showToastsForEventsSummary">Popups anzeigen, wenn Ereignisse wie Regelausführungen auftreten</string>
<string name="notificationAccessAndroid13">Nachdem Sie auf OK geklickt haben, wählen Sie Automatisierung, dann \"Benachrichtigungszugriff zulassen\", dann \"Zulassen\".\n\nAuf einigen Systemen ist diese Einstellung ausgegraut. In diesen Fällen müssen Sie zu \"settings\" -> \"apps\" -> \"Automation\" -> 3-Punkte-Menü -> Gehen Sie diese Einschränkungen auf. Danach kehren Sie hierher zurück.</string>
<string name="displayLanguage">Anzeigesprache</string>
<string name="displayLanguageSummary">Bestimmte Anzeigesprache wählen</string>
<string name="wifiMonitoringAlsoRequiresThis">Diese Berechtigung wird auch benötigt, wenn man die aktuelle WLAN Verbindung auslesen möchte.</string>
<string name="copyTextToClipboard">Text in die Zwischenablage kopieren</string>
<string name="textToCopy">Text, der kopiert werden soll</string>
<string name="android.permission.SYSTEM_ALERT_WINDOW">Über anderen Anwendungen anzeigen</string>
<string name="overlayPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automation aus und erlauben Sie die Anzeige über anderen Apps.</string>
<string name="overlayPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automatisierung aus und lassen Sie das Zeichnen über andere Apps zu.</string>
</resources>

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