Compare commits

...
74 Commits
Author SHA1 Message Date
jens 2a067507ae new release 1.7.2 2022-01-10 10:33:49 +01:00
jens 1c8eec735d code cleanups 2022-01-09 21:43:49 +01:00
jens 53f46c10da translations 2022-01-09 14:55:52 +01:00
jens c5f04afe85 translations 2022-01-09 14:01:38 +01:00
jens 4d7fa711f9 profile trigger 2022-01-09 13:51:38 +01:00
jens 4bea2113fa profile trigger 2022-01-09 13:48:12 +01:00
jens 890260b8eb startApp 2022-01-08 19:00:06 +01:00
jens 230521149f startApp 2022-01-08 14:46:01 +01:00
jens 9a50da550a bugs and translations 2022-01-05 23:27:27 +01:00
jens 941bb3e1af profile trigger 2022-01-05 18:06:26 +01:00
jens 5653a9c70e profile trigger 2022-01-04 17:51:27 +01:00
jens 8c6331237d Cosmetics 2022-01-04 16:14:13 +01:00
jens 1bbf04d548 Exclusion from battery optimization 2022-01-03 23:24:34 +01:00
jens a2d93d27cb Cosmetics 2022-01-03 19:50:57 +01:00
jens 0463e0aa19 Silent mode bug 2021-12-27 13:58:43 +01:00
jens 41cf907be3 Merge remote-tracking branch 'origin/development' 2021-12-24 01:50:44 +01:00
jens acae282a0d New changelog 2021-12-24 01:50:33 +01:00
jens ebfceee69f Translations 2021-12-24 01:38:42 +01:00
jens 69283c5fea Translations 2021-12-21 20:02:13 +01:00
jens fff0bde9d8 Merge remote-tracking branch 'origin/development' into development 2021-12-20 19:58:56 +01:00
jens f9c76ba951 Rework 2021-12-20 19:58:43 +01:00
jens d1263b46b6 Refactoring 2021-12-19 22:31:05 +01:00
jens 64801d8ff2 Rework 2021-12-19 17:12:24 +01:00
jens 3d8257aeec Rework 2021-12-19 14:47:46 +01:00
jens 67b2a81647 Rework 2021-12-19 12:58:33 +01:00
jens 3e9590d7d2 Rework 2021-12-18 13:29:47 +01:00
jens 21b8c6c7ec Rework 2021-12-18 02:43:04 +01:00
jens dc8cc14d20 Rework 2021-12-13 20:03:26 +01:00
jens 4fc1f8a2a9 Rework 2021-12-13 20:03:00 +01:00
jens d7e1cd44e8 Rework 2021-12-12 20:03:53 +01:00
jens c1139e1cb8 Rework 2021-12-11 14:15:05 +01:00
jens 03c8a1ff60 Rework 2021-12-11 02:04:45 +01:00
jens 20acd563e7 Refactoring 2021-12-09 22:54:34 +01:00
jens 5ae193847e Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Actions.java
2021-12-09 18:05:58 +01:00
jens 391479b164 Rework 2021-12-09 18:03:00 +01:00
jens fa578b175d Refactoring 2021-12-08 23:08:05 +01:00
jens 0008642044 Rework 2021-12-08 19:57:27 +01:00
jens 359dd545c7 Merge remote-tracking branch 'origin/transfer_applies_to_trigger' into development 2021-12-08 17:22:33 +01:00
jens 89ac69fd4b Rework 2021-12-08 17:22:18 +01:00
jens b88801500f Refactoring 2021-12-07 23:10:37 +01:00
jens 128116025f Rework 2021-12-07 16:45:05 +01:00
jens 5d3e89595f description 2021-12-05 22:28:30 +01:00
jens 8e5ad15c34 Rework 2021-12-05 17:24:47 +01:00
jens 8b29dd0985 Rework 2021-12-05 14:51:00 +01:00
jens c34ec83425 Rework 2021-12-04 13:24:43 +01:00
jens cdf1a8baa8 Rework 2021-12-04 02:39:37 +01:00
jens d28ee8d00d Fixed infinite loop 2021-12-03 22:30:34 +01:00
jens 2bb6f81596 Position trigger 2021-11-30 18:25:51 +01:00
jens 6f0dbc9555 Position trigger 2021-11-29 20:14:09 +01:00
jens a9bd7b9561 Position trigger 2021-11-28 20:01:58 +01:00
jens 81d6ab7b5f Position trigger 2021-11-27 20:22:13 +01:00
jens 034c76fe30 Translations and integrated BT tethering 2021-11-27 02:03:51 +01:00
jens 15637e914d Translations and integrated BT tethering 2021-11-27 01:52:57 +01:00
jens cd6ed7543c Translations and integrated BT tethering 2021-11-26 19:26:42 +01:00
jens f991325566 Merge remote-tracking branch 'origin/BT_tethering' into development 2021-11-26 18:56:28 +01:00
jens b744e76b07 Negative location coordinates allowed 2021-11-23 13:27:09 +01:00
jens 06d63826e6 Donate button 2021-11-20 16:14:21 +01:00
jens fb87d5e42d BT tethering 2021-11-17 21:46:56 +01:00
jens 17109b12d4 BT tethering 2021-11-15 20:28:38 +01:00
jens 92ca6d6cb4 BT tethering 2021-11-13 14:48:56 +01:00
jens 5fdc68e396 Merge remote-tracking branch 'origin/reoccuring_time_trigger' into development 2021-11-13 12:31:27 +01:00
jens ab0f2d88b4 Reoccuring time trigger 2021-11-13 02:32:39 +01:00
jens 06a6651fae Reoccuring time trigger 2021-11-13 02:17:36 +01:00
jens 473c464bf7 BT tethering 2021-11-13 01:00:36 +01:00
jens a5b9ced9ba line break 2021-11-11 10:28:46 +01:00
jens 9cea3f4285 reocc time 2021-11-10 21:47:09 +01:00
jens 0438a58f3e translation 2021-11-09 11:10:06 +01:00
jens 97f32bd012 Reoccuring time 2021-11-08 20:13:11 +01:00
jens 6588443459 reoccuring time 2021-11-07 17:29:00 +01:00
jens 604ab0eb43 miscellaneous 2021-11-07 15:38:42 +01:00
jens 31c4f6c1d1 Fixed crash of edit wifi trigger 2021-11-07 02:09:09 +01:00
jens 0c646b55fc Fixed infinite loop 2021-11-05 22:47:48 +01:00
jens 88cdc366c5 Changelogs 2021-11-04 18:01:30 +01:00
jens 2bd94e8a3d Changelogs 2021-11-03 15:30:49 +01:00
111 changed files with 5974 additions and 3968 deletions
+2
View File
@@ -148,3 +148,5 @@ fabric.properties
/app/app-release.apk
Automation_settings.xml
/app/googlePlayFlavor/
/.idea/deploymentTargetDropDown.xml
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\jens\.android\avd\Android_11.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-09-24T23:07:53.935197300Z" />
</component>
</project>
+2 -2
View File
@@ -11,8 +11,8 @@ android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 113
versionName "1.6.43"
versionCode 116
versionName "1.7.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 113,
"versionName": "1.6.43-googlePlay",
"versionCode": 116,
"versionName": "1.7.2-googlePlay",
"outputFile": "app-googlePlayFlavor-release.apk"
}
],
+19 -9
View File
@@ -65,6 +65,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-feature
android:name="android.hardware.telephony"
@@ -121,30 +122,37 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
@@ -186,6 +194,7 @@
<activity android:name=".ActivityManageActionStartActivity" />
<activity android:name=".ActivityManageTriggerNfc" />
<activity android:name=".ActivityManageActionSpeakText" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" />
@@ -204,6 +213,7 @@
</service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
File diff suppressed because it is too large Load Diff
@@ -291,10 +291,10 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
if(allRulesWithActivityDetection.get(i).getsGreenLight(Miscellaneous.getAnyContext()))
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
}
}
+19 -10
View File
@@ -51,6 +51,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@@ -62,6 +63,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-feature
android:name="android.hardware.telephony"
@@ -118,30 +120,37 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
@@ -170,6 +179,7 @@
</intent-filter>
-->
<!--
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
@@ -203,7 +213,6 @@
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
File diff suppressed because it is too large Load Diff
+18 -10
View File
@@ -50,6 +50,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@@ -63,6 +64,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application
android:allowBackup="true"
@@ -112,30 +114,37 @@
<receiver android:name=".receivers.PackageReplacedReceiver"
android:enabled="true">
<intent-filter>
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<!--<data
android:path="com.jens.automation2"
android:scheme="package" />-->
</intent-filter>
</receiver>
<receiver android:name=".receivers.AlarmListener" />
<receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity
@@ -198,7 +207,6 @@
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
File diff suppressed because it is too large Load Diff
@@ -301,7 +301,7 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
@@ -5,6 +5,7 @@ import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import java.util.ArrayList;
@@ -13,6 +14,8 @@ import java.util.Locale;
public class Action
{
Rule parentRule = null;
public static final String actionParameter2Split = "ap2split";
public static final String intentPairSeperator = "intPairSplit";
public static final String vibrateSeparator = ",";
@@ -22,6 +25,7 @@ public class Action
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
@@ -29,10 +33,10 @@ public class Action
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation, disableScreenRotation,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
wakeupDevice,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
@@ -52,6 +56,8 @@ public class Action
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
@@ -84,8 +90,8 @@ public class Action
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case wakeupDevice:
return context.getResources().getString(R.string.wakeupDevice);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
@@ -147,86 +153,93 @@ public class Action
public String toString()
{
StringBuilder returnString = new StringBuilder();
if(this.getAction().equals(Action_Enum.setWifi))
switch(getAction())
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
case setWifi:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
break;
case setBluetooth:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOff));
break;
case setUsbTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOff));
break;
case setWifiTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
break;
case setBluetoothTethering:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOff));
break;
case setDisplayRotation:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionEnableScreenRotation));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionDisableScreenRotation));
break;
case setAirplaneMode:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOff));
break;
case setDataConnection:
if (this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOff));
break;
case startOtherActivity:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
break;
case triggerUrl:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
break;
case speakText:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
break;
case playMusic:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
break;
case sendTextMessage:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
break;
case turnScreenOnOrOff:
if (getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOff));
break;
case playSound:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playSound));
break;
case changeSoundProfile:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionChangeSoundProfile));
break;
case waitBeforeNextAction:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.waitBeforeNextAction));
break;
case setScreenBrightness:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setScreenBrightness));
break;
default:
returnString.append(action.toString());
}
else if(this.getAction().equals(Action_Enum.setBluetooth))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOff));
}
else if(this.getAction().equals(Action_Enum.setUsbTethering))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOff));
}
else if(this.getAction().equals(Action_Enum.setWifiTethering))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
}
else if(this.getAction().equals(Action_Enum.setDisplayRotation))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionEnableScreenRotation));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionDisableScreenRotation));
}
else if(this.getAction().equals(Action_Enum.setAirplaneMode))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOff));
}
else if(this.getAction().equals(Action_Enum.setDataConnection))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOff));
}
else if(this.getAction().equals(Action_Enum.startOtherActivity))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
}
else if(this.getAction().equals(Action_Enum.triggerUrl))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
}
else if(this.getAction().equals(Action_Enum.speakText))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
}
else if(this.getAction().equals(Action_Enum.playMusic))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
}
else if(this.getAction().equals(Action_Enum.sendTextMessage))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
}
else if(this.getAction().equals(Action_Enum.wakeupDevice))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wakeupDevice));
}
else if(this.getAction().equals(Action_Enum.playSound))
{
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playSound));
}
else
returnString.append(action.toString());
if(this.getAction().equals(Action_Enum.triggerUrl))
{
@@ -236,7 +249,7 @@ public class Action
returnString.append(": " + components[2]);
if(parameter1)
returnString.append(" using authentication.");
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingAuthentication) + ".");
}
else
returnString.append(": " + components[0]);
@@ -250,14 +263,14 @@ public class Action
String[] components = parameter2.split(Actions.smsSeparator);
if(components.length >= 2)
{
returnString.append(" to number " + components[0]);
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.toNumber) + " " + components[0]);
returnString.append(". Message: " + components[1]);
returnString.append(". " + Miscellaneous.getAnyContext().getResources().getString(R.string.message) + ": " + components[1]);
}
}
else if(this.getAction().equals(Action_Enum.setScreenBrightness))
{
returnString.append(" to ");
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.to) + " ");
if(parameter1)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
@@ -273,6 +286,16 @@ public class Action
return returnString.toString();
}
public Rule getParentRule()
{
return parentRule;
}
public void setParentRule(Rule parentRule)
{
this.parentRule = parentRule;
}
public static CharSequence[] getActionTypesAsArray()
{
ArrayList<String> actionTypesList = new ArrayList<String>();
@@ -370,6 +393,9 @@ public class Action
case setWifiTethering:
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setBluetoothTethering:
Actions.BluetoothTetheringClass.setBluetoothTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setDisplayRotation:
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
break;
@@ -379,16 +405,26 @@ public class Action
case waitBeforeNextAction:
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
break;
case wakeupDevice:
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
try
case turnScreenOnOrOff:
if(getParameter1())
{
Thread.sleep(100);
if(StringUtils.isNumeric(this.getParameter2()))
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
else
Actions.wakeupDevice((long)1000);
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
else
{
e.printStackTrace();
Actions.turnOffScreen();
}
break;
case setAirplaneMode:
@@ -5,7 +5,11 @@ import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -43,13 +47,16 @@ import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.KeyStore;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.net.ssl.SSLContext;
@@ -304,6 +311,149 @@ public class Actions
return true;
}
public static class BluetoothTetheringClass
{
static Object instance = null;
static Method setTetheringOn = null;
static Method isTetheringOn = null;
static Object mutex = new Object();
public static Boolean setBluetoothTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "Bluetooth Tethering", "Changing Bluetooth Tethering to " + String.valueOf(desiredState), 4);
// boolean state = isTetheringOn(context);
// if (toggleActionIfPossible)
// {
// Miscellaneous.logEvent("i", "Bluetooth Tethering", context.getResources().getString(R.string.toggling), 2);
// desiredState = !state;
// }
// if (((state && !desiredState) || (!state && desiredState)))
// {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Method mBTPanConnect = null;
String sClassName = "android.bluetooth.BluetoothPan";
try
{
classBluetoothPan = Class.forName(sClassName);
Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
ctor.setAccessible(true);
// Set Tethering ON
Class[] paramSet = new Class[1];
paramSet[0] = boolean.class;
synchronized (mutex)
{
setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);
isTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", null);
instance = ctor.newInstance(context, new BTPanServiceListener(context));
}
classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
mBTPanConnect = classBluetoothPan.getDeclaredMethod("connect", BluetoothDevice.class);
BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
BTPanCtor.setAccessible(true);
BTSrvInstance = BTPanCtor.newInstance(context, new BTPanServiceListener(context));
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0)
{
// Loop through paired devices
for (BluetoothDevice device : pairedDevices)
{
try
{
mBTPanConnect.invoke(BTSrvInstance, device);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
}
return true;
}
catch (NoSuchMethodException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (ClassNotFoundException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch(InvocationTargetException e)
{
/*
Exact error message: "Bluetooth binder is null"
This means this device doesn't have bluetooth.
*/
Miscellaneous.logEvent("e", "Bluetooth Tethering", "Device probably doesn't have bluetooth. " + Log.getStackTraceString(e), 1);
Toast.makeText(context, context.getResources().getString(R.string.deviceDoesNotHaveBluetooth), Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
return false;
}
public static class BTPanServiceListener implements BluetoothProfile.ServiceListener
{
private final Context context;
public BTPanServiceListener(final Context context)
{
this.context = context;
}
@Override
public void onServiceConnected(final int profile, final BluetoothProfile proxy)
{
//Some code must be here or the compiler will optimize away this callback.
try
{
synchronized (mutex)
{
setTetheringOn.invoke(instance, true);
if ((Boolean) isTetheringOn.invoke(instance, null))
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is on", 1);
}
else
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is off", 1);
}
}
}
catch (InvocationTargetException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (IllegalAccessException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
@Override
public void onServiceDisconnected(final int profile)
{
}
}
}
public static boolean setUsbTethering(Context context2, Boolean desiredState, boolean toggleActionIfPossible)
{
//TODO:toggle not really implemented, yet
@@ -537,14 +687,14 @@ public class Actions
AudioManager myAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && desiredSoundSetting == AudioManager.RINGER_MODE_SILENT)
{
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, AudioManager.FLAG_PLAY_SOUND);
am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
}
else
myAudioManager.setRingerMode(desiredSoundSetting);
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && desiredSoundSetting == AudioManager.RINGER_MODE_SILENT)
// {
// AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
// am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, AudioManager.FLAG_PLAY_SOUND);
// am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
// }
// else
// myAudioManager.setRingerMode(desiredSoundSetting);
}
private static String getIPAddressUsb(final boolean useIPv4)
@@ -945,23 +1095,96 @@ public class Actions
@Override
public void run()
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock((WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
wakeLock.acquire();
try
{
Thread.sleep(awakeTime);
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
}
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock((PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
wakeLock.acquire();
wakeLock.release();
try
{
Thread.sleep(awakeTime);
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
}
wakeLock.release();
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "Wakeup device action", "Error while waking up device: " + Log.getStackTraceString(e), 1);
}
}
}
/*public static void turnOnScreen()
{
// turn on screen
Miscellaneous.logEvent("i", "Actions", "Turning screen on.", 3);
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
wakeLock.acquire();
}*/
@TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
public static void turnOffScreen()
{
Miscellaneous.logEvent("i", "Actions", "Turning screen off.", 3);
/*params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);*/
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
// wakeLock.acquire();
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , "tag");
// wakeLock.acquire();
// wakeLock.release();
lockScreen();
}
public static void lockScreen()
{
Miscellaneous.logEvent("i", "Actions", "Locking screen.", 3);
// Works, but requires Manifest.permission.BIND_DEVICE_ADMIN
// https://stackoverflow.com/questions/23898406/java-lang-securityexception-no-active-admin-owned-by-uid-10047-for-policy-4-on
DevicePolicyManager deviceManager = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
deviceManager.lockNow();
}
// using root
/*private void turnOffScreen()
{
try
{
Class c = Class.forName("android.os.PowerManager");
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
for(Method m : c.getDeclaredMethods())
{
if(m.getName().equals("goToSleep"))
{
m.setAccessible(true);
if(m.getParameterTypes().length == 1)
{
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
}
}
}
}
catch (Exception e)
{
}
}*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("NewApi")
public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible)
@@ -9,7 +9,6 @@ import com.jens.automation2.R.layout;
public class ActivityHelp extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -19,5 +18,4 @@ public class ActivityHelp extends Activity
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
@@ -184,8 +184,16 @@ public class ActivityMainProfiles extends ActivityGeneric
startActivityForResult(manageSpecificProfileIntent, 2000);
break;
case 2:
if(profile.delete(myAutomationService))
updateListView();
Rule user = profile.isInUseByRules();
if(user == null)
{
if (profile.delete(ActivityMainProfiles.this))
updateListView();
else
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.profileCouldNotBeDeleted), Toast.LENGTH_LONG).show();
}
else
Toast.makeText(ActivityMainProfiles.this, String.format(getResources().getString(R.string.ruleXIsUsingProfileY), user.getName(), profile.getName()), Toast.LENGTH_LONG).show();
break;
}
}
@@ -19,7 +19,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.jens.automation2.AutomationService.serviceCommands;
import com.jens.automation2.receivers.AlarmListener;
import com.jens.automation2.receivers.DateTimeListener;
import java.util.ArrayList;
@@ -254,7 +254,7 @@ public class ActivityMainRules extends ActivityGeneric
try
{
if(AutomationService.isMyServiceRunning(this))
AlarmListener.reloadAlarms();
DateTimeListener.reloadAlarms();
}
catch(NullPointerException e)
{
@@ -44,7 +44,7 @@ public class ActivityMainScreen extends ActivityGeneric
private static ActivityMainScreen activityMainScreenInstance = null;
private ToggleButton toggleService, tbLockSound;
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme;
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme, bDonate;
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration;
private static boolean updateNoteDisplayed = false;
@@ -82,6 +82,12 @@ public class ActivityMainScreen extends ActivityGeneric
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
if(!BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
bDonate.setVisibility(View.VISIBLE);
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@@ -111,6 +117,18 @@ public class ActivityMainScreen extends ActivityGeneric
}
});
bDonate.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
String privacyPolicyUrl = "https://server47.de/donate";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
startActivity(browserIntent);
}
});
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
@@ -72,4 +72,4 @@ public class ActivityMainTabLayout extends TabActivity
// setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent);
}
}
}
@@ -201,6 +201,9 @@ public class ActivityMaintenance extends Activity
try
{
XmlFileInterface.readFile();
ActivityMainPoi.getInstance().updateListView();
ActivityMainRules.getInstance().updateListView();
ActivityMainProfiles.getInstance().updateListView();
}
catch (Exception e)
{
@@ -314,18 +317,9 @@ public class ActivityMaintenance extends Activity
String subject = "Automation logs";
StringBuilder emailBody = new StringBuilder();
emailBody.append("Device details" + Miscellaneous.lineSeparator);
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
emailBody.append("Product: " + android.os.Build.PRODUCT);
emailBody.append("Flavor: " + BuildConfig.FLAVOR);
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), uri);
}
});
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
@@ -334,6 +328,19 @@ public class ActivityMaintenance extends Activity
return alertDialog;
}
public static String getSystemInfo()
{
StringBuilder systemInfoText = new StringBuilder();
systemInfoText.append("Device details" + Miscellaneous.lineSeparator);
systemInfoText.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
systemInfoText.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
systemInfoText.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
systemInfoText.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
systemInfoText.append("Product: " + android.os.Build.PRODUCT + Miscellaneous.lineSeparator);
systemInfoText.append("Flavor: " + BuildConfig.FLAVOR);
return systemInfoText.toString();
}
@Override
protected void onResume()
{
@@ -59,7 +59,7 @@ public class ActivityManageActionSendTextMessage extends Activity
backToRuleManager();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
}
});
@@ -44,7 +44,7 @@ public class ActivityManageActionSpeakText extends Activity
backToRuleManager();
}
else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
}
});
@@ -230,44 +230,89 @@ public class ActivityManageActionStartActivity extends Activity
return null;
}
private AlertDialog getActionStartActivityDialog1()
private AlertDialog getActionStartActivityDialog1Application()
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
final String[] applicationArray = ActivityManageActionStartActivity.getApplicationNameListString(this);
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
{
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
getActionStartActivityDialog2(applicationArray[which]).show();
getActionStartActivityDialog2(applicationArray[which]);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
private AlertDialog getActionStartActivityDialog2(String applicationName)
private void getActionStartActivityDialog2(String applicationName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
final String[] packageArray = ActivityManageActionStartActivity.getPackageListString(this, applicationName);
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
{
if(packageArray.length > 1)
{
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog4ActivityPickMethod(packageArray[which]).show();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
else
{
getActionStartActivityDialog4ActivityPickMethod(packageArray[0]).show();
}
}
private AlertDialog getActionStartActivityDialog4ActivityPickMethod(final String packageName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage(getResources().getString(R.string.launcherOrManualExplanation));
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.takeLauncherActivity), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog3(packageArray[which]).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
// Pick the launcher automatically
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (launchIntent != null)
{
ActivityInfo ai = ActivityManageActionStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, launchIntent.getComponent().getClassName());
etPackageName.setText(ai.packageName);
etActivityOrActionPath.setText(ai.name);
}
else
{
getActionStartActivityDialog5Activity(packageName).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.launcherNotFound) + Miscellaneous.lineSeparator + getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
}
}
});
alertDialogBuilder.setNegativeButton(getResources().getString(R.string.pickActivityManually), new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
getActionStartActivityDialog5Activity(packageName).show();
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
}
});
final String activityArray[] = ActivityManageActionStartActivity.getActivityListForPackageName(packageName);
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
private AlertDialog getActionStartActivityDialog3(final String packageName)
private AlertDialog getActionStartActivityDialog5Activity(final String packageName)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
@@ -283,7 +328,6 @@ public class ActivityManageActionStartActivity extends Activity
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
@@ -598,7 +642,6 @@ public class ActivityManageActionStartActivity extends Activity
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
@@ -615,9 +658,7 @@ public class ActivityManageActionStartActivity extends Activity
protected void onPostExecute(Void result)
{
progressDialog.dismiss();
getActionStartActivityDialog1().show();
getActionStartActivityDialog1Application().show();
}
}
}
}
@@ -3,7 +3,6 @@ package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -14,6 +13,7 @@ import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.text.util.Linkify;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
@@ -49,32 +49,36 @@ import java.util.Collections;
public class ActivityManageRule extends Activity
{
final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver";
public final static String intentNameTriggerParameter1 = "triggerParameter1";
public final static String intentNameTriggerParameter2 = "triggerParameter2";
public final static String intentNameActionParameter1 = "actionParameter1";
public final static String intentNameActionParameter2 = "actionParameter2";
public Context context;
private Button cmdTriggerAdd, cmdActionAdd, cmdSaveRule;
private ListView triggerListView, actionListView;
private EditText etRuleName;
private CheckBox chkRuleActive, chkRuleToggle;
private static ActivityManageRule instance = null;
Button cmdTriggerAdd, cmdActionAdd, cmdSaveRule;
ListView triggerListView, actionListView;
EditText etRuleName;
CheckBox chkRuleActive, chkRuleToggle;
static ActivityManageRule instance = null;
ImageView imageHelpButton;
private static ProgressDialog progressDialog = null;
static ProgressDialog progressDialog = null;
private static Trigger_Enum triggerType;
private static boolean triggerParameter;
private static PointOfInterest triggerPoi;
private static String triggerProcess;
private static int triggerBattery;
private static double triggerSpeed;
private static double triggerNoise;
private static TimeFrame triggerTimeFrame;
private static String triggerWifiName;
static Trigger_Enum triggerType;
static boolean triggerParameter;
static PointOfInterest triggerPoi;
static String triggerProcess;
static int triggerBattery;
static double triggerSpeed;
static double triggerNoise;
static TimeFrame triggerTimeFrame;
static String triggerWifiName;
private static Rule ruleToEdit;
private static boolean newRule;
static Rule ruleToEdit;
static boolean newRule;
private static Trigger newTrigger;
private static Action newAction;
static Trigger newTrigger;
static Action newAction;
ArrayAdapter<Trigger> triggerListViewAdapter;
ArrayAdapter<Action> actionListViewAdapter;
@@ -95,12 +99,16 @@ public class ActivityManageRule extends Activity
final static int requestCodeTriggerBluetoothEdit = 6001;
final static int requestCodeActionScreenBrightnessAdd = 401;
final static int requestCodeActionScreenBrightnessEdit = 402;
final static int requestCodeTriggerDeviceOrientationAdd = 301;
final static int requestCodeTriggerDeviceOrientationEdit = 302;
final static int requestCodeTriggerNotificationAdd = 8000;
final static int requestCodeTriggerNfcNotificationEdit = 8001;
final static int requestCodeActionPlaySoundAdd = 501;
final static int requestCodeActionPlaySoundEdit = 502;
final static int requestCodeTriggerPhoneCallAdd = 601;
final static int requestCodeTriggerPhoneCallEdit = 602;
final static int requestCodeTriggerProfileAdd = 603;
final static int requestCodeTriggerProfileEdit = 604;
final static int requestCodeTriggerWifiAdd = 723;
final static int requestCodeTriggerWifiEdit = 724;
final static int requestCodeActionSendTextMessageAdd = 5001;
@@ -165,7 +173,13 @@ public class ActivityManageRule extends Activity
{
hideKeyboard();
newTrigger = new Trigger();
getTriggerTypeDialog(context).show();
AlertDialog dia = getTriggerTypeDialog(context);
if(Miscellaneous.isDarkModeEnabled(ActivityManageRule.this))
dia.getListView().setBackgroundColor(getResources().getColor(R.color.darkScreenBackgroundColor));
dia.show();
}
});
@@ -175,12 +189,18 @@ public class ActivityManageRule extends Activity
public void onClick(View v)
{
hideKeyboard();
getActionTypeDialog().show();
AlertDialog dia = getActionTypeDialog();
if(Miscellaneous.isDarkModeEnabled(ActivityManageRule.this))
dia.getListView().setBackgroundColor(getResources().getColor(R.color.darkScreenBackgroundColor));
dia.show();
}
});
cmdSaveRule.setOnClickListener(new OnClickListener()
{
{
@Override
public void onClick(View v)
{
@@ -254,15 +274,27 @@ public class ActivityManageRule extends Activity
phoneCallEditor.putExtra("edit", true);
startActivityForResult(phoneCallEditor, requestCodeTriggerPhoneCallEdit);
break;
case profileActive:
Intent profileActiveEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerProfile.class);
profileActiveEditor.putExtra(ActivityManageRule.intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
profileActiveEditor.putExtra(ActivityManageRule.intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(profileActiveEditor, requestCodeTriggerProfileEdit);
break;
case wifiConnection:
Intent wifiEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerWifi.class);
wifiEditor.putExtra("edit", true);
wifiEditor.putExtra("wifiState", selectedTrigger.getTriggerParameter());
wifiEditor.putExtra("wifiName", selectedTrigger.getTriggerParameter2());
wifiEditor.putExtra(ActivityManageTriggerWifi.intentNameWifiState, selectedTrigger.getTriggerParameter());
wifiEditor.putExtra(ActivityManageTriggerWifi.intentNameWifiName, selectedTrigger.getTriggerParameter2());
startActivityForResult(wifiEditor, requestCodeTriggerWifiEdit);
break;
case deviceOrientation:
Intent devicePositionEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerDeviceOrientation.class);
devicePositionEditor.putExtra(ActivityManageRule.intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
devicePositionEditor.putExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName, selectedTrigger.getTriggerParameter2());
startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit);
break;
default:
break;
break;
}
}
});
@@ -303,6 +335,7 @@ public class ActivityManageRule extends Activity
case triggerUrl:
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class);
ActivityManageActionTriggerUrl.resultingAction = a;
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
activityEditTriggerUrlIntent.putExtra("edit", true);
startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit);
break;
@@ -332,8 +365,8 @@ public class ActivityManageRule extends Activity
case playSound:
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
actionPlaySoundIntent.putExtra("edit", true);
actionPlaySoundIntent.putExtra("actionParameter1", a.getParameter1());
actionPlaySoundIntent.putExtra("actionParameter2", a.getParameter2());
actionPlaySoundIntent.putExtra(intentNameActionParameter1, a.getParameter1());
actionPlaySoundIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit);
break;
default:
@@ -403,6 +436,11 @@ public class ActivityManageRule extends Activity
ruleToEdit.setName(etRuleName.getText().toString());
ruleToEdit.setRuleActive(chkRuleActive.isChecked());
ruleToEdit.setRuleToggle(chkRuleToggle.isChecked());
for(Trigger t : ruleToEdit.getTriggerSet())
t.setParentRule(ruleToEdit);
for(Action a : ruleToEdit.getActionSet())
a.setParentRule(ruleToEdit);
}
private void loadVariablesIntoGui()
@@ -465,164 +503,187 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.headphone));
else if(types[i].toString().equals(Trigger_Enum.notification.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Trigger_Enum.deviceOrientation.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else if(types[i].toString().equals(Trigger_Enum.profileActive.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items)
{
public View getView(int position, View convertView, ViewGroup parent)
{
//User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items)
{
public View getView(int position, View convertView, ViewGroup parent)
{
//User super class to create the View
View v = super.getView(position, convertView, parent);
//Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
//Add margin between image and text (support various screen densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
//Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
return v;
}
};
//Add margin between image and text (support various screen densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle(getResources().getString(R.string.selectTypeOfTrigger))
.setAdapter(adapter, new DialogInterface.OnClickListener()
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onClick(DialogInterface dialog, int which)
{
triggerType = Trigger_Enum.values()[which];
return v;
}
};
String[] booleanChoices = null;
if(triggerType == Trigger_Enum.pointOfInterest)
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle(getResources().getString(R.string.selectTypeOfTrigger))
.setAdapter(adapter, new DialogInterface.OnClickListener()
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onClick(DialogInterface dialog, int which)
{
triggerType = Trigger_Enum.values()[which];
String[] booleanChoices = null;
if(triggerType == Trigger_Enum.pointOfInterest)
{
if(Miscellaneous.googleToBlameForLocation(false))
{
if(Miscellaneous.googleToBlameForLocation(false))
{
ActivityMainScreen.openGoogleBlamingWindow();
return;
}
else
{
if (PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
else
{
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
return;
}
}
}
else if(triggerType == Trigger_Enum.timeFrame)
{
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = newTrigger;
Intent timeFrameEditor = new Intent(myContext, ActivityManageTriggerTimeFrame.class);
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeAdd);
ActivityMainScreen.openGoogleBlamingWindow();
return;
}
else if(triggerType == Trigger_Enum.charging)
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)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
// else if(triggerType == Trigger_Enum.wifiConnection)
// booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.process_started_stopped)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.notification)
{
newTrigger.setTriggerType(Trigger_Enum.notification);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNotification.class);
startActivityForResult(nfcEditor, requestCodeTriggerNotificationAdd);
return;
}
else if(triggerType == Trigger_Enum.airplaneMode)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.roaming)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.phoneCall)
{
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
else if(triggerType == Trigger_Enum.activityDetection)
{
try
{
Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "isPlayServiceAvailable");
if(m != null)
{
boolean available = (Boolean)m.invoke(null);
if(available)
{
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
getTriggerActivityDetectionDialog().show();
}
else
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
}
else
Miscellaneous.messageBox(getResources().getString(R.string.error), getResources().getString(R.string.featureNotInFdroidVersion), ActivityManageRule.this).show();
}
catch (IllegalAccessException | InvocationTargetException e)
{
e.printStackTrace();
}
return;
}
else if(triggerType == Trigger_Enum.nfcTag)
{
if(NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
{
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNfc.class);
startActivityForResult(nfcEditor, requestCodeTriggerNfcTagAdd);
return;
}
}
else if(triggerType == Trigger_Enum.bluetoothConnection)
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).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.headsetPlugged)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
if(triggerType == Trigger_Enum.nfcTag)
{
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show();
}
else
{
if (PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
else
{
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
return;
}
}
}
else if(triggerType == Trigger_Enum.timeFrame)
{
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = newTrigger;
Intent timeFrameEditor = new Intent(myContext, ActivityManageTriggerTimeFrame.class);
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeAdd);
return;
}
else if(triggerType == Trigger_Enum.charging)
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)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
return;
}
else if(triggerType == Trigger_Enum.deviceOrientation)
{
newTrigger.setTriggerType(Trigger_Enum.deviceOrientation);
Intent devicePositionTriggerEditor = new Intent(myContext, ActivityManageTriggerDeviceOrientation.class);
startActivityForResult(devicePositionTriggerEditor, requestCodeTriggerDeviceOrientationAdd);
return;
}
else if(triggerType == Trigger_Enum.process_started_stopped)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.notification)
{
newTrigger.setTriggerType(Trigger_Enum.notification);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNotification.class);
startActivityForResult(nfcEditor, requestCodeTriggerNotificationAdd);
return;
}
else if(triggerType == Trigger_Enum.airplaneMode)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.roaming)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.phoneCall)
{
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
return;
}
else if(triggerType == Trigger_Enum.profileActive)
{
if(Profile.getProfileCollection().size() > 0)
{
newTrigger.setTriggerType(Trigger_Enum.profileActive);
Intent profileTriggerEditor = new Intent(myContext, ActivityManageTriggerProfile.class);
startActivityForResult(profileTriggerEditor, requestCodeTriggerProfileAdd);
return;
}
else
{
Toast.makeText(context, getResources().getString(R.string.noProfilesCreateOneFirst), Toast.LENGTH_LONG).show();
return;
}
}
else if(triggerType == Trigger_Enum.activityDetection)
{
try
{
Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "isPlayServiceAvailable");
if(m != null)
{
boolean available = (Boolean)m.invoke(null);
if(available)
{
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
getTriggerActivityDetectionDialog().show();
}
else
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
}
else
Miscellaneous.messageBox(getResources().getString(R.string.error), getResources().getString(R.string.featureNotInFdroidVersion), ActivityManageRule.this).show();
}
catch (IllegalAccessException | InvocationTargetException e)
{
Miscellaneous.logEvent("w", "ActivityDetection", "Either play services are not available or the ActivityDetection classes are not. " + Log.getStackTraceString(e), 4);
}
return;
}
else if(triggerType == Trigger_Enum.nfcTag)
{
if(NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
{
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNfc.class);
startActivityForResult(nfcEditor, requestCodeTriggerNfcTagAdd);
return;
}
}
else if(triggerType == Trigger_Enum.bluetoothConnection)
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).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.headsetPlugged)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
if(triggerType == Trigger_Enum.nfcTag)
{
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show();
}
});
return builder.create();
}
else
getTriggerParameterDialog(context, booleanChoices).show();
}
});
return builder.create();
}
private AlertDialog getTriggerParameterDialog(final Context myContext, final String[] choices)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
@@ -990,7 +1051,6 @@ public class ActivityManageRule extends Activity
@Override
protected String[] doInBackground(ActivityManageRule... params)
{
// Looper.prepare();
final String[] applicationArray = ActivityManageActionStartActivity.getApplicationNameListString(params[0]);
return applicationArray;
}
@@ -1086,6 +1146,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
//add TriggerUrl
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionTriggerUrl.resultingAction);
this.refreshActionList();
}
@@ -1103,6 +1164,7 @@ public class ActivityManageRule extends Activity
//add TimeFrame
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
{
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
@@ -1114,6 +1176,7 @@ public class ActivityManageRule extends Activity
//edit TimeFrame
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
{
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList();
}
else
@@ -1123,8 +1186,9 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageTriggerWifi.intentNameWifiState, false));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerWifi.intentNameWifiName));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
@@ -1133,8 +1197,12 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.wifiConnection);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageTriggerWifi.intentNameWifiState, false));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerWifi.intentNameWifiName));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
@@ -1144,6 +1212,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
@@ -1154,6 +1223,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
// ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
@@ -1164,6 +1234,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK && ActivityManageTriggerNfc.generatedId != null)
{
newTrigger.setNfcTagId(ActivityManageTriggerNfc.generatedId);
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
@@ -1177,14 +1248,15 @@ public class ActivityManageRule extends Activity
{
ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter(data.getBooleanExtra("direction", false));
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageTriggerNotification.intentNameNotificationDirection, false));
newTrigger.setTriggerParameter2(
data.getStringExtra("app") + Trigger.triggerParameter2Split +
data.getStringExtra("titleDir") + Trigger.triggerParameter2Split +
data.getStringExtra("title") + Trigger.triggerParameter2Split +
data.getStringExtra("textDir") + Trigger.triggerParameter2Split +
data.getStringExtra("text")
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)
);
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList();
}
}
@@ -1193,6 +1265,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
newTrigger = ActivityManageTriggerNotification.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList();
}
}
@@ -1200,6 +1273,7 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2"));
this.refreshTriggerList();
@@ -1210,6 +1284,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
newTrigger = ActivityManageTriggerPhoneCall.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList();
}
}
@@ -1218,6 +1293,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
//add SpeakText
ActivityManageActionSpeakText.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionSpeakText.resultingAction);
this.refreshActionList();
}
@@ -1227,6 +1303,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK)
{
//edit SpeakText
ActivityManageActionSpeakText.resultingAction.setParentRule(ruleToEdit);
newAction = ActivityManageActionSpeakText.resultingAction;
this.refreshActionList();
}
@@ -1236,6 +1313,7 @@ public class ActivityManageRule extends Activity
//add bluetooth trigger
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
{
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
@@ -1247,6 +1325,7 @@ public class ActivityManageRule extends Activity
//edit bluetooth trigger
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
{
ActivityManageTriggerBluetooth.editedBluetoothTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList();
}
else
@@ -1258,6 +1337,7 @@ public class ActivityManageRule extends Activity
{
newAction.setParameter1(data.getBooleanExtra("autoBrightness", false));
newAction.setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0)));
newAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
@@ -1272,6 +1352,8 @@ public class ActivityManageRule extends Activity
if(data.hasExtra("brightnessValue"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0)));
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
this.refreshActionList();
}
}
@@ -1279,6 +1361,7 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra("vibratePattern"));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
@@ -1288,6 +1371,8 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra("vibratePattern"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("vibratePattern"));
@@ -1298,8 +1383,9 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newAction.setParameter1(data.getBooleanExtra("actionParameter1", false));
newAction.setParameter2(data.getStringExtra("actionParameter2"));
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
@@ -1308,11 +1394,13 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
if(data.hasExtra("actionParameter1"))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra("actionParameter1", false));
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra("actionParameter2"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("actionParameter2"));
if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
@@ -1321,7 +1409,7 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
//add SendTextMessage
ActivityManageActionSendTextMessage.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction);
this.refreshActionList();
}
@@ -1330,15 +1418,63 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
//edit SendTextMessage
newAction = ActivityManageActionSendTextMessage.resultingAction;
newAction.setParentRule(ruleToEdit);
//ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeTriggerDeviceOrientationAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerDeviceOrientationEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.deviceOrientation);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerProfileAdd)
{
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 == requestCodeTriggerProfileEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.profileActive);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
}
protected Dialog getActionTypeDialog()
protected AlertDialog getActionTypeDialog()
{
final ArrayList<Item> items = new ArrayList<Item>();
@@ -1355,14 +1491,16 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setWifiTethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setBluetoothTethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setDisplayRotation.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.displayrotation));
else if(types[i].toString().equals(Action_Enum.waitBeforeNextAction.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.wait));
else if(types[i].toString().equals(Action_Enum.setAirplaneMode.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.plane));
else if(types[i].toString().equals(Action_Enum.wakeupDevice.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm));
else if(types[i].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else if(types[i].toString().equals(Action_Enum.changeSoundProfile.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
else if(types[i].toString().equals(Action_Enum.triggerUrl.toString()))
@@ -1455,6 +1593,17 @@ public class ActivityManageRule extends Activity
newAction.setAction(Action_Enum.setWifiTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetoothTethering.toString()))
{
newAction.setAction(Action_Enum.setBluetoothTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
Miscellaneous.messageBox(context.getResources().getString(R.string.notice), context.getResources().getString(R.string.btTetheringNotice), context).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDisplayRotation.toString()))
{
newAction.setAction(Action_Enum.setDisplayRotation);
@@ -1481,10 +1630,10 @@ public class ActivityManageRule extends Activity
newAction.setAction(Action_Enum.waitBeforeNextAction);
getActionWaitBeforeNextActionDialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.wakeupDevice.toString()))
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
{
newAction.setAction(Action_Enum.wakeupDevice);
getActionWakeupDeviceDialog(ActivityManageRule.this).show();
newAction.setAction(Action_Enum.turnScreenOnOrOff);
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString()))
{
@@ -1492,7 +1641,6 @@ public class ActivityManageRule extends Activity
getActionParameter1Dialog(ActivityManageRule.this).show();
if(Build.VERSION.SDK_INT >= 17)
{
// Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show();
Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
}
}
@@ -1512,7 +1660,7 @@ public class ActivityManageRule extends Activity
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS"))
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
{
//launch other activity to enter parameters;
newAction.setAction(Action_Enum.sendTextMessage);
@@ -0,0 +1,297 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.jens.automation2.receivers.DeviceOrientationListener;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerDeviceOrientation extends Activity
{
TextView currentAzimuth, currentPitch, currentRoll, tvAppliesAzimuth, tvAppliesPitch, tvAppliesRoll;
Button bApplyPositionValues, bSavePositionValues;
EditText etDesiredAzimuth, etDesiredAzimuthTolerance, etDesiredPitch, etDesiredPitchTolerance, etDesiredRoll, etDesiredRollTolerance;
CheckBox chkDevicePositionApplies;
public static String vectorFieldName = "deviceVector";
boolean editMode = false;
float desiredAzimuth, desiredPitch, desiredRoll, desiredAzimuthTolerance, desiredPitchTolerance, desiredRollTolerance;
public void updateFields(float azimuth, float pitch, float roll)
{
currentAzimuth.setText(Float.toString(azimuth));
currentPitch.setText(Float.toString(pitch));
currentRoll.setText(Float.toString(roll));
try
{
desiredAzimuth = Float.parseFloat(etDesiredAzimuth.getText().toString());
desiredAzimuthTolerance = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
if (desiredAzimuthTolerance == 180 || (desiredAzimuth - desiredAzimuthTolerance <= azimuth && azimuth <= desiredAzimuth + desiredAzimuthTolerance))
{
tvAppliesAzimuth.setText(getResources().getString(R.string.yes));
tvAppliesAzimuth.setTextColor(Color.GREEN);
}
else
{
tvAppliesAzimuth.setText(getResources().getString(R.string.no));
tvAppliesAzimuth.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesAzimuth.setText("");
}
try
{
desiredPitch = Float.parseFloat(etDesiredPitch.getText().toString());
desiredPitchTolerance = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
if (desiredPitchTolerance == 180 || (desiredPitch - desiredPitchTolerance <= pitch && pitch <= desiredPitch + desiredPitchTolerance))
{
tvAppliesPitch.setText(getResources().getString(R.string.yes));
tvAppliesPitch.setTextColor(Color.GREEN);
}
else
{
tvAppliesPitch.setText(getResources().getString(R.string.no));
tvAppliesPitch.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesPitch.setText("");
}
try
{
desiredRoll = Float.parseFloat(etDesiredRoll.getText().toString());
desiredRollTolerance = Float.parseFloat(etDesiredRollTolerance.getText().toString());
if (desiredRollTolerance == 180 || (desiredRoll - desiredRollTolerance <= roll && roll <= desiredRoll + desiredRollTolerance))
{
tvAppliesRoll.setText(getResources().getString(R.string.yes));
tvAppliesRoll.setTextColor(Color.GREEN);
}
else
{
tvAppliesRoll.setText(getResources().getString(R.string.no));
tvAppliesRoll.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesRoll.setText("");
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_device_orientation);
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
currentPitch = (TextView) findViewById(R.id.tvCurrentOrientationPitch);
currentRoll = (TextView) findViewById(R.id.tvCurrentRoll);
tvAppliesAzimuth = (TextView) findViewById(R.id.tvAppliesAzimuth);
tvAppliesPitch = (TextView) findViewById(R.id.tvAppliesPitch);
tvAppliesRoll = (TextView) findViewById(R.id.tvAppliesRoll);
bApplyPositionValues = (Button) findViewById(R.id.bApplyPositionValues);
bSavePositionValues = (Button) findViewById(R.id.bSavePositionValues);
etDesiredAzimuth = (EditText) findViewById(R.id.etDesiredAzimuth);
etDesiredAzimuthTolerance = (EditText) findViewById(R.id.etDesiredAzimuthTolerance);
etDesiredPitch = (EditText) findViewById(R.id.etDesiredPitch);
etDesiredPitchTolerance = (EditText) findViewById(R.id.etDesiredPitchTolerance);
etDesiredRoll = (EditText) findViewById(R.id.etDesiredRoll);
etDesiredRollTolerance = (EditText) findViewById(R.id.etDesiredRollTolerance);
chkDevicePositionApplies = (CheckBox)findViewById(R.id.chkDevicePositionApplies);
// etDesiredAzimuth.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredPitch.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredRoll.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
etDesiredAzimuthTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredPitchTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredRollTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
if(getIntent().hasExtra(vectorFieldName))
{
editMode = true;
try
{
boolean chkValue = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true);
chkDevicePositionApplies.setChecked(chkValue);
String values[] = getIntent().getStringExtra(vectorFieldName).split(Trigger.triggerParameter2Split);
etDesiredAzimuth.setText(values[0]);
etDesiredAzimuthTolerance.setText(values[1]);
etDesiredPitch.setText(values[2]);
etDesiredPitchTolerance.setText(values[3]);
etDesiredRoll.setText(values[4]);
etDesiredRollTolerance.setText(values[5]);
}
catch(Exception e)
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show();
Miscellaneous.logEvent("e", "DevicePositionTrigger", "There\'s something wrong with a device position trigger. Content: " + getIntent().getStringExtra(vectorFieldName) + ", " + Log.getStackTraceString(e), 1);
}
}
bApplyPositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// Round the values. Too long decimals will destroy the layout
if(!StringUtils.isEmpty(currentAzimuth.getText()))
etDesiredAzimuth.setText(String.valueOf(Math.round(Float.parseFloat(currentAzimuth.getText().toString()))));
if(!StringUtils.isEmpty(currentPitch.getText()))
etDesiredPitch.setText(String.valueOf(Math.round(Float.parseFloat(currentPitch.getText().toString()))));
if(!StringUtils.isEmpty(currentRoll.getText()))
etDesiredRoll.setText(String.valueOf(Math.round(Float.parseFloat(currentRoll.getText().toString()))));
}
});
bSavePositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(!checkInputs(true))
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.enterValidNumbersIntoAllFields), Toast.LENGTH_LONG).show();
}
else
{
// Save
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkDevicePositionApplies.isChecked());
returnData.putExtra(vectorFieldName,
etDesiredAzimuth.getText().toString() + Trigger.triggerParameter2Split +
etDesiredAzimuthTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitch.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitchTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRoll.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRollTolerance.getText().toString());
setResult(RESULT_OK, returnData);
finish();
}
}
});
}
boolean checkInputs(boolean showMessages)
{
if(
!StringUtils.isEmpty(etDesiredAzimuth.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuth.getText().toString())
&&
!StringUtils.isEmpty(etDesiredAzimuthTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuthTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitch.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitch.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitchTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitchTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRoll.getText().toString()) && Miscellaneous.isNumeric(etDesiredRoll.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRollTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredRollTolerance.getText().toString())
)
{
float da = Float.parseFloat(etDesiredAzimuth.getText().toString());
float dp = Float.parseFloat(etDesiredPitch.getText().toString());
float dr = Float.parseFloat(etDesiredRoll.getText().toString());
if(Math.abs(da) > 180 || Math.abs(dp) > 180 || Math.abs(dr) > 180)
{
return false;
}
if(showMessages)
{
float dat = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
float dpt = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
float drt = Float.parseFloat(etDesiredRollTolerance.getText().toString());
/*
The user may enter a tolerance of 180° for two directions, but not all three.
Otherwise this trigger would always apply.
*/
if (Math.abs(dat) >= 180 && Math.abs(dpt) >= 180 && Math.abs(drt) >= 180)
{
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.toleranceOf180OnlyAllowedIn2Fields), ActivityManageTriggerDeviceOrientation.this).show();
return false;
}
}
return true;
}
return false;
}
@Override
protected void onResume()
{
super.onResume();
DeviceOrientationListener.getInstance().startSensorFromConfigActivity(ActivityManageTriggerDeviceOrientation.this, this);
}
@Override
protected void onPause()
{
super.onPause();
DeviceOrientationListener.getInstance().stopSensorFromConfigActivity();
}
public class InputFilterMinMax implements InputFilter
{
private float minimumValue;
private float maximumValue;
public InputFilterMinMax(float minimumValue, float maximumValue)
{
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
}
private boolean isInRange(float a, float b, float c)
{
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
try
{
int input = Integer.parseInt(dest.subSequence(0, dstart).toString() + source + dest.subSequence(dend, dest.length()));
if (isInRange(minimumValue, maximumValue, input))
return null;
}
catch (NumberFormatException nfe)
{
}
return "";
}
}
}
@@ -31,6 +31,13 @@ import static com.jens.automation2.Trigger.triggerParameter2Split;
public class ActivityManageTriggerNotification extends Activity
{
public static final String intentNameNotificationApp = "app";
public static final String intentNameNotificationTitleDir = "titleDir";
public static final String intentNameNotificationTitle = "title";
public static final String intentNameNotificationTextDir = "textDir";
public static final String intentNameNotificationText = "text";
public static final String intentNameNotificationDirection = "direction";
public static Trigger editedNotificationTrigger;
boolean edit = false;
ProgressDialog progressDialog = null;
@@ -323,12 +330,12 @@ public class ActivityManageTriggerNotification extends Activity
else
{
Intent data = new Intent();
data.putExtra("direction", chkNotificationDirection.isChecked());
data.putExtra("app", app);
data.putExtra("titleDir", titleDir);
data.putExtra("title", title);
data.putExtra("textDir", textDir);
data.putExtra("text", text);
data.putExtra(intentNameNotificationDirection, chkNotificationDirection.isChecked());
data.putExtra(intentNameNotificationApp, app);
data.putExtra(intentNameNotificationTitleDir, titleDir);
data.putExtra(intentNameNotificationTitle, title);
data.putExtra(intentNameNotificationTextDir, textDir);
data.putExtra(intentNameNotificationText, text);
ActivityManageTriggerNotification.this.setResult(RESULT_OK, data);
}
@@ -395,4 +402,4 @@ public class ActivityManageTriggerNotification extends Activity
getActionStartActivityDialog1().show();
}
}
}
}
@@ -0,0 +1,117 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.List;
public class ActivityManageTriggerProfile extends Activity
{
public static final String profileFieldName = "profileName";
boolean editMode = false;
Button bSaveTriggerProfile;
Spinner spinnerProfiles;
CheckBox chkProfileActive, chkProfileCheckSettings;
ArrayAdapter<Profile> profileSpinnerAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_profile);
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile);
spinnerProfiles = (Spinner)findViewById(R.id.spinnerProfiles);
chkProfileActive = (CheckBox)findViewById(R.id.chkProfileActive);
chkProfileCheckSettings = (CheckBox)findViewById(R.id.chkProfileCheckSettings);
try
{
profileSpinnerAdapter = new ArrayAdapter<Profile>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Profile.getProfileCollection());
loadProfileItems();
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "ActivityManageTriggerProfile", Log.getStackTraceString(e), 1);
}
if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2))
{
editMode = true;
boolean active = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true);
chkProfileActive.setChecked(active);
try
{
String values[] = getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split);
if(values.length >= 2)
{
boolean checkSettings = Boolean.parseBoolean(values[0]);
chkProfileCheckSettings.setChecked(checkSettings);
String profileName = values[0];
List<Profile> profileList = Profile.getProfileCollection();
for(int i = 0; i < profileList.size(); i++)
{
if(profileList.get(i).getName().equals(profileName))
{
spinnerProfiles.setSelection(i);
break;
}
}
}
}
catch(Exception e)
{
Toast.makeText(ActivityManageTriggerProfile.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show();
Miscellaneous.logEvent("e", "ActivityManageTriggerProfile", "There\'s something wrong with parameters. Content: " + getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2) + ", " + Log.getStackTraceString(e), 1);
}
}
bSaveTriggerProfile.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkProfileActive.isChecked());
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter2,
spinnerProfiles.getSelectedItem().toString() + Trigger.triggerParameter2Split +
chkProfileCheckSettings.isChecked());
setResult(RESULT_OK, returnData);
finish();
}
});
}
private void loadProfileItems()
{
try
{
if(spinnerProfiles.getAdapter() == null)
spinnerProfiles.setAdapter(profileSpinnerAdapter);
profileSpinnerAdapter.notifyDataSetChanged();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
}
}
@@ -6,11 +6,16 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TimePicker;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -18,8 +23,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
{
Button bSaveTimeFrame;
TimePicker startPicker, stopPicker;
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday;
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday, chkRepeat;
RadioButton radioTimeFrameEntering, radioTimeFrameLeaving;
EditText etRepeatEvery;
public static Trigger editedTimeFrameTrigger = null;
@@ -44,7 +50,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
checkSunday = (CheckBox)findViewById(R.id.checkSunday);
radioTimeFrameEntering = (RadioButton)findViewById(R.id.radioTimeFrameEntering);
radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving);
chkRepeat = (CheckBox)findViewById(R.id.chkRepeat);
etRepeatEvery = (EditText)findViewById(R.id.etRepeatEvery);
bSaveTimeFrame.setOnClickListener(new OnClickListener()
{
@Override
@@ -92,11 +100,43 @@ public class ActivityManageTriggerTimeFrame extends Activity
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.selectOneDay), Toast.LENGTH_LONG).show();
return;
}
}
boolean goOn = false;
if(chkRepeat.isChecked())
{
if(!StringUtils.isEmpty(etRepeatEvery.getText().toString()))
{
try
{
long value = Long.parseLong(etRepeatEvery.getText().toString());
if(value > 0)
{
goOn = true;
}
}
catch(Exception e)
{
}
}
}
else
goOn = true;
if(!goOn)
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterRepetitionTime), Toast.LENGTH_LONG).show();
return;
}
if(editedTimeFrameTrigger.getTimeFrame() == null)
{
// add new one
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList));
if(chkRepeat.isChecked())
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, Long.parseLong(etRepeatEvery.getText().toString())));
else
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, 0));
}
else
{
// edit one
@@ -104,6 +144,11 @@ public class ActivityManageTriggerTimeFrame extends Activity
editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStop(stopTime);
editedTimeFrameTrigger.getTimeFrame().getDayList().clear();
editedTimeFrameTrigger.getTimeFrame().setDayList(dayList);
if(chkRepeat.isChecked())
editedTimeFrameTrigger.getTimeFrame().setRepetition(Long.parseLong(etRepeatEvery.getText().toString()));
else
editedTimeFrameTrigger.getTimeFrame().setRepetition(0);
}
editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked());
@@ -112,6 +157,15 @@ public class ActivityManageTriggerTimeFrame extends Activity
finish();
}
});
chkRepeat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
etRepeatEvery.setEnabled(isChecked);
}
});
if(editedTimeFrameTrigger.getTimeFrame() != null)
loadVariableIntoGui();
@@ -158,6 +212,12 @@ public class ActivityManageTriggerTimeFrame extends Activity
break;
}
}
if(editedTimeFrameTrigger.getTimeFrame().getRepetition() > 0)
{
chkRepeat.setChecked(true);
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
}
}
}
@@ -35,6 +35,9 @@ import java.util.List;
public class ActivityManageTriggerWifi extends Activity
{
public final static String intentNameWifiState = "wifiState";
public final static String intentNameWifiName = "wifiName";
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
EditText etTriggerWifiName;
Spinner spinnerWifiList;
@@ -3,8 +3,8 @@ package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
@@ -15,14 +15,13 @@ import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.NotificationManagerCompat;
import com.jens.automation2.receivers.NotificationListener;
@@ -46,6 +45,8 @@ public class ActivityPermissions extends Activity
private static final int requestCodeForPermissionsNotificationPolicy = 12044;
private static final int requestCodeForPermissionsBackgroundLocation = 12045;
private static final int requestCodeForPermissionsNotifications = 12046;
private static final int requestCodeForPermissionsDeviceAdmin = 12047;
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
protected String[] specificPermissionsToRequest = null;
public static String intentExtraName = "permissionsToBeRequested";
@@ -238,9 +239,9 @@ public class ActivityPermissions extends Activity
if(
s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
||
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
||
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
)
{
if (!Miscellaneous.googleToBlameForLocation(true))
@@ -282,6 +283,16 @@ public class ActivityPermissions extends Activity
{
return verifyNotificationPermission();
}
else if (s.equals(Manifest.permission.BIND_DEVICE_ADMIN))
{
return haveDeviceAdmin();
}
else if (s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
String packageName = context.getApplicationContext().getPackageName();
return pm.isIgnoringBatteryOptimizations(packageName);
}
else
{
int res = context.checkCallingOrSelfPermission(s);
@@ -292,6 +303,28 @@ public class ActivityPermissions extends Activity
return true;
}
public static boolean haveDeviceAdmin()
{
DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName compName = new ComponentName(Miscellaneous.getAnyContext(), DeviceAdmin.class);
boolean active = deviceManger.isAdminActive(compName);
return active;
}
public static void requestDeviceAdmin()
{
if(!haveDeviceAdmin())
{
// DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName compName = new ComponentName(ActivityPermissions.getInstance(), DeviceAdmin.class) ;
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN );
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN , compName );
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION , Miscellaneous.getAnyContext().getResources().getString(R.string.deviceAdminNote));
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsDeviceAdmin);
}
}
public static String[] getRequiredPermissions(boolean onlyGeneral)
{
ArrayList<String> requiredPermissions = new ArrayList<String>();
@@ -308,20 +341,18 @@ public class ActivityPermissions extends Activity
addToArrayListUnique("android.permission.RECEIVE_BOOT_COMPLETED", requiredPermissions);
*/
// if (!havePermission(ActivityPermissions.writeExternalStoragePermissionName, workingContext))
// addToArrayListUnique(ActivityPermissions.writeExternalStoragePermissionName, requiredPermissions);
if(!havePermission(Manifest.permission.WRITE_SETTINGS, workingContext))
{
for (Profile profile : Profile.getProfileCollection())
{
if (profile.changeIncomingCallsRingtone)
{
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
}
}
}
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
if (!onlyGeneral)
{
for (Rule rule : Rule.getRuleCollection())
@@ -333,9 +364,9 @@ public class ActivityPermissions extends Activity
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
||
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
)
{
if (!Miscellaneous.googleToBlameForLocation(true))
@@ -531,6 +562,12 @@ public class ActivityPermissions extends Activity
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case setBluetoothTethering:
//addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case setWifi:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
@@ -557,9 +594,9 @@ public class ActivityPermissions extends Activity
if(
action.getParameter2().contains(Actions.wireguard_tunnel_up)
||
action.getParameter2().contains(Actions.wireguard_tunnel_down)
action.getParameter2().contains(Actions.wireguard_tunnel_down)
||
action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
)
addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions);
// if(
@@ -587,40 +624,37 @@ public class ActivityPermissions extends Activity
break;
case turnUsbTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case turnUsbTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case turnWifiOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case waitBeforeNextAction:
break;
case wakeupDevice:
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
break;
case playSound:
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
break;
case turnScreenOnOrOff:
if(action.getParameter1())
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
else
addToArrayListUnique(Manifest.permission.BIND_DEVICE_ADMIN, requiredPermissions);
break;
default:
break;
}
@@ -696,13 +730,6 @@ public class ActivityPermissions extends Activity
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.ACCESS_COARSE_LOCATION:
// usingElements.add(getResources().getString(R.string.android_permission_ACCESS_COARSE_LOCATION));
usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.ACCESS_FINE_LOCATION:
usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
@@ -759,14 +786,6 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
/*case "android.permission.BATTERY_STATS":
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.batteryLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.charging))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;*/
case Manifest.permission.BLUETOOTH_ADMIN:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
@@ -834,6 +853,13 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.playSound))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.BIND_DEVICE_ADMIN:
for(String ruleName : getRulesUsing(Action.Action_Enum.turnScreenOnOrOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS:
usingElements.add(getResources().getString(R.string.recommendedForBetterReliability));
break;
}
return usingElements;
@@ -861,6 +887,14 @@ public class ActivityPermissions extends Activity
}
}
if (requestCode == requestCodeForPermissionsDeviceAdmin)
{
NotificationManager mNotificationManager = (NotificationManager) ActivityPermissions.this.getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager.isNotificationPolicyAccessGranted())
requestPermissions(cachedPermissionsToRequest, true);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
if (requestCode == requestCodeForPermissionsBackgroundLocation)
@@ -873,6 +907,10 @@ public class ActivityPermissions extends Activity
if (requestCode == requestCodeForPermissionsNotifications)
if(havePermission(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
if (requestCode == requestCodeForPermissionsBatteryOptimization)
if(havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
}
}
@@ -923,12 +961,18 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
return;
}
if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestDeviceAdmin();
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
// intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
return;
}
@@ -936,10 +980,20 @@ public class ActivityPermissions extends Activity
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivityForResult(intent, requestCodeForPermissionsNotifications);
return;
}
else if(s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
String packageName = getApplicationContext().getPackageName();
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, requestCodeForPermissionsBatteryOptimization);
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.readLocation), getResources().getString(R.string.pleaseGiveBgLocation), ActivityPermissions.this);
@@ -968,7 +1022,7 @@ public class ActivityPermissions extends Activity
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
&&
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
)
{
requiredPermissions.remove(Manifest.permission.PROCESS_OUTGOING_CALLS);
@@ -978,8 +1032,6 @@ public class ActivityPermissions extends Activity
if(requiredPermissions.contains(Manifest.permission.SEND_SMS))
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
// &&
// Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
)
{
requiredPermissions.remove(Manifest.permission.SEND_SMS);
@@ -996,11 +1048,8 @@ public class ActivityPermissions extends Activity
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
// Toast.makeText(ActivityPermissions.this, "Requesting permissions. Amount: " + String.valueOf(requiredPermissions.size()), Toast.LENGTH_LONG).show();
if(requiredPermissions.size() > 0)
requestPermissions(requiredPermissions.toArray(new String[requiredPermissions.size()]), requestCodeForPermissions);
// else
// Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.permissionsRequiredNotAvailable), ActivityPermissions.this).show();
}
else
setHaveAllPermissions();
@@ -1018,17 +1067,11 @@ public class ActivityPermissions extends Activity
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
Miscellaneous.logEvent("i", "onRequestPermissionsResult()", "onRequestPermissionsResult()", 3);
// Toast.makeText(ActivityPermissions.this, "onRequestPermissionsResult()", Toast.LENGTH_LONG).show();
// ArrayList<String> disabledFeatures = new ArrayList<String>();
ArrayList<String> deniedPermissions = new ArrayList<String>();
if (requestCode == requestCodeForPermissions)
{
/*ArrayList<String> affectedGeneralList = new ArrayList<String>();
ArrayList<String> affectedTriggersList = new ArrayList<String>();
ArrayList<String> affectedActionList = new ArrayList<String>();*/
for (int i=0; i < grantResults.length; i++)
{
if(permissions[i].equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
@@ -1088,8 +1131,8 @@ public class ActivityPermissions extends Activity
if(deniedPermissions.size() > 0)
{
/*
The user denied certain permissions. With the exception of write-storage we need to live with that
and simply disable features while keeping the notification alive. The user may dismiss it anyway.
The user denied certain permissions. We need to live with that and simply disable
features while keeping the notification alive. The user may dismiss it anyway.
*/
Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(", ", deniedPermissions), 3);
@@ -1314,10 +1357,7 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("setWifiTethering", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setWifiTethering", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setWifiTethering", Manifest.permission.ACCESS_NETWORK_STATE);
// mapActionPermissions.put("speakText", Manifest.permission.ACCESS_NOTIFICATION_POLICY);
// mapActionPermissions.put("startOtherActivity", "");
mapActionPermissions.put("triggerUrl", Manifest.permission.INTERNET);
// Hier müßte ein Hinweis kommen, daß nur die Variablen verwendet werden können, für die es Rechte gibt.
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH_ADMIN);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.ACCESS_NETWORK_STATE);
@@ -1347,209 +1387,6 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK);
}
/*
<string name="android.permission.SEND_SMS"></string>
<string name="android.permission.SEND_SMS_NO_CONFIRMATION"></string>
<string name="android.permission.RECEIVE_SMS"></string>
<string name="android.permission.RECEIVE_MMS"></string>
<string name="android.permission.RECEIVE_EMERGENCY_BROADCAST"></string>
<string name="android.permission.READ_CELL_BROADCASTS"></string>
<string name="android.permission.READ_SMS"></string>
<string name="android.permission.WRITE_SMS"></string>
<string name="android.permission.RECEIVE_WAP_PUSH"></string>
<string name="android.permission.READ_CONTACTS"></string>
<string name="android.permission.WRITE_CONTACTS"></string>
<string name="android.permission.BIND_DIRECTORY_SEARCH"></string>
<string name="android.permission.READ_CALL_LOG"></string>
<string name="android.permission.WRITE_CALL_LOG"></string>
<string name="android.permission.READ_SOCIAL_STREAM"></string>
<string name="android.permission.WRITE_SOCIAL_STREAM"></string>
<string name="android.permission.READ_PROFILE"></string>
<string name="android.permission.WRITE_PROFILE"></string>
<string name="android.permission.READ_CALENDAR"></string>
<string name="android.permission.WRITE_CALENDAR"></string>
<string name="android.permission.READ_USER_DICTIONARY"></string>
<string name="android.permission.WRITE_USER_DICTIONARY"></string>
<string name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"></string>
<string name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"></string>
<string name="com.android.alarm.permission.SET_ALARM"></string>
<string name="com.android.voicemail.permission.ADD_VOICEMAIL"></string>
<string name="android.permission.ACCESS_FINE_LOCATION"></string>
<string name="android.permission.ACCESS_COARSE_LOCATION"></string>
<string name="android.permission.ACCESS_MOCK_LOCATION"></string>
<string name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></string>
<string name="android.permission.INSTALL_LOCATION_PROVIDER"></string>
<string name="android.permission.INTERNET"></string>
<string name="android.permission.ACCESS_NETWORK_STATE"></string>
<string name="android.permission.ACCESS_WIFI_STATE"></string>
<string name="android.permission.CHANGE_WIFI_STATE"></string>
<string name="android.permission.ACCESS_WIMAX_STATE"></string>
<string name="android.permission.CHANGE_WIMAX_STATE"></string>
<string name="android.permission.BLUETOOTH"></string>
<string name="android.permission.BLUETOOTH_ADMIN"></string>
<string name="android.permission.BLUETOOTH_STACK"></string>
<string name="android.permission.NFC"></string>
<string name="android.permission.CONNECTIVITY_INTERNAL"></string>
<string name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"></string>
<string name="android.permission.GET_ACCOUNTS"></string>
<string name="android.permission.AUTHENTICATE_ACCOUNTS"></string>
<string name="android.permission.USE_CREDENTIALS"></string>
<string name="android.permission.MANAGE_ACCOUNTS"></string>
<string name="android.permission.ACCOUNT_MANAGER"></string>
<string name="android.permission.CHANGE_WIFI_MULTICAST_STATE"></string>
<string name="android.permission.VIBRATE"></string>
<string name="android.permission.FLASHLIGHT"></string>
<string name="android.permission.WAKE_LOCK"></string>
<string name="android.permission.MODIFY_AUDIO_SETTINGS"></string>
<string name="android.permission.MANAGE_USB"></string>
<string name="android.permission.ACCESS_MTP"></string>
<string name="android.permission.HARDWARE_TEST"></string>
<string name="android.permission.NET_ADMIN"></string>
<string name="android.permission.REMOTE_AUDIO_PLAYBACK"></string>
<string name="android.permission.RECORD_AUDIO"></string>
<string name="android.permission.CAMERA"></string>
<string name="android.permission.PROCESS_OUTGOING_CALLS"></string>
<string name="android.permission.MODIFY_PHONE_STATE"></string>
<string name="android.permission.READ_PHONE_STATE"></string>
<string name="android.permission.READ_PRIVILEGED_PHONE_STATE"></string>
<string name="android.permission.CALL_PHONE"></string>
<string name="android.permission.USE_SIP"></string>
<string name="android.permission.READ_EXTERNAL_STORAGE"></string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE"></string>
<string name="android.permission.WRITE_MEDIA_STORAGE"></string>
<string name="android.permission.DISABLE_KEYGUARD"></string>
<string name="android.permission.GET_TASKS"></string>
<string name="android.permission.INTERACT_ACROSS_USERS"></string>
<string name="android.permission.INTERACT_ACROSS_USERS_FULL"></string>
<string name="android.permission.MANAGE_USERS"></string>
<string name="android.permission.GET_DETAILED_TASKS"></string>
<string name="android.permission.REORDER_TASKS"></string>
<string name="android.permission.REMOVE_TASKS"></string>
<string name="android.permission.START_ANY_ACTIVITY"></string>
<string name="android.permission.RESTART_PACKAGES"></string>
<string name="android.permission.KILL_BACKGROUND_PROCESSES"></string>
<string name="android.permission.SYSTEM_ALERT_WINDOW"></string>
<string name="android.permission.SET_WALLPAPER"></string>
<string name="android.permission.SET_WALLPAPER_HINTS"></string>
<string name="android.permission.SET_TIME"></string>
<string name="android.permission.SET_TIME_ZONE"></string>
<string name="android.permission.EXPAND_STATUS_BAR"></string>
<string name="android.permission.READ_SYNC_SETTINGS"></string>
<string name="android.permission.WRITE_SYNC_SETTINGS"></string>
<string name="android.permission.READ_SYNC_STATS"></string>
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
<string name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE"></string>
<string name="android.permission.CHANGE_CONFIGURATION"></string>
<string name="android.permission.WRITE_SETTINGS"></string>
<string name="android.permission.WRITE_GSERVICES"></string>
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
<string name="android.permission.CHANGE_CONFIGURATION"></string>
<string name="android.permission.FORCE_STOP_PACKAGES"></string>
<string name="android.permission.RETRIEVE_WINDOW_CONTENT"></string>
<string name="android.permission.SET_ANIMATION_SCALE"></string>
<string name="android.permission.PERSISTENT_ACTIVITY"></string>
<string name="android.permission.GET_PACKAGE_SIZE"></string>
<string name="android.permission.SET_PREFERRED_APPLICATIONS"></string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED"></string>
<string name="android.permission.BROADCAST_STICKY"></string>
<string name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></string>
<string name="android.permission.MOUNT_FORMAT_FILESYSTEMS"></string>
<string name="android.permission.ASEC_ACCESS"></string>
<string name="android.permission.ASEC_CREATE"></string>
<string name="android.permission.ASEC_DESTROY"></string>
<string name="android.permission.ASEC_MOUNT_UNMOUNT"></string>
<string name="android.permission.ASEC_RENAME"></string>
<string name="android.permission.WRITE_APN_SETTINGS"></string>
<string name="android.permission.SUBSCRIBED_FEEDS_READ"></string>
<string name="android.permission.SUBSCRIBED_FEEDS_WRITE"></string>
<string name="android.permission.CHANGE_NETWORK_STATE"></string>
<string name="android.permission.CLEAR_APP_CACHE"></string>
<string name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"></string>
<string name="android.permission.WRITE_SECURE_SETTINGS"></string>
<string name="android.permission.DUMP"></string>
<string name="android.permission.READ_LOGS"></string>
<string name="android.permission.SET_DEBUG_APP"></string>
<string name="android.permission.SET_PROCESS_LIMIT"></string>
<string name="android.permission.SET_ALWAYS_FINISH"></string>
<string name="android.permission.SIGNAL_PERSISTENT_PROCESSES"></string>
<string name="android.permission.DIAGNOSTIC"></string>
<string name="android.permission.STATUS_BAR"></string>
<string name="android.permission.STATUS_BAR_SERVICE"></string>
<string name="android.permission.FORCE_BACK"></string>
<string name="android.permission.UPDATE_DEVICE_STATS"></string>
<string name="android.permission.INTERNAL_SYSTEM_WINDOW"></string>
<string name="android.permission.MANAGE_APP_TOKENS"></string>
<string name="android.permission.FREEZE_SCREEN"></string>
<string name="android.permission.INJECT_EVENTS"></string>
<string name="android.permission.FILTER_EVENTS"></string>
<string name="android.permission.RETRIEVE_WINDOW_INFO"></string>
<string name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"></string>
<string name="android.permission.MAGNIFY_DISPLAY"></string>
<string name="android.permission.SET_ACTIVITY_WATCHER"></string>
<string name="android.permission.SHUTDOWN"></string>
<string name="android.permission.STOP_APP_SWITCHES"></string>
<string name="android.permission.READ_INPUT_STATE"></string>
<string name="android.permission.BIND_INPUT_METHOD"></string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE"></string>
<string name="android.permission.BIND_TEXT_SERVICE"></string>
<string name="android.permission.BIND_VPN_SERVICE"></string>
<string name="android.permission.BIND_WALLPAPER"></string>
<string name="android.permission.BIND_DEVICE_ADMIN"></string>
<string name="android.permission.SET_ORIENTATION"></string>
<string name="android.permission.SET_POINTER_SPEED"></string>
<string name="android.permission.SET_KEYBOARD_LAYOUT"></string>
<string name="android.permission.INSTALL_PACKAGES"></string>
<string name="android.permission.CLEAR_APP_USER_DATA"></string>
<string name="android.permission.DELETE_CACHE_FILES"></string>
<string name="android.permission.DELETE_PACKAGES"></string>
<string name="android.permission.MOVE_PACKAGE"></string>
<string name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"></string>
<string name="android.permission.GRANT_REVOKE_PERMISSIONS"></string>
<string name="android.permission.ACCESS_SURFACE_FLINGER"></string>
<string name="android.permission.READ_FRAME_BUFFER"></string>
<string name="android.permission.CONFIGURE_WIFI_DISPLAY"></string>
<string name="android.permission.CONTROL_WIFI_DISPLAY"></string>
<string name="android.permission.BRICK"></string>
<string name="android.permission.REBOOT"></string>
<string name="android.permission.DEVICE_POWER"></string>
<string name="android.permission.NET_TUNNELING"></string>
<string name="android.permission.FACTORY_TEST"></string>
<string name="android.permission.BROADCAST_PACKAGE_REMOVED"></string>
<string name="android.permission.BROADCAST_SMS"></string>
<string name="android.permission.BROADCAST_WAP_PUSH"></string>
<string name="android.permission.MASTER_CLEAR"></string>
<string name="android.permission.CALL_PRIVILEGED"></string>
<string name="android.permission.PERFORM_CDMA_PROVISIONING"></string>
<string name="android.permission.CONTROL_LOCATION_UPDATES"></string>
<string name="android.permission.ACCESS_CHECKIN_PROPERTIES"></string>
<string name="android.permission.PACKAGE_USAGE_STATS"></string>
<string name="android.permission.BATTERY_STATS"></string>
<string name="android.permission.BACKUP"></string>
<string name="android.permission.CONFIRM_FULL_BACKUP"></string>
<string name="android.permission.BIND_REMOTEVIEWS"></string>
<string name="android.permission.BIND_APPWIDGET"></string>
<string name="android.permission.BIND_KEYGUARD_APPWIDGET"></string>
<string name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"></string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"></string>
<string name="android.permission.GLOBAL_SEARCH"></string>
<string name="android.permission.GLOBAL_SEARCH_CONTROL"></string>
<string name="android.permission.SET_WALLPAPER_COMPONENT"></string>
<string name="android.permission.READ_DREAM_STATE"></string>
<string name="android.permission.WRITE_DREAM_STATE"></string>
<string name="android.permission.ACCESS_CACHE_FILESYSTEM"></string>
<string name="android.permission.COPY_PROTECTED_DATA"></string>
<string name="android.permission.CRYPT_KEEPER"></string>
<string name="android.permission.READ_NETWORK_USAGE_HISTORY"></string>
<string name="android.permission.MANAGE_NETWORK_POLICY"></string>
<string name="android.permission.MODIFY_NETWORK_ACCOUNTING"></string>
<string name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"></string>
<string name="android.permission.PACKAGE_VERIFICATION_AGENT"></string>
<string name="android.permission.BIND_PACKAGE_VERIFIER"></string>
<string name="android.permission.SERIAL_PORT"></string>
<string name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"></string>
<string name="android.permission.UPDATE_LOCK"></string>
*/
public static boolean isPermissionDeclaratedInManifest(Context context, String permission)
{
PackageManager pm = context.getPackageManager();
@@ -1568,12 +1405,11 @@ public class ActivityPermissions extends Activity
ArrayList<String> requestedPermissionsArrayList = new ArrayList<String>();
requestedPermissionsArrayList.addAll(requestedPermissionsList);
return (requestedPermissionsArrayList.contains(permission));
// Log.i(ExConsts.TAG, ""+requestedPermissionsArrayList);
}
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
Miscellaneous.logEvent("w", "ActivityPermissions", Log.getStackTraceString(e), 2);
}
return false;
@@ -30,14 +30,14 @@ public class ActivityVolumeTest extends Activity
instance = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_volume_test);
setContentView(R.layout.activity_volume_calibration);
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
etReferenceValue = (EditText)findViewById(R.id.etReferenceValue);
sbReferenceValue = (SeekBar)findViewById(R.id.sbReferenceValue);
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeTestExplanation);
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeCalibrationExplanation);
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeTesterExplanation), String.valueOf(volumeRefreshInterval)));
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeCalibrationExplanation), String.valueOf(volumeRefreshInterval)));
etReferenceValue.setText(String.valueOf(Settings.referenceValueForNoiseLevelMeasurements));
@@ -199,6 +199,7 @@ public class AutomationService extends Service implements OnInitListener
if (checkStartupRequirements(this, startAtBoot))
{
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Miscellaneous.logEvent("i", "Service", ActivityMaintenance.getSystemInfo(), 1);
startUpRoutine();
@@ -273,16 +274,7 @@ public class AutomationService extends Service implements OnInitListener
public void applySettingsAndRules()
{
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate)
{
if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this);
}
else
{
if (ttsEngine != null)
ttsEngine.shutdown();
}
checkForTtsEngine();
startLocationProvider();
ReceiverCoordinator.startAllReceivers();
@@ -305,7 +297,7 @@ public class AutomationService extends Service implements OnInitListener
public void checkForTtsEngine()
{
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate | Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
if (Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate || Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
{
if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this);
@@ -352,12 +344,8 @@ public class AutomationService extends Service implements OnInitListener
if(r.isRuleActive())
{
if(!r.haveEnoughPermissions())
// for (String permission : ActivityPermissions.getPermissionsForRule(r))
{
// if (!ActivityPermissions.havePermission(permission, AutomationService.this))
{
// r.setRuleActive(false);
// r.change(AutomationService.this);
if(!displayNotification)
{
displayNotification = true;
@@ -410,10 +398,7 @@ public class AutomationService extends Service implements OnInitListener
public void cancelNotification()
{
// stopForeground(false);
NotificationManagerCompat.from(AutomationService.this).cancelAll();
// NotificationManagerCompat.from(AutomationService.this).cancel(ActivityPermissions.notificationIdPermissions);
// NotificationManagerCompat.from(AutomationService.this).cancel(AutomationService.notificationIdRestrictions);
}
protected void checkForMissingBackgroundLocationPermission()
@@ -450,7 +435,6 @@ public class AutomationService extends Service implements OnInitListener
private void stopRoutine()
{
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
// Log.i("STOP", "Stopping");
try
{
myLocationProvider.stopLocationService();
@@ -479,7 +463,6 @@ public class AutomationService extends Service implements OnInitListener
builder.setWhen(System.currentTimeMillis());
builder.setContentIntent(myPendingIntent);
// Notification defaultNotification = new Notification();
Notification defaultNotification = builder.build();
defaultNotification.icon = R.drawable.ic_launcher;
@@ -497,31 +480,6 @@ public class AutomationService extends Service implements OnInitListener
// defaultNotification.ledOffMS = 1500;
return builder;
/*NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(AutomationService.getInstance());
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(Notification.CATEGORY_EVENT);
builder.setWhen(System.currentTimeMillis());
builder.setContentTitle("Automation");
builder.setSmallIcon(R.drawable.ic_launcher);
// builder.setContentText(textToDisplay);
// builder.setSmallIcon(icon);
// builder.setContentIntent(pendingIntent);
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel("notify_001", "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
return builder;*/
}
protected static NotificationCompat.Builder createDefaultNotificationBuilder()
@@ -571,79 +529,68 @@ public class AutomationService extends Service implements OnInitListener
if(instance != null)
{
// if(Settings.showIconWhenServiceIsRunning)
// {
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
String bodyText="";
String lastRuleString = "";
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
try
{
PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
}
catch(NullPointerException e)
{
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
}
}
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
String bodyText="";
String lastRuleString = "";
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
try
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
}
catch(Exception e)
catch(NullPointerException e)
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
}
}
String textToDisplay = bodyText + " " + lastRuleString;
// if(Build.VERSION.SDK_INT < 11)
// {
// myNotification.setLatestEventInfo(instance, "Automation", textToDisplay, myPendingIntent);
// }
// else
// {
if(notificationBuilder == null)
notificationBuilder = createDefaultNotificationBuilder();
try
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
}
catch(Exception e)
{
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
}
notificationBuilder.setContentText(textToDisplay);
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
String textToDisplay = bodyText + " " + lastRuleString;
myNotification = notificationBuilder.build();
myNotification.defaults = 0;
// }
if(notificationBuilder == null)
notificationBuilder = createDefaultNotificationBuilder();
notificationBuilder.setContentText(textToDisplay);
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
myNotification = notificationBuilder.build();
myNotification.defaults = 0;
// NotificationManager notificationManager = (NotificationManager) instance.getSystemService(NOTIFICATION_SERVICE);
// hide the notification after its selected
// hide the notification after its selected
// myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
myNotification.flags |= Notification.FLAG_NO_CLEAR;
myNotification.flags |= Notification.FLAG_NO_CLEAR;
// notificationManager.notify(notificationId, myNotification);
instance.startForeground(notificationId, myNotification);
// }
// else
// instance.startForeground(notificationId, null); // do not show icon in task bar
instance.startForeground(notificationId, myNotification);
}
}
@@ -667,18 +614,18 @@ public class AutomationService extends Service implements OnInitListener
**/
public void speak(String text, boolean force)
{
if(text.length() > 0 && (force | Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate))
if(text.length() > 0 && (force || Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate))
{
AudioManager myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int mode = myAudioManager.getRingerMode();
if(
(mode == AudioManager.RINGER_MODE_NORMAL && Settings.useTextToSpeechOnNormal)
|
||
(mode == AudioManager.RINGER_MODE_VIBRATE && Settings.useTextToSpeechOnVibrate)
|
||
(mode == AudioManager.RINGER_MODE_SILENT && Settings.useTextToSpeechOnSilent)
|
||
force
)
{
@@ -708,12 +655,12 @@ public class AutomationService extends Service implements OnInitListener
{}
}
}
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking " + text + " in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3);
e.printStackTrace();
}
}
}
@@ -726,31 +673,6 @@ public class AutomationService extends Service implements OnInitListener
return false;
else
return true;
// boolean isActivityFound = false;
// ActivityManager activityManager = (ActivityManager)context.getSystemService (Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
// isActivityFound = false;
// for (int i = 0; i < activitys.size(); i++)
// {
// if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.jens.automation/com.jens.automation.ActivityMainScreen}"))
// {
// isActivityFound = true;
// }
// }
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity running status: " + String.valueOf(isActivityFound), 5);
// return isActivityFound;
// ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
//
// for (RunningTaskInfo task : tasks)
// {
// if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
// return true;
// }
//
// return false;
}
public static boolean isMyServiceRunning(Context context)
@@ -762,7 +684,6 @@ public class AutomationService extends Service implements OnInitListener
{
if(AutomationService.class.getName().equals(service.service.getClassName()))
{
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
return true;
}
}
@@ -771,9 +692,8 @@ public class AutomationService extends Service implements OnInitListener
{
if(Log.getStackTraceString(e).contains("activate")) // Means that a poi has been activated/deactivated. Service is running.
return true;
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
}
return false;
}
}
}
@@ -0,0 +1,22 @@
package com.jens.automation2;
import android.app.admin.DeviceAdminReceiver;
import android.content.Context;
import android.content.Intent;
public class DeviceAdmin extends DeviceAdminReceiver
{
@Override
public void onEnabled (Context context , Intent intent)
{
super.onEnabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Got permission BIND_DEVICE_ADMIN.", 3);
}
@Override
public void onDisabled (Context context , Intent intent)
{
super.onDisabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Permission BIND_DEVICE_ADMIN taken.", 3);
}
}
@@ -14,6 +14,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@@ -77,6 +78,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@@ -213,7 +216,15 @@ public class Miscellaneous extends Service
return null;
}
@Override
public static int boolToInt(boolean input)
{
if(input)
return 1;
else
return 0;
}
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
@@ -541,6 +552,22 @@ public class Miscellaneous extends Service
return null;
}
public static boolean isDarkModeEnabled(Context context)
{
int mode = context.getResources().getConfiguration().uiMode;
switch(mode)
{
case 33:
case Configuration.UI_MODE_NIGHT_YES:
return true;
case 17:
case Configuration.UI_MODE_NIGHT_NO:
case Configuration.UI_MODE_NIGHT_UNDEFINED:
default:
return false;
}
}
@SuppressLint("NewApi")
public static String replaceVariablesInText(String source, Context context) throws Exception
@@ -1046,6 +1073,23 @@ public class Miscellaneous extends Service
return "";
}
public static String explode(String glue, String[] inputArray)
{
if(inputArray != null)
{
StringBuilder builder = new StringBuilder();
for (String s : inputArray)
builder.append(s + glue);
if (builder.length() > 0)
builder.delete(builder.length() - glue.length(), builder.length());
return builder.toString();
}
else
return "";
}
public static boolean isGooglePlayInstalled(Context context)
{
// return false;
@@ -1133,11 +1177,11 @@ public class Miscellaneous extends Service
}
catch (IllegalAccessException e)
{
e.printStackTrace();
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
}
catch (InvocationTargetException e)
{
e.printStackTrace();
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
}
return result;
@@ -1532,4 +1576,21 @@ public class Miscellaneous extends Service
else*/
return PhoneNumberUtils.compare(number1, number2);
}
public static String formatDate(Date input)
{
DateFormat sdf = null;
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
if(sdf == null && Settings.dateFormat != null)
sdf = new SimpleDateFormat(Settings.dateFormat);
String formattedDate;
if(sdf != null)
formattedDate = sdf.format(input);
else
formattedDate = fallBackFormatter.format(input);
return formattedDate;
}
}
@@ -23,7 +23,7 @@ import java.util.Map;
public class News
{
Calendar publishDate;
String applicablePlattform;
String applicablePlatform;
Map<String,NewsTranslation> translations = new HashMap<>();
public static class NewsTranslation
@@ -151,9 +151,9 @@ public class News
String publishDateString = neEl.getElementsByTagName("publishDate").item(0).getTextContent();
newsEntry.setPublishDate(Miscellaneous.calendarFromLong(Long.parseLong(publishDateString) * 1000));
newsEntry.setApplicablePlattform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent());
newsEntry.setApplicablePlatform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent());
if(newsEntry.getApplicablePlattform().equalsIgnoreCase("all") || newsEntry.getApplicablePlattform().equalsIgnoreCase(BuildConfig.FLAVOR))
if(newsEntry.getApplicablePlatform().equalsIgnoreCase("all") || newsEntry.getApplicablePlatform().equalsIgnoreCase(BuildConfig.FLAVOR))
returnList.add(newsEntry);
}
}
@@ -199,14 +199,14 @@ public class News
this.publishDate = publishDate;
}
public String getApplicablePlattform()
public String getApplicablePlatform()
{
return applicablePlattform;
return applicablePlatform;
}
public void setApplicablePlattform(String applicablePlattform)
public void setApplicablePlatform(String applicablePlatform)
{
this.applicablePlattform = applicablePlattform;
this.applicablePlatform = applicablePlatform;
}
@NonNull
@@ -252,8 +252,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, true);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0)
{
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@@ -264,18 +265,22 @@ public class PointOfInterest implements Comparable<PointOfInterest>
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions())
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false);
}
}
}
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Done checking POI rules.", 2);
parentService.updateNotification();
ActivityMainScreen.updateMainScreen();
}
}
public void deactivate(AutomationService parentService)
{
if(this.isActivated())
@@ -285,8 +290,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Left POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, false);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0)
{
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@@ -296,7 +302,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(parentService))
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false);
@@ -1,5 +1,6 @@
package com.jens.automation2;
import android.app.NotificationManager;
import android.content.ContentValues;
import android.content.Context;
import android.media.AudioManager;
@@ -14,10 +15,12 @@ import com.jens.automation2.Action.Action_Enum;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Profile implements Comparable<Profile>
{
protected static ArrayList<Profile> profileCollection = new ArrayList<Profile>();
protected static List<Profile> profileCollection = new ArrayList<Profile>();
protected static List<Profile> profileActivationHistory = new ArrayList<>();
protected String name;
protected String oldName;
@@ -267,7 +270,7 @@ public class Profile implements Comparable<Profile>
return hapticFeedback;
}
public static ArrayList<Profile> getProfileCollection()
public static List<Profile> getProfileCollection()
{
return profileCollection;
}
@@ -288,18 +291,12 @@ public class Profile implements Comparable<Profile>
return null;
}
public boolean delete(AutomationService myAutomationService)
{
// TODO Auto-generated method stub
return false;
}
private boolean applyRingTone(File ringtoneFile, int ringtoneType, Context context)
{
Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile.getAbsolutePath(), 3);
if(!ringtoneFile.exists() | !ringtoneFile.canRead())
if(!ringtoneFile.exists() || !ringtoneFile.canRead())
{
String message = "Ringtone file does not exist or cannot read it: " + ringtoneFile.getAbsolutePath();
Miscellaneous.logEvent("i", "Profile", message, 3);
@@ -390,11 +387,23 @@ public class Profile implements Comparable<Profile>
}
// Check if rules reference this profile
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByProfile(this);
ArrayList<Rule> rulesThatReferenceMe = Rule.findRuleCandidatesByActionProfile(this);
if(rulesThatReferenceMe.size() > 0)
{
for(Rule oneRule : rulesThatReferenceMe)
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.profileActive)
{
String[] parts = oneTrigger.getTriggerParameter2().split(Trigger.triggerParameter2Split);
parts[0] = this.name;
oneTrigger.setTriggerParameter2(Miscellaneous.explode(Trigger.triggerParameter2Split, parts));
// We don't need to save the file. This will happen anyway in PointOfInterest.writePoisToFile() below.
}
}
for(Action oneAction : oneRule.getActionSet())
{
if(oneAction.getAction() == Action_Enum.changeSoundProfile)
@@ -423,19 +432,50 @@ public class Profile implements Comparable<Profile>
return false;
}
public boolean delete()
{
for(int i = 0; i< Profile.getProfileCollection().size(); i++)
public Rule isInUseByRules()
{
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.profileActive))
{
if(Profile.getProfileCollection().get(i).getName().equals(this.getName()))
for (Rule rule : Rule.findRuleCandidatesByTriggerProfile(this))
{
Profile.getProfileCollection().remove(0);
// write to file
return XmlFileInterface.writeFile();
return rule;
}
}
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
{
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
{
return rule;
}
}
return null;
}
public boolean delete(Context context)
{
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.profileActive))
{
for (Rule rule : Rule.findRuleCandidatesByTriggerProfile(this))
{
Toast.makeText(context, String.format(context.getResources().getString(R.string.ruleXIsUsingProfileY), rule.getName(), this.getName()), Toast.LENGTH_LONG).show();
return false;
}
}
else if(Rule.isAnyRuleUsing(Action_Enum.changeSoundProfile))
{
for (Rule rule : Rule.findRuleCandidatesByActionProfile(this))
{
Toast.makeText(context, String.format(context.getResources().getString(R.string.ruleXIsUsingProfileY), rule.getName(), this.getName()), Toast.LENGTH_LONG).show();
return false;
}
}
else
{
profileCollection.remove(this);
return XmlFileInterface.writeFile();
}
return false;
}
@@ -463,6 +503,8 @@ public class Profile implements Comparable<Profile>
{
Miscellaneous.logEvent("i", "Profile " + this.getName(), String.format(context.getResources().getString(R.string.profileActivate), this.getName()), 3);
profileActivationHistory.add(this);
AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
if(AutomationService.getInstance().getLockSoundChangesEnd() == null)
@@ -534,6 +576,20 @@ public class Profile implements Comparable<Profile>
{
Miscellaneous.logEvent("e", "Profile " + this.getName(), context.getResources().getString(R.string.errorActivatingProfile) + " " + Log.getStackTraceString(e), 1);
}
finally
{
Miscellaneous.logEvent("i", "POI", "Checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.profileActive);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
{
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies after " + this.getName() + " has been activated.", 2);
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
Miscellaneous.logEvent("i", "POI", "Done checking for applicable rule after profile " + this.getName() + " has been activated.", 2);
}
}
else
{
@@ -541,6 +597,104 @@ public class Profile implements Comparable<Profile>
}
}
public boolean areMySettingsCurrentlyActive(Context context)
{
Miscellaneous.logEvent("i", "Profile " + this.getName(), "Checking if profile's settings are currently active.", 3);
try
{
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
if(changeSoundMode)
{
if(am.getRingerMode() != soundMode)
return false;
}
if(changeDndMode && Build.VERSION.SDK_INT >= 23)
{
if(mNotificationManager.getCurrentInterruptionFilter() != dndMode)
return false;
}
if(changeVolumeMusicVideoGameMedia)
{
if(am.getStreamVolume(AudioManager.STREAM_MUSIC) != volumeMusic)
return false;
}
if(changeVolumeNotifications)
{
if(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != volumeNotifications)
return false;
}
if(changeVolumeAlarms)
{
if(am.getStreamVolume(AudioManager.STREAM_ALARM) != volumeAlarms)
return false;
}
// if(changeIncomingCallsRingtone)
// {
// if (incomingCallsRingtone != null)
// {
// applyRingTone(incomingCallsRingtone, RingtoneManager.TYPE_RINGTONE, context);
// }
// }
if(changeVibrateWhenRinging)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), "vibrate_when_ringing");
if(currentSetting != Miscellaneous.boolToInt(vibrateWhenRinging))
return false;
}
else
{
int currentSetting = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
if(currentSetting != Miscellaneous.boolToInt(vibrateWhenRinging))
return false;
}
}
// if(changeNotificationRingtone)
// if(notificationRingtone != null)
// applyRingTone(notificationRingtone, RingtoneManager.TYPE_NOTIFICATION, context);
if(changeScreenLockUnlockSound)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), "lockscreen_sounds_enabled");
if(currentSetting != Miscellaneous.boolToInt(screenLockUnlockSound))
return false;
}
if(changeAudibleSelection)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.SOUND_EFFECTS_ENABLED);
if(currentSetting != Miscellaneous.boolToInt(audibleSelection))
return false;
}
if(changeHapticFeedback)
{
int currentSetting = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED);
if(currentSetting != Miscellaneous.boolToInt(hapticFeedback))
return false;
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "Profile " + this.getName(), "Error while checking if profile settings are currently active. " + Log.getStackTraceString(e), 1);
}
Miscellaneous.logEvent("i", "Profile " + this.getName(), "This profile's settings are currently active.", 4);
return true;
}
@Override
public String toString()
{
@@ -5,11 +5,12 @@ import android.util.Log;
import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.AlarmListener;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.AutomationListenerInterface;
import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener;
import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener;
@@ -42,10 +43,11 @@ public class ReceiverCoordinator
Class adClass = Class.forName("ActivityDetectionReceiver");
allImplementers = new Class[] {
adClass,
AlarmListener.class,
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
//NfcReceiver.class,
NoiseListener.class,
@@ -56,13 +58,12 @@ public class ReceiverCoordinator
}
catch (ClassNotFoundException e)
{
// e.printStackTrace();
allImplementers = new Class[] {
AlarmListener.class,
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
//NfcReceiver.class,
NoiseListener.class,
@@ -155,7 +156,7 @@ public class ReceiverCoordinator
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
// startAlarmListener
AlarmListener.startAlarmListener(AutomationService.getInstance());
DateTimeListener.startAlarmListener(AutomationService.getInstance());
TimeZoneListener.startTimeZoneListener(AutomationService.getInstance());
// startNoiseListener
@@ -166,15 +167,15 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
ProcessListener.startProcessListener(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
//startActivityDetectionReceiver
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
// ActivityDetectionReceiver.startActivityDetectionReceiver();
}
}
catch(ClassNotFoundException e)
{
@@ -199,15 +200,15 @@ public class ReceiverCoordinator
WifiBroadcastReceiver.stopWifiReceiver();
BatteryReceiver.stopBatteryReceiver();
TimeZoneListener.stopTimeZoneListener();
AlarmListener.stopAlarmListener(AutomationService.getInstance());
DateTimeListener.stopAlarmListener(AutomationService.getInstance());
NoiseListener.stopNoiseListener();
ProcessListener.stopProcessListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
}
catch(ClassNotFoundException e)
{
@@ -216,6 +217,7 @@ public class ReceiverCoordinator
BluetoothReceiver.stopBluetoothReceiver();
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
}
catch(Exception e)
{
@@ -350,6 +352,24 @@ public class ReceiverCoordinator
}
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
{
if(!DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Starting DevicePositionListener because used in a new/changed rule.", 4);
// if(DevicePositionListener.getInstance().haveAllPermission())
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
}
}
else
{
if(DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Shutting down DevicePositionListener because not used in any rule.", 4);
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
}
}
AutomationService.updateNotification();
}
}
@@ -56,6 +56,7 @@ public class Settings implements SharedPreferences
public static boolean rememberLastActivePoi;
public static int locationRingBufferSize;
public static long timeBetweenProcessMonitorings;
public static long acceptDeviceOrientationSignalEveryX_MilliSeconds;
public static int activityDetectionFrequency;
public static int activityDetectionRequiredProbability;
public static boolean privacyLocationing;
@@ -113,6 +114,7 @@ public class Settings implements SharedPreferences
protected static final boolean default_rememberLastActivePoi = true;
protected static final int default_locationRingBufferSize=3;
protected static final long default_timeBetweenProcessMonitorings = 60;
protected static final long default_acceptDevicePositionSignalEveryX_MilliSeconds = 1000;
protected static final int default_activityDetectionFrequency = 60;
protected static final int default_activityDetectionRequiredProbability = 75;
protected static final boolean default_privacyLocationing = false;
@@ -236,6 +238,7 @@ public class Settings implements SharedPreferences
lengthOfNoiseLevelMeasurements = Long.parseLong(prefs.getString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements)));
referenceValueForNoiseLevelMeasurements = Long.parseLong(prefs.getString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements)));
timeBetweenProcessMonitorings = Long.parseLong(prefs.getString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings)));
acceptDeviceOrientationSignalEveryX_MilliSeconds = Long.parseLong(prefs.getString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds)));
httpAcceptAllCertificates = prefs.getBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates);
httpAttempts = Integer.parseInt(prefs.getString("httpAttempts", String.valueOf(default_httpAttempts)));
@@ -431,6 +434,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("timeBetweenProcessMonitorings") | force)
editor.putString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings));
if(!prefs.contains("acceptDevicePositionSignalEveryX_MilliSeconds") | force)
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds));
if(!prefs.contains("activityDetectionFrequency") | force)
editor.putString("activityDetectionFrequency", String.valueOf(default_activityDetectionFrequency));
@@ -526,6 +532,7 @@ public class Settings implements SharedPreferences
editor.putString("httpAttemptGap", String.valueOf(httpAttemptGap));
editor.putString("locationRingBufferSize", String.valueOf(locationRingBufferSize));
editor.putString("timeBetweenProcessMonitorings", String.valueOf(timeBetweenProcessMonitorings));
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(acceptDeviceOrientationSignalEveryX_MilliSeconds));
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
editor.putBoolean("privacyLocationing", privacyLocationing);
@@ -6,70 +6,90 @@ import java.util.ArrayList;
public class TimeFrame
{
// Defines a timeframe
private Time triggerTimeStart;
private Time triggerTimeStop;
protected Time triggerTimeStart;
protected Time triggerTimeStop;
protected long repetition;
private ArrayList<Integer> dayList = new ArrayList<Integer>();
public ArrayList<Integer> getDayList()
protected final static String separator = "/";
private ArrayList<Integer> dayList = new ArrayList<Integer>();
public ArrayList<Integer> getDayList()
{
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
// Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item)));
}
dayList.add(Integer.parseInt(String.valueOf(item)));
}
}
public Time getTriggerTimeStart()
{
return triggerTimeStart;
}
public void setTriggerTimeStart(Time triggerTimeStart)
{
this.triggerTimeStart = triggerTimeStart;
}
public Time getTriggerTimeStop()
{
return triggerTimeStop;
}
public void setTriggerTimeStop(Time triggerTimeStop)
{
this.triggerTimeStop = triggerTimeStop;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
this.setDayList(dayList2);
}
TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split("/"); // example: timestart/timestop/days[int]
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.setDayListFromString(dateArray[2]);
}
@Override
public String toString()
{
String returnString = this.getTriggerTimeStart().toString() + "/" + this.getTriggerTimeStop().toString() + "/";
for(Integer oneDay : this.getDayList())
returnString += String.valueOf(oneDay);
return returnString;
}
}
public Time getTriggerTimeStart()
{
return triggerTimeStart;
}
public void setTriggerTimeStart(Time triggerTimeStart)
{
this.triggerTimeStart = triggerTimeStart;
}
public Time getTriggerTimeStop()
{
return triggerTimeStop;
}
public void setTriggerTimeStop(Time triggerTimeStop)
{
this.triggerTimeStop = triggerTimeStop;
}
public long getRepetition()
{
return repetition;
}
public void setRepetition(long repetition)
{
this.repetition = repetition;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2, long repetition)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
this.setDayList(dayList2);
this.setRepetition(repetition);
}
public TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split(separator); // example: timestart/timestop/days[int]/repetition
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.setDayListFromString(dateArray[2]);
if(dateArray.length > 3) // may not exist in old config files
this.setRepetition(Long.parseLong(dateArray[3]));
}
@Override
public String toString()
{
String returnString = this.getTriggerTimeStart().toString() + separator + this.getTriggerTimeStop().toString() + separator;
for(Integer oneDay : this.getDayList())
returnString += String.valueOf(oneDay);
returnString += separator + String.valueOf(repetition);
return returnString;
}
}
File diff suppressed because it is too large Load Diff
@@ -764,6 +764,8 @@ public class XmlFileInterface
try
{
newRule.setTriggerSet(readTriggerCollection(parser));
for(Trigger t : newRule.getTriggerSet())
t.setParentRule(newRule);
}
catch (XmlPullParserException e)
{
@@ -779,6 +781,8 @@ public class XmlFileInterface
try
{
newRule.setActionSet(readActionCollection(parser));
for(Action a : newRule.getActionSet())
a.setParentRule(newRule);
}
catch (XmlPullParserException e)
{
@@ -815,7 +819,15 @@ public class XmlFileInterface
// Starts by looking for the entry tag
if (name.equals("Trigger"))
{
triggerCollection.add(readTrigger(parser));
try
{
triggerCollection.add(readTrigger(parser));
}
catch (IllegalArgumentException | NullPointerException e)
{
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown trigger found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
}
}
else
{
@@ -826,7 +838,6 @@ public class XmlFileInterface
return (triggerCollection);
}
private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException
{
@@ -878,7 +889,7 @@ public class XmlFileInterface
{
String triggerEventString = readTag(parser, "TriggerEvent");
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
if(triggerEventString.equals("process_started_stopped") || triggerEventString.equals("process_running"))
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
else
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
@@ -928,7 +939,6 @@ public class XmlFileInterface
}
else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection)
{
// newTrigger.setWifiName(triggerParameter2);
newTrigger.setTriggerParameter2(triggerParameter2);
}
else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped)
@@ -1051,7 +1061,15 @@ public class XmlFileInterface
// Starts by looking for the entry tag
if (name.equals("Action"))
{
actionCollection.add(readAction(parser));
try
{
actionCollection.add(readAction(parser));
}
catch (IllegalArgumentException | NullPointerException e)
{
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown action found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
}
}
else
{
@@ -1060,7 +1078,6 @@ public class XmlFileInterface
}
return (actionCollection);
}
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
{
@@ -1135,7 +1152,14 @@ public class XmlFileInterface
newAction.setAction(Action_Enum.enableScreenRotation);
else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation);
// *** deprecated
else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation);
else if(actionNameString.equals("wakeupDevice"))
{
newAction.setAction(Action_Enum.turnScreenOnOrOff);
newAction.setParameter1(true);
}
// *** deprecated
else
newAction.setAction(Action_Enum.valueOf(actionNameString));
@@ -1203,6 +1227,18 @@ public class XmlFileInterface
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
{
newAction.setAction(Action_Enum.setDisplayRotation);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnScreenOnOrOff) && newAction.getParameter1())
{
/*
If param1 == true we will keep it because this action used to be of type wakeUpDevice.
*/
}
else
// exclusion for deprecated types
newAction.setParameter1(Boolean.parseBoolean(readTag(parser, "ActionParameter1")));
@@ -1224,7 +1260,6 @@ public class XmlFileInterface
{
newAction.setParameter2(tag);
}
/*
androidx.security.crypto.MasterKey.Builder
@@ -1283,9 +1318,6 @@ public class XmlFileInterface
}
}
}
// Miscellaneous.logEvent("i", "New Rule from file", newPoi.name + "/" + String.valueOf(newPoi.radius) + "/" + String.valueOf(newPoi.location.getLatitude()) + "/" + String.valueOf(newPoi.location.getLongitude()) + "/" + String.valueOf(newPoi.changeWifiState) + "/" + String.valueOf(newPoi.desiredWifiState) + "/" + String.valueOf(newPoi.changeCameraState) + "/" + String.valueOf(newPoi.desiredCameraState) + "/" + String.valueOf(newPoi.changeSoundSetting) + "/" + String.valueOf(newPoi.desiredSoundSetting));
return newAction;
}
@@ -369,7 +369,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
// Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4);
}
else
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
}
else
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4);
@@ -121,9 +121,9 @@ public class LocationProvider
if (
locationList.size() >= 1
&&
locationList.get(locationList.size() - 1).getTime() == newLocation.getTime()
locationList.get(locationList.size() - 1).getTime() == newLocation.getTime()
&&
locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider())
locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider())
)
{
// This is a duplicate update, do not store it
@@ -198,10 +198,10 @@ public class LocationProvider
setSpeed(currentSpeed);
// execute matching rules containing speed
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesBySpeed();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.speed);
for (Rule oneRule : ruleCandidates)
{
if (oneRule.applies(this.getParentService()))
if(oneRule.getsGreenLight(this.getParentService()))
oneRule.activate(getParentService(), false);
}
}
@@ -16,6 +16,7 @@ import com.jens.automation2.PointOfInterest;
import com.jens.automation2.R;
import com.jens.automation2.Rule;
import com.jens.automation2.Settings;
import com.jens.automation2.Trigger;
import java.util.ArrayList;
@@ -144,10 +145,10 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static void findRules(AutomationService automationServiceInstance)
{
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.wifiConnection);
for(Rule oneRule : ruleCandidates)
{
if(oneRule.applies(automationServiceInstance))
if(oneRule.getsGreenLight(automationServiceInstance))
oneRule.activate(automationServiceInstance, false);
}
}
@@ -1,301 +0,0 @@
package com.jens.automation2.receivers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class AlarmListener extends BroadcastReceiver implements AutomationListenerInterface
{
private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance;
// private static Intent alarmIntent;
// private static PendingIntent alarmPendingIntent;
private static boolean alarmListenerActive=false;
private static ArrayList<Long> alarmCandidates = new ArrayList<Long>();
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
public static void startAlarmListener(final AutomationService automationServiceRef)
{
AlarmListener.startAlarmListenerInternal(automationServiceRef);
}
public static void stopAlarmListener(Context context)
{
AlarmListener.stopAlarmListenerInternal();
}
public static boolean isAlarmListenerActive()
{
return alarmListenerActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
Date now = new Date();
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
Time passTime = Time.valueOf(timeString);
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
{
if(allRulesWithNowInTimeFrame.get(i).applies(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
}
setAlarms();
}
public static void setAlarms()
{
alarmCandidates.clear();
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
clearAlarms();
int i=0;
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = null;
// SimpleDateFormat sdf2 = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
// if (cal != null)
// {
// calSetWorkingCopyString2 = sdf2.format(cal.getTime());
// }
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
for(Rule oneRule : allRulesWithTimeFrames)
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
if(oneTrigger.getTriggerType() == Trigger_Enum.timeFrame)
{
Calendar calNow, calSet;
Time setTime;
if(oneTrigger.getTriggerParameter())
setTime = oneTrigger.getTimeFrame().getTriggerTimeStart();
else
setTime = oneTrigger.getTimeFrame().getTriggerTimeStop();
calNow = Calendar.getInstance();
calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// At this point calSet would be a scheduling candidate. It's just the day the might not be right, yet.
long milliSecondsInAWeek = 1000 * 60 * 60 * 24 * 7;
for(int dayOfWeek : oneTrigger.getTimeFrame().getDayList())
{
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
// calSetWorkingCopy.set(Calendar.HOUR_OF_DAY, setTime.getHours());
// calSetWorkingCopy.set(Calendar.MINUTE, setTime.getMinutes());
// calSetWorkingCopy.set(Calendar.SECOND, 0);
// calSetWorkingCopy.set(Calendar.MILLISECOND, 0);
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
// Log.i("AlarmManager", "Today: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + " / Sched.Day: " + String.valueOf(dayOfWeek) + " Difference to target day is: " + String.valueOf(diff));
if(diff == 0) //if we're talking about the current day, is the time still in the future?
{
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours(" + String.valueOf(calSetWorkingCopy.getTime().getHours()) + ") < calNow.getTime().getHours(" + String.valueOf(calNow.getTime().getHours()) + ")");
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours()");
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getMinutes() < calNow.getTime().getMinutes()");
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
}
}
else if(diff < 0)
{
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff+7) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
}
else
{
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
}
i++;
i=(int)System.currentTimeMillis();
String calSetWorkingCopyString = sdf.format(calSetWorkingCopy.getTime()) + " RequestCode: " + String.valueOf(i);
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of rule: " + oneRule.getName() + " beginning at " + calSetWorkingCopyString);
alarmCandidates.add(calSetWorkingCopy.getTimeInMillis());
// Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmIntent.setData(Uri.parse("myalarms://" + i));
// PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, i, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, calSetWorkingCopy.getTimeInMillis(), milliSecondsInAWeek, alarmPendingIntent);
// requestCodeList.add(i);
}
}
}
}
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = sdf.format(cal.getTime());
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
scheduleNextAlarm();
}
private static void scheduleNextAlarm()
{
Long currentTime = System.currentTimeMillis();
Long scheduleCandidate = null;
if(alarmCandidates.size() == 0)
{
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
return;
}
else if(alarmCandidates.size() == 1)
{
// only one alarm, schedule that
scheduleCandidate = alarmCandidates.get(0);
}
else if(alarmCandidates.size() > 1)
{
scheduleCandidate = alarmCandidates.get(0);
for(long alarmCandidate : alarmCandidates)
{
if(Math.abs(currentTime - alarmCandidate) < Math.abs(currentTime - scheduleCandidate))
scheduleCandidate = alarmCandidate;
}
}
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate, alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate);
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
}
public static void clearAlarms()
{
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for(int requestCode : requestCodeList)
{
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent);
}
requestCodeList.clear();
}
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
{
if(!alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
AlarmListener.automationServiceRef = givenAutomationServiceRef;
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
alarmListenerActive = true;
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
AlarmListener.setAlarms();
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent);
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
}
private static void stopAlarmListenerInternal()
{
if(alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false;
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
}
public static void reloadAlarms()
{
AlarmListener.setAlarms();
}
@Override
public void startListener(AutomationService automationService)
{
AlarmListener.startAlarmListener(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
AlarmListener.stopAlarmListener(automationService);
}
public static boolean haveAllPermission()
{
return true;
}
@Override
public boolean isListenerRunning()
{
return isAlarmListenerActive();
}
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.timeFrame };
}
}
@@ -1,5 +1,6 @@
package com.jens.automation2.receivers;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -18,7 +19,7 @@ import java.util.ArrayList;
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface
{
private static int batteryLevel=-1; // initialize with a better value than this
private static int batteryLevel = -1; // initialize with a better value than this
public static AutomationService automationServiceRef = null;
private static boolean usbHostConnected = false;
@@ -26,6 +27,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private static IntentFilter batteryIntentFilter = null;
private static Intent batteryStatus = null;
private static BroadcastReceiver batteryInfoReceiverInstance = null;
public static void startBatteryReceiver(final AutomationService automationServiceRef)
{
if(!batteryReceiverActive)
@@ -78,11 +80,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
return batteryLevel;
}
private static int deviceIsCharging = 0; //0=unknown, 1=no, 2=yes
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
public static int getDeviceIsCharging()
public static int getCurrentChargingState()
{
return deviceIsCharging;
return currentChargingState;
}
@Override
@@ -145,31 +147,6 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
this.actionDischarging(context);
break;
}
// }
// else if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED))
// {
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.");
// deviceIsCharging = 2;
// //activate rule(s)
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
// for(int i=0; i<ruleCandidates.size(); i++)
// {
// if(ruleCandidates.get(i).applies(context))
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
// }
// }
// else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED))
// {
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.");
// deviceIsCharging = 1;
// //activate rule(s)
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
// for(int i=0; i<ruleCandidates.size(); i++)
// {
// if(ruleCandidates.get(i).applies(context))
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
// }
// }
}
catch(Exception e)
{
@@ -180,7 +157,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
public static int isDeviceCharging(Context context)
{
switch(deviceIsCharging)
switch(currentChargingState)
{
case 0:
Miscellaneous.logEvent("w", "ChargingInfo", "Status of device charging was requested. Information isn't available, yet.", 4);
@@ -188,25 +165,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
case 1:
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is discharging.", 3);
break;
case 2:
case BatteryManager.BATTERY_STATUS_CHARGING:
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3);
break;
}
return deviceIsCharging;
return currentChargingState;
}
private void actionCharging(Context context)
{
if(deviceIsCharging != 2) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
if(currentChargingState != BatteryManager.BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
deviceIsCharging = 2;
currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING;
//activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(context))
if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@@ -216,25 +194,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
{
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery level has changed.", 3);
//activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBatteryLevel();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.batteryLevel);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(context))
if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
private void actionDischarging(Context context)
{
if(deviceIsCharging != 1) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
if(currentChargingState != BatteryManager.BATTERY_STATUS_UNKNOWN) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3);
deviceIsCharging = 1;
currentChargingState = BatteryManager.BATTERY_STATUS_UNKNOWN;
//activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(context))
if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
@@ -253,11 +232,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
usbHostConnected = true;
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
for(Rule oneRule : ruleCandidates)
{
if(oneRule.applies(context))
if(oneRule.getsGreenLight(context))
oneRule.activate(automationServiceRef, false);
}
@@ -274,11 +254,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
usbHostConnected = false;
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
for(Rule oneRule : ruleCandidates)
{
if(oneRule.applies(context))
if(oneRule.getsGreenLight(context))
oneRule.activate(automationServiceRef, false);
}
}
@@ -296,8 +277,8 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
public static boolean haveAllPermission()
{
return ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext()) &&
ActivityPermissions.havePermission("android.permission.BATTERY_STATS", Miscellaneous.getAnyContext());
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
}
@Override
@@ -124,10 +124,10 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDeviceInRange), bluetoothDevice.getName()), 3);
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.bluetoothConnection);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(AutomationService.getInstance()))
if(ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
@@ -112,7 +112,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
@SuppressLint("NewApi")
public static boolean isAirplaneMode(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
int value = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0);
return value != 0;
@@ -138,10 +138,11 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
boolean isAirplaneMode = isAirplaneMode(context);
automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.airplaneMode);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(automationServiceRef))
if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@@ -170,11 +171,12 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
roamingLastState = isRoaming;
automationServiceRef.getLocationProvider().handleRoaming(isRoaming);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.roaming);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(automationServiceRef))
if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@@ -0,0 +1,433 @@
package com.jens.automation2.receivers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.TimeFrame;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
{
private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance;
// private static 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>();
public static void startAlarmListener(final AutomationService automationServiceRef)
{
DateTimeListener.startAlarmListenerInternal(automationServiceRef);
}
public static void stopAlarmListener(Context context)
{
DateTimeListener.stopAlarmListenerInternal();
}
public static boolean isAlarmListenerActive()
{
return alarmListenerActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
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++)
{
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
}
setAlarms();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setAlarms()
{
alarmCandidates.clear();
Calendar calNow = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
clearAlarms();
int i=0;
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = null;
// SimpleDateFormat sdf2 = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
// if (cal != null)
// {
// calSetWorkingCopyString2 = sdf2.format(cal.getTime());
// }
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
// allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
/*
* Take care of regular executions, no repetitions in between.
*/
Miscellaneous.logEvent("i", "DateTimeListener", "Checking rules for single run alarm candidates.", 5);
for(Rule oneRule : allRulesWithTimeFrames)
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for single run alarm candidates.", 5);
if(oneRule.isRuleActive())
{
try
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for single run alarm candidates.", 5);
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
{
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
Calendar calSet;
Time setTime;
if(oneTrigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
else
setTime = tf.getTriggerTimeStop();
calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// At this point calSet would be a scheduling candidate. It's just the day that might not be right, yet.
for(int dayOfWeek : tf.getDayList())
{
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
if(diff == 0) // We're talking about the current weekday, but is the time still in the future?
{
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
{
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
{
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
{
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
}
}
else if(diff < 0)
{
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
}
else
{
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
}
i++;
i=(int)System.currentTimeMillis();
sdf.format(calSetWorkingCopy.getTime());
String.valueOf(i);
alarmCandidates.add(new ScheduleElement(calSetWorkingCopy, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
}
}
}
/*
* Only take care of repeated executions.
*/
Miscellaneous.logEvent("i", "DateTimeListener","Checking rules for repeated run alarm candidates.", 5);
for(Rule oneRule : allRulesWithTimeFrames)
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for repeated run alarm candidates.", 5);
if(oneRule.isRuleActive())
{
try
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.toString() , 5);
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for repeated run alarm candidates.", 5);
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule trigger " + oneTrigger.toString() , 5);
/*
* Check for next repeated execution:
*
* Check if the rule currently applies....
*
* If no -> do nothing
* If yes -> Take starting time and calculate the next repeated execution
* 1. Take starting time
* 2. Take current time
* 3. Calculate difference, but include check to see if we're after that time,
* be it start or end of the timeframe.
* 4. Take div result +1 and add this on top of starting time
* 5. Is this next possible execution still inside timeframe? Also consider timeframes spanning over midnight
*/
Calendar calSet;
Time setTime;
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
{
Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow);
alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
}
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
}
}
}
scheduleNextAlarm();
}
private static void scheduleNextAlarm()
{
Long currentTime = System.currentTimeMillis();
ScheduleElement scheduleCandidate = null;
if(alarmCandidates.size() == 0)
{
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
return;
}
else if(alarmCandidates.size() == 1)
{
// only one alarm, schedule that
scheduleCandidate = alarmCandidates.get(0);
}
else if(alarmCandidates.size() > 1)
{
scheduleCandidate = alarmCandidates.get(0);
for(ScheduleElement alarmCandidate : alarmCandidates)
{
if(Math.abs(currentTime - alarmCandidate.time.getTimeInMillis()) < Math.abs(currentTime - scheduleCandidate.time.getTimeInMillis()))
scheduleCandidate = alarmCandidate;
}
}
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
PendingIntent 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");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis());
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
}
public static void clearAlarms()
{
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for</