Compare commits
102 Commits
v1.7.9
...
d75cf137ba
Author | SHA1 | Date | |
---|---|---|---|
d75cf137ba | |||
5e3d268815 | |||
3bcf90277f | |||
81a205a8db | |||
97a3344e81 | |||
cd47b33449 | |||
2ba25a9e65 | |||
d2606b72cd | |||
584495ef61 | |||
9b28aeef8b | |||
b6bf31589a | |||
67238bd2f0 | |||
5f278a6ba0 | |||
a21f90acb5 | |||
5f8ed5765a | |||
605f85d215 | |||
21f4a7fd5c | |||
2219164869 | |||
a8646ef61d | |||
f641de9893 | |||
bca8b44ad6 | |||
c34dfa4af4 | |||
38644cee28 | |||
47898e84ea | |||
ac74b52aed | |||
3f76813e80 | |||
1b8dc5de5f | |||
3c8c0f14f2 | |||
9ead47bdf7 | |||
e4828a9720 | |||
4f971e8a1b | |||
34fbc1d005 | |||
b72049defc | |||
54f3cc84c4 | |||
7884358564 | |||
f24c9f99dc | |||
64b97c650d | |||
9daf4c4747 | |||
94f7936c4a | |||
02f7b642cf | |||
8d10bf05af | |||
8c0cee9589 | |||
6b23bd6733 | |||
1a60c88f35 | |||
3312d99177 | |||
ea01806915 | |||
36173f2fcb | |||
4c66fe906e | |||
60cfa150b5 | |||
bd2231b075 | |||
158f5f2e04 | |||
f1315dc742 | |||
28aa0c3e4b | |||
6b9dbca7ab | |||
291e0c41af | |||
c9eedd5d87 | |||
2470321e15 | |||
d85a199117 | |||
b047cde4ea | |||
9a1796f2eb | |||
7e8a6b121e | |||
810c7488c4 | |||
8af24695fd | |||
533a9bf54d | |||
8653e4853b | |||
c464a9d71f | |||
26e4851c0d | |||
11f0ee25bf | |||
a76cafc6e2 | |||
bd2920e6d9 | |||
5caf33b45d | |||
6a74d070eb | |||
eba02ade08 | |||
394effea36 | |||
4d51f1890a | |||
a8b2c3bf7d | |||
d1c6abaa91 | |||
587ed5803e | |||
49d272be1e | |||
d9e54c7780 | |||
170dbbc7e8 | |||
3fc1dd1a26 | |||
0acb52099c | |||
b6015a3f2e | |||
ae1e767fa6 | |||
6e12e71133 | |||
e4e3faea06 | |||
7c42250e13 | |||
ebb0724b28 | |||
a7ae0c6588 | |||
e5433bf2ec | |||
fd8ffd4f7d | |||
f49455712a | |||
132f64114e | |||
27e9b3e0d1 | |||
a6c6dfc6ba | |||
6a7875cc61 | |||
6f80caa1c6 | |||
a9646cbf28 | |||
52edfa32df | |||
ca81e6a7bd | |||
49e4c20ab6 |
@ -11,8 +11,8 @@ android {
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 124
|
||||
versionName "1.7.9"
|
||||
versionCode 138
|
||||
versionName "1.7.21"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -36,9 +36,15 @@ android {
|
||||
{
|
||||
dimension "version"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 31
|
||||
targetSdkVersion 33
|
||||
}
|
||||
|
||||
/*
|
||||
targetSdkVersion is kept at 28 for as long as possible.
|
||||
If raised wifi cannot be switched on or off anymore without root permissions.
|
||||
In the Google version I'm forced to raise the value regularly.
|
||||
*/
|
||||
|
||||
fdroidFlavor
|
||||
{
|
||||
dimension "version"
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -50,7 +52,6 @@
|
||||
<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" />
|
||||
@ -68,6 +69,16 @@
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -85,7 +96,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -136,6 +147,7 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
@ -176,6 +188,8 @@
|
||||
<activity android:name=".ActivityManageActionMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
@ -224,6 +238,7 @@
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
@ -258,6 +273,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -347,7 +347,16 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
|
||||
{
|
||||
if(oneTrigger.getTimeFrame().repetition > 0)
|
||||
return true;
|
||||
{
|
||||
if(this.getLastExecution() != null)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (this.getLastExecution().getTimeInMillis() + oneTrigger.getTimeFrame().getRepetition() * 1000 <= now.getTimeInMillis())
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
|
||||
{
|
||||
@ -467,7 +476,9 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
service.speak(messages[0], false);
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
super.onProgressUpdate(messages);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -50,7 +52,6 @@
|
||||
<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" />
|
||||
@ -66,6 +67,15 @@
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -83,7 +93,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -134,6 +144,7 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
@ -171,9 +182,12 @@
|
||||
<activity android:name=".ActivityManageTriggerTethering" />
|
||||
<activity android:name=".ActivityManageActionWakeLock" />
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionMakePhoneCall" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@ -221,6 +235,7 @@
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
@ -243,6 +258,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -440,7 +440,9 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
service.speak(messages[0], false);
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
super.onProgressUpdate(messages);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
@ -49,7 +51,6 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@ -64,11 +65,19 @@
|
||||
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SECURE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<!--android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:icon="@drawable/crane"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
@ -120,6 +129,7 @@
|
||||
<receiver android:name=".receivers.DateTimeListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
<receiver android:name=".receivers.CalendarReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".DeviceAdmin"
|
||||
@ -160,6 +170,10 @@
|
||||
<activity android:name=".ActivityManageTriggerSubSystemState" />
|
||||
<activity android:name=".ActivityManageActionSetVariable" />
|
||||
<activity android:name=".ActivityManageTriggerCheckVariable" />
|
||||
<activity android:name=".ActivityManageActionCopyToClipboard" />
|
||||
<activity android:name=".ActivityManageActionLocationService" />
|
||||
<activity android:name=".ActivityManageTriggerCalendar" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:exported="true"
|
||||
@ -243,6 +257,17 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<service android:name=".MyAccessibilityService"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accessibilityservice"
|
||||
android:resource="@xml/config_accessibility_service" />
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -467,7 +467,9 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
service.speak(messages[0], false);
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(service, messages[0], Toast.LENGTH_LONG).show();
|
||||
|
||||
super.onProgressUpdate(messages);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
@ -7,7 +7,6 @@ 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;
|
||||
import java.util.Locale;
|
||||
@ -55,6 +54,9 @@ public class Action
|
||||
setVariable,
|
||||
startPhoneCall,
|
||||
stopPhoneCall,
|
||||
copyToClipboard,
|
||||
takeScreenshot,
|
||||
setLocationService,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -137,6 +139,12 @@ public class Action
|
||||
return context.getResources().getString(R.string.startPhoneCall);
|
||||
case stopPhoneCall:
|
||||
return context.getResources().getString(R.string.endPhoneCall);
|
||||
case copyToClipboard:
|
||||
return context.getResources().getString(R.string.copyTextToClipboard);
|
||||
case takeScreenshot:
|
||||
return context.getResources().getString(R.string.takeScreenshot);
|
||||
case setLocationService:
|
||||
return context.getResources().getString(R.string.setLocationServiceCapital);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -302,6 +310,30 @@ public class Action
|
||||
case stopPhoneCall:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.endPhoneCall));
|
||||
break;
|
||||
case copyToClipboard:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.copyTextToClipboard));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.takeScreenshot));
|
||||
break;
|
||||
case setLocationService:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setLocationService) + ": " );
|
||||
switch(Integer.parseInt(getParameter2()))
|
||||
{
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_OFF:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.off));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_SENSOR_ONLY));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_BATTERY_SAVING));
|
||||
break;
|
||||
case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_HIGH_ACCURACY));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
returnString.append(action.toString());
|
||||
}
|
||||
@ -409,7 +441,7 @@ public class Action
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; ").replace(Action.intentPairSeparator, "/"));
|
||||
}
|
||||
else if (this.getAction().equals(Action_Enum.setVariable))
|
||||
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard) || this.getAction().equals(Action_Enum.setLocationService))
|
||||
; // it's completed further above already
|
||||
else if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
|
||||
@ -624,6 +656,15 @@ public class Action
|
||||
case stopPhoneCall:
|
||||
Actions.endPhoneCall(context);
|
||||
break;
|
||||
case copyToClipboard:
|
||||
Actions.copyToClipboard(context, Miscellaneous.replaceVariablesInText(this.getParameter2(), context));
|
||||
break;
|
||||
case takeScreenshot:
|
||||
Actions.takeScreenshot();
|
||||
break;
|
||||
case setLocationService:
|
||||
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
@ -640,6 +681,7 @@ public class Action
|
||||
{
|
||||
String username = null;
|
||||
String password = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
String url;
|
||||
|
||||
String[] components = getParameter2().split(";");
|
||||
@ -649,8 +691,11 @@ public class Action
|
||||
username = components[0];
|
||||
password = components[1];
|
||||
url = components[2];
|
||||
|
||||
if(components.length >= 4)
|
||||
method = components[3];
|
||||
}
|
||||
else
|
||||
else // compatibility for very old versions which haven't upgraded, yet.
|
||||
url = components[0];
|
||||
|
||||
try
|
||||
@ -662,7 +707,7 @@ public class Action
|
||||
Miscellaneous.logEvent("i", "HTTP", "Attempting download of " + url, 4); //getResources().getString("attemptingDownloadOf");
|
||||
|
||||
if(this.getParameter1()) // use authentication
|
||||
new DownloadTask().execute(url, username, password);
|
||||
new DownloadTask().execute(url, username, password, method);
|
||||
else
|
||||
new DownloadTask().execute(url, null, null);
|
||||
}
|
||||
@ -684,16 +729,19 @@ public class Action
|
||||
|
||||
String urlUsername = null;
|
||||
String urlPassword = null;
|
||||
String method = ActivityManageActionTriggerUrl.methodGet;
|
||||
if(parameters.length >= 3)
|
||||
{
|
||||
urlUsername=parameters[1];
|
||||
urlPassword=parameters[2];
|
||||
urlUsername = parameters[1];
|
||||
urlPassword = parameters[2];
|
||||
|
||||
if(parameters.length >= 4)
|
||||
method = parameters[3];
|
||||
}
|
||||
|
||||
String response = "httpError";
|
||||
HttpGet post;
|
||||
|
||||
if(Settings.httpAttempts < 1)
|
||||
String response = "HTTP_ERROR";
|
||||
|
||||
if(Settings.httpAttempts < 1)
|
||||
Miscellaneous.logEvent("w", "HTTP Request", Miscellaneous.getAnyContext().getResources().getString(R.string.cantDownloadTooFewRequestsInSettings), 3);
|
||||
|
||||
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
|
||||
@ -702,9 +750,9 @@ public class Action
|
||||
|
||||
// Either thorough checking or no encryption
|
||||
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method);
|
||||
else
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword, method);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.NotificationManager;
|
||||
@ -10,7 +11,7 @@ import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
@ -19,7 +20,6 @@ import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.VibrationEffect;
|
||||
@ -30,7 +30,6 @@ import android.telecom.TelecomManager;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.Toast;
|
||||
@ -54,7 +53,6 @@ import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@ -97,6 +95,7 @@ public class Actions
|
||||
|
||||
Miscellaneous.logEvent("w", "createNotification", "Creating notification with title " + elements[0] + " and text " + elements[1], 3);
|
||||
|
||||
// Create a new notification ID each time
|
||||
int notificationId = Math.round(Calendar.getInstance().getTimeInMillis()/1000);
|
||||
|
||||
try
|
||||
@ -115,8 +114,8 @@ public class Actions
|
||||
public static void closeNotification(Action action)
|
||||
{
|
||||
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
for(StatusBarNotification n : nm.getActiveNotifications())
|
||||
{
|
||||
// for(StatusBarNotification n : nm.getActiveNotifications())
|
||||
// {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = action.getParameter2().split(Action.actionParameter2Split);
|
||||
@ -196,7 +195,7 @@ public class Actions
|
||||
Miscellaneous.logEvent("i", "NotificationCloseCheck", "NotificationListener instance is null. Can\'t close notification.", 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public static void sendBroadcast(Context context, String action)
|
||||
@ -987,6 +986,7 @@ public class Actions
|
||||
public void useDownloadedWebpage(String result)
|
||||
{
|
||||
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
|
||||
Actions.setVariable("LAST_TRIGGERURL_RESULT" + Action.actionParameter2Split + result);
|
||||
}
|
||||
|
||||
public static HttpClient getInsecureSslClient(HttpClient client)
|
||||
@ -1045,11 +1045,16 @@ public class Actions
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherActivity", "Starting other Activity...", 4);
|
||||
|
||||
String params[] = param.split(";");
|
||||
String params[];
|
||||
|
||||
if(param.contains(Action.actionParameter2Split))
|
||||
params = param.split(Action.actionParameter2Split);
|
||||
else
|
||||
params = param.split(";");
|
||||
|
||||
try
|
||||
{
|
||||
Intent externalActivityIntent;
|
||||
Intent externalApplicationIntent;
|
||||
|
||||
if (!startByAction)
|
||||
{
|
||||
@ -1062,15 +1067,15 @@ public class Actions
|
||||
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by activity: " + packageName + " " + className, 3);
|
||||
|
||||
externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
externalApplicationIntent = new Intent(Intent.ACTION_MAIN);
|
||||
externalApplicationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
// if(packageName.equals("dummyPkg"))
|
||||
// externalActivityIntent.setAction(className);
|
||||
// else
|
||||
externalActivityIntent.setClassName(packageName, className);
|
||||
if(packageName.equals("dummyPkg"))
|
||||
externalApplicationIntent.setAction(className);
|
||||
|
||||
if (!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext()))
|
||||
externalApplicationIntent.setClassName(packageName, className);
|
||||
|
||||
if (!Miscellaneous.doesActivityExist(externalApplicationIntent, Miscellaneous.getAnyContext()))
|
||||
Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2);
|
||||
}
|
||||
else
|
||||
@ -1078,25 +1083,32 @@ public class Actions
|
||||
// selected by action
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by action: " + param, 3);
|
||||
|
||||
externalActivityIntent = new Intent();
|
||||
externalApplicationIntent = new Intent();
|
||||
|
||||
if (!params[0].equals(dummyPackageString))
|
||||
externalActivityIntent.setPackage(params[0]);
|
||||
externalApplicationIntent.setPackage(params[0]);
|
||||
|
||||
externalActivityIntent.setAction(params[1]);
|
||||
externalApplicationIntent.setAction(params[1]);
|
||||
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString) || params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString))
|
||||
{
|
||||
externalApplicationIntent.setComponent(new ComponentName(params[0], params[2]));
|
||||
}
|
||||
}
|
||||
|
||||
externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
externalApplicationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
// Pack intents
|
||||
externalActivityIntent = packParametersIntoIntent(externalActivityIntent, params, 3);
|
||||
externalApplicationIntent = packParametersIntoIntent(externalApplicationIntent, params, 3);
|
||||
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
|
||||
automationServerRef.startActivity(externalActivityIntent);
|
||||
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
|
||||
automationServerRef.startService(externalActivityIntent);
|
||||
automationServerRef.startActivity(externalApplicationIntent);
|
||||
else if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
|
||||
automationServerRef.startService(externalApplicationIntent);
|
||||
else if (params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString) && Build.VERSION.SDK_INT >= 26)
|
||||
automationServerRef.startForegroundService(externalApplicationIntent);
|
||||
else
|
||||
automationServerRef.sendBroadcast(externalActivityIntent);
|
||||
automationServerRef.sendBroadcast(externalApplicationIntent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -1168,21 +1180,36 @@ public class Actions
|
||||
}
|
||||
else if (singleParam[0].equals("Uri"))
|
||||
{
|
||||
if (singleParam[1].equalsIgnoreCase("IntentData"))
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
|
||||
intent.setData(Uri.parse(singleParam[2]));
|
||||
if (singleParam[1].equalsIgnoreCase("IntentData"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
|
||||
intent.setData(Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
intent.putExtra(singleParam[1], Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
intent.putExtra(singleParam[1], Uri.parse(singleParam[2]));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
else if (singleParam[0].equals("String"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
intent.putExtra(singleParam[1], singleParam[2]);
|
||||
try
|
||||
{
|
||||
intent.putExtra(singleParam[1], Miscellaneous.replaceVariablesInText(singleParam[2], context));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
intent.putExtra(singleParam[1], singleParam[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
|
||||
@ -2261,7 +2288,18 @@ public class Actions
|
||||
|
||||
public static void startPhoneCall(Context context, String phoneNumber)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
|
||||
Intent intent;
|
||||
|
||||
/*
|
||||
Bug in Android 14 makes it necessary to add double quotes around MMI code.
|
||||
More precisely it's required for codes containing the # character.
|
||||
*/
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 34)
|
||||
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode("\"" + phoneNumber + "\"")));
|
||||
else
|
||||
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
|
||||
|
||||
// intent.setClassName("com.android.phone","com.android.phone.OutgoingCallBroadcaster");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
|
||||
@ -2297,4 +2335,43 @@ public class Actions
|
||||
mgr.endCall();
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyToClipboard(Context context, String text)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Clipboard", "Copying data to clipboard: " + text, 4);
|
||||
|
||||
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
|
||||
{
|
||||
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
android.content.ClipData clip = android.content.ClipData.newPlainText("Data-from-Automation", text);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
}
|
||||
}
|
||||
|
||||
public static void takeScreenshot()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||
{
|
||||
MyAccessibilityService.getInstance().performGlobalAction(AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setLocationService(int desiredState, Context context)
|
||||
{
|
||||
// if(desiredState)
|
||||
// {
|
||||
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY).toString());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_OFF).toString());
|
||||
// }
|
||||
android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState));
|
||||
}
|
||||
|
||||
}
|
@ -39,8 +39,10 @@ public class ActivityControlCenter extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_control_center);
|
||||
|
||||
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@ -384,6 +386,7 @@ public class ActivityControlCenter extends Activity
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if (folder != null && folder.length() > 0)
|
||||
|
@ -21,6 +21,7 @@ public class ActivityDisplayLongMessage extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_display_long_message);
|
||||
|
||||
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
|
||||
|
@ -13,7 +13,8 @@ public class ActivityHelp extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(layout.help_text);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(layout.activity_help_text);
|
||||
|
||||
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
|
||||
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
@ -44,6 +44,7 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_poi_layout);
|
||||
|
||||
instance = this;
|
||||
@ -107,6 +108,13 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private void buttonAddPoi()
|
||||
{
|
||||
poiToEdit = null;
|
||||
|
@ -40,6 +40,7 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_profile_layout);
|
||||
|
||||
instance = this;
|
||||
@ -154,6 +155,13 @@ public class ActivityMainProfiles extends ActivityGeneric
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
private AlertDialog getProfileDialog(final Profile profile)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
|
@ -47,7 +47,8 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_rule_layout);
|
||||
|
||||
instance = this;
|
||||
@ -153,6 +154,13 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
|
@ -6,9 +6,12 @@ import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -31,6 +34,7 @@ import com.jens.automation2.location.LocationProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainScreen extends ActivityGeneric
|
||||
@ -51,6 +55,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.main_overview_layout);
|
||||
|
||||
activityMainScreenInstance = this;
|
||||
@ -429,7 +434,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
else
|
||||
activityMainScreenInstance.checkForNews();
|
||||
|
||||
if(BuildConfig.FLAVOR.equals("apkFlavor") && Settings.automaticUpdateCheck)
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk) && Settings.automaticUpdateCheck)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (Settings.lastUpdateCheck == Settings.default_lastUpdateCheck || now.getTimeInMillis() >= Settings.lastUpdateCheck + (long)(Settings.updateCheckFrequencyDays * 24 * 60 * 60 * 1000))
|
||||
@ -566,6 +571,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
|
@ -3,12 +3,17 @@ package com.jens.automation2;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.TabActivity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabHost.TabSpec;
|
||||
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainTabLayout extends TabActivity
|
||||
@ -17,8 +22,8 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
|
||||
if(Settings.tabsPlacement == 1)
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
|
||||
@ -60,6 +65,7 @@ public class ActivityMainTabLayout extends TabActivity
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
|
||||
NfcReceiver.checkIntentForNFC(this, getIntent());
|
||||
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass()));
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageActionBrightnessSetting extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
setContentView(R.layout.activity_manage_action_brightness_settings);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
|
||||
|
@ -259,6 +259,7 @@ public class ActivityManageActionCloseNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_close_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
|
@ -19,6 +19,7 @@ public class ActivityManageActionControlMedia extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_control_media);
|
||||
|
||||
rbMediaPlayPause = (RadioButton)findViewById(R.id.rbMediaPlayPause);
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionCopyToClipboard extends Activity
|
||||
{
|
||||
private Button bSaveCopyToClipboard;
|
||||
private EditText etCopyToClipboard;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_copy_to_clipboard);
|
||||
|
||||
bSaveCopyToClipboard = (Button) findViewById(R.id.bSaveCopyToClipboard);
|
||||
etCopyToClipboard = (EditText)findViewById(R.id.etCopyToClipboard);
|
||||
|
||||
bSaveCopyToClipboard.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(StringUtils.isEmpty(etCopyToClipboard.getText().toString()))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionCopyToClipboard.this, getResources().getString(R.string.enterText), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, etCopyToClipboard.getText().toString());
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String text = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
etCopyToClipboard.setText(text);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ public class ActivityManageActionCreateNotification extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_create_notification);
|
||||
|
||||
etNotificationTitle = (EditText) findViewById(R.id.etNotificationTitle);
|
||||
|
@ -0,0 +1,75 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageActionLocationService extends Activity
|
||||
{
|
||||
RadioButton rbActionLocationServiceOff, rbActionLocationServiceSensorsOnly, rbActionLocationServiceBatterySaving, rbActionLocationServiceHighAccuracy;
|
||||
Button bActionSetLocationServiceSave;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_location_service);
|
||||
|
||||
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
|
||||
rbActionLocationServiceSensorsOnly = (RadioButton)findViewById(R.id.rbActionLocationServiceSensorsOnly);
|
||||
rbActionLocationServiceBatterySaving = (RadioButton)findViewById(R.id.rbActionLocationServiceBatterySaving);
|
||||
rbActionLocationServiceHighAccuracy = (RadioButton)findViewById(R.id.rbActionLocationServiceHighAccuracy);
|
||||
bActionSetLocationServiceSave = (Button) findViewById(R.id.bActionSetLocationServiceSave);
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
int desiredState = Integer.parseInt(params[0]);
|
||||
|
||||
switch(desiredState)
|
||||
{
|
||||
case Settings.Secure.LOCATION_MODE_OFF:
|
||||
rbActionLocationServiceOff.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
|
||||
rbActionLocationServiceSensorsOnly.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
|
||||
rbActionLocationServiceBatterySaving.setChecked(true);
|
||||
break;
|
||||
case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
|
||||
rbActionLocationServiceHighAccuracy.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bActionSetLocationServiceSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
if(rbActionLocationServiceOff.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_OFF));
|
||||
else if(rbActionLocationServiceSensorsOnly.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_SENSORS_ONLY));
|
||||
else if(rbActionLocationServiceBatterySaving.isChecked())
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_BATTERY_SAVING));
|
||||
else
|
||||
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
|
||||
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ public class ActivityManageActionMakePhoneCall extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_make_phone_call);
|
||||
|
||||
etTargetPhoneNumber = (EditText)findViewById(R.id.etTargetPhoneNumber);
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageActionPlaySound extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_play_sound);
|
||||
|
||||
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
|
||||
|
@ -28,6 +28,7 @@ public class ActivityManageActionRunExecutable extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_run_executable);
|
||||
|
||||
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
|
||||
@ -57,6 +58,15 @@ public class ActivityManageActionRunExecutable extends Activity
|
||||
saveExecSettings();
|
||||
}
|
||||
});
|
||||
|
||||
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
|
||||
{
|
||||
String[] parts = getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
|
||||
etRunExecutablePath.setText(parts[0]);
|
||||
|
||||
if(parts.length > 1)
|
||||
etRunExecutableParameters.setText(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void saveExecSettings()
|
||||
|
@ -37,6 +37,7 @@ public class ActivityManageActionSendBroadcast extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_send_broadcast);
|
||||
|
||||
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
|
||||
@ -225,7 +226,7 @@ public class ActivityManageActionSendBroadcast extends Activity
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
|
||||
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
else
|
||||
|
@ -48,6 +48,7 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_send_textmessage);
|
||||
|
||||
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
|
||||
|
@ -24,6 +24,7 @@ public class ActivityManageActionSetVariable extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_set_variable);
|
||||
|
||||
etVariableSetKey = (EditText)findViewById(R.id.etVariableSetKey);
|
||||
@ -61,4 +62,4 @@ public class ActivityManageActionSetVariable extends Activity
|
||||
etVariableSetValue.setText(input[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ public class ActivityManageActionSpeakText extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_speak_text);
|
||||
|
||||
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
|
||||
|
@ -29,6 +29,7 @@ import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -48,17 +49,19 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
*/
|
||||
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath, etClassName;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
|
||||
Spinner spinnerParameterType;
|
||||
RadioGroup rgAppStartupType;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService;
|
||||
|
||||
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
|
||||
final static String startByActivityString = "0";
|
||||
final static String startByBroadcastString = "1";
|
||||
final static String startByServiceString = "2";
|
||||
public final static String startByActivityString = "0";
|
||||
public final static String startByBroadcastString = "1";
|
||||
public final static String startByServiceString = "2";
|
||||
public final static String startByForegroundServiceString = "3";
|
||||
|
||||
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
|
||||
|
||||
@ -66,11 +69,13 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
etClassName = (EditText)findViewById(R.id.etClassName);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
@ -83,13 +88,16 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
|
||||
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
|
||||
rbStartAppByService = (RadioButton)findViewById(R.id.rbStartAppByService);
|
||||
rbStartAppByForegroundService = (RadioButton)findViewById(R.id.rbStartAppByForegroundService);
|
||||
rgAppStartupType = (RadioGroup)findViewById(R.id.rgAppStartupType);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
etClassName.setEnabled(false);
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -226,23 +234,29 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
String parameter2 = "";
|
||||
|
||||
if (rbStartAppSelectByActivity.isChecked())
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
else {
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
{
|
||||
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
|
||||
parameter2 += Actions.dummyPackageString + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
|
||||
|
||||
// if(etClassName.getText().toString().length() > 0)
|
||||
parameter2 += Action.actionParameter2Split + etClassName.getText().toString();
|
||||
}
|
||||
|
||||
if (rbStartAppByActivity.isChecked())
|
||||
parameter2 += ";" + startByActivityString;
|
||||
parameter2 += Action.actionParameter2Split + startByActivityString;
|
||||
else if(rbStartAppByService.isChecked())
|
||||
parameter2 += ";" + startByServiceString;
|
||||
parameter2 += Action.actionParameter2Split + startByServiceString;
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
parameter2 += Action.actionParameter2Split + startByForegroundServiceString;
|
||||
else
|
||||
parameter2 += ";" + startByBroadcastString;
|
||||
parameter2 += Action.actionParameter2Split + startByBroadcastString;
|
||||
|
||||
for (String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
parameter2 += Action.actionParameter2Split + s;
|
||||
|
||||
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, parameter2);
|
||||
|
||||
@ -268,7 +282,7 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
else
|
||||
@ -289,7 +303,9 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
bSelectApp.setEnabled(isChecked);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -303,6 +319,23 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
rgAppStartupType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int i)
|
||||
{
|
||||
if(rbStartAppByActivity.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if (rbStartAppByBroadcast.isChecked())
|
||||
etClassName.setEnabled(false);
|
||||
else if(rbStartAppByService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
else if(rbStartAppByForegroundService.isChecked())
|
||||
etClassName.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.hasExtra(ActivityManageRule.intentNameActionParameter1))
|
||||
loadValuesIntoGui(i);
|
||||
@ -595,11 +628,27 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
rbStartAppSelectByActivity.setChecked(!selectionByAction);
|
||||
rbStartAppSelectByAction.setChecked(selectionByAction);
|
||||
|
||||
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";");
|
||||
String[] params;
|
||||
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
|
||||
|
||||
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[2].equals(startByServiceString));
|
||||
if(partsString.contains(Action.actionParameter2Split))
|
||||
params = partsString.split(Action.actionParameter2Split);
|
||||
else
|
||||
params = partsString.split(";");
|
||||
|
||||
if(Miscellaneous.isNumeric(params[2])) // old configuration file
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[2].equals(startByServiceString));
|
||||
}
|
||||
else
|
||||
{
|
||||
rbStartAppByActivity.setChecked(params[3].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[3].equals(startByBroadcastString));
|
||||
rbStartAppByService.setChecked(params[3].equals(startByServiceString));
|
||||
rbStartAppByForegroundService.setChecked(params[3].equals(startByForegroundServiceString));
|
||||
}
|
||||
|
||||
int startIndex = -1;
|
||||
|
||||
@ -614,10 +663,11 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
etPackageName.setText(params[0]);
|
||||
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
etClassName.setText(params[2]);
|
||||
}
|
||||
|
||||
if (params.length >= 3)
|
||||
startIndex = 3;
|
||||
if (params.length >= 4)
|
||||
startIndex = 4;
|
||||
|
||||
if(startIndex > -1 && params.length > startIndex)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -26,11 +27,15 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
|
||||
ListView lvTriggerUrlPostParameters;
|
||||
CheckBox chkTriggerUrlUseAuthentication;
|
||||
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
|
||||
TableLayout tlTriggerUrlAuthentication;
|
||||
|
||||
ArrayAdapter<Map<String,String>> lvTriggerUrlPostParametersAdapter;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
public static final String methodGet = "GET";
|
||||
public static final String methodPost = "POST";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
@ -39,6 +44,7 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_action_trigger_url);
|
||||
|
||||
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
|
||||
@ -48,6 +54,9 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
|
||||
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
|
||||
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveSpeakText);
|
||||
rbTriggerUrlMethodGet = (RadioButton) findViewById(R.id.rbTriggerUrlMethodGet);
|
||||
rbTriggerUrlMethodPost = (RadioButton) findViewById(R.id.rbTriggerUrlMethodPost);
|
||||
|
||||
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -58,6 +67,8 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
}
|
||||
|
||||
resultingAction.setAction(Action_Enum.triggerUrl);
|
||||
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
@ -69,13 +80,18 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
|
||||
String method = methodGet;
|
||||
if(rbTriggerUrlMethodPost.isChecked())
|
||||
method = methodPost;
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString().trim()
|
||||
etTriggerUrl.getText().toString().trim() + ";" +
|
||||
method
|
||||
);
|
||||
}
|
||||
|
||||
backToRuleManager();
|
||||
}
|
||||
else
|
||||
@ -83,16 +99,25 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chkTriggerUrlUseAuthentication.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.VISIBLE);
|
||||
rbTriggerUrlMethodGet.setChecked(false);
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
rbTriggerUrlMethodGet.setEnabled(false);
|
||||
rbTriggerUrlMethodPost.setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlTriggerUrlAuthentication.setVisibility(View.GONE);
|
||||
rbTriggerUrlMethodGet.setEnabled(true);
|
||||
rbTriggerUrlMethodPost.setEnabled(true);
|
||||
}
|
||||
|
||||
etTriggerUrlUsername.setEnabled(isChecked);
|
||||
etTriggerUrlPassword.setEnabled(isChecked);
|
||||
@ -108,7 +133,6 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
}
|
||||
});
|
||||
updateListView();
|
||||
|
||||
|
||||
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
@ -122,6 +146,20 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
|
||||
etTriggerUrlUsername.setText(components[0]);
|
||||
etTriggerUrlPassword.setText(components[1]);
|
||||
|
||||
if(components.length >= 4)
|
||||
{
|
||||
switch(components[3])
|
||||
{
|
||||
case methodPost:
|
||||
rbTriggerUrlMethodPost.setChecked(true);
|
||||
break;
|
||||
case methodGet:
|
||||
default:
|
||||
rbTriggerUrlMethodGet.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
etTriggerUrl.setText(components[0]);
|
||||
@ -140,13 +178,18 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
|
||||
String method = methodGet;
|
||||
if(rbTriggerUrlMethodPost.isChecked())
|
||||
method = methodPost;
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString()
|
||||
etTriggerUrl.getText().toString() + ";" +
|
||||
method
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ public class ActivityManageActionVibrate extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_vibrate);
|
||||
|
||||
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
|
||||
|
@ -27,6 +27,7 @@ public class ActivityManageActionWakeLock extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wakelock);
|
||||
|
||||
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
|
||||
|
@ -23,6 +23,7 @@ public class ActivityManageActionWifi extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_action_wifi);
|
||||
|
||||
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
|
||||
|
@ -59,6 +59,7 @@ public class ActivityManagePoi extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_poi);
|
||||
|
||||
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
|
@ -86,6 +86,7 @@ public class ActivityManageProfile extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
this.setContentView(R.layout.activity_manage_specific_profile);
|
||||
|
||||
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
|
||||
|
@ -139,6 +139,12 @@ public class ActivityManageRule extends Activity
|
||||
final static int requestCodeActionSetVariableEdit = 826;
|
||||
final static int requestCodeTriggerCheckVariableAdd = 827;
|
||||
final static int requestCodeTriggerCheckVariableEdit = 828;
|
||||
final static int requestCodeActionCopyTextToClipboardAdd = 829;
|
||||
final static int requestCodeActionCopyTextToClipboardEdit = 830;
|
||||
final static int requestCodeActionSetLocationServiceAdd = 831;
|
||||
final static int requestCodeActionSetLocationServiceEdit = 832;
|
||||
final static int requestCodeTriggerCalendarEventAdd = 833;
|
||||
final static int requestCodeTriggerCalendarEventEdit = 834;
|
||||
|
||||
public static ActivityManageRule getInstance()
|
||||
{
|
||||
@ -152,6 +158,7 @@ public class ActivityManageRule extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_specific_rule);
|
||||
|
||||
context = this;
|
||||
@ -342,6 +349,12 @@ public class ActivityManageRule extends Activity
|
||||
variableStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
|
||||
startActivityForResult(variableStateEditor, requestCodeTriggerCheckVariableEdit);
|
||||
break;
|
||||
case calendarEvent:
|
||||
Intent calendarStateEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerCalendar.class);
|
||||
calendarStateEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
|
||||
calendarStateEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
|
||||
startActivityForResult(calendarStateEditor, requestCodeTriggerCalendarEventEdit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -469,6 +482,18 @@ public class ActivityManageRule extends Activity
|
||||
actionPlaySoundIntent.putExtra(intentNameActionParameter2, a.getParameter2());
|
||||
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit);
|
||||
break;
|
||||
case copyToClipboard:
|
||||
Intent actionCopyToClipboardIntent = new Intent(context, ActivityManageActionCopyToClipboard.class);
|
||||
actionCopyToClipboardIntent.putExtra(intentNameActionParameter1, a.getParameter1());
|
||||
actionCopyToClipboardIntent.putExtra(intentNameActionParameter2, a.getParameter2());
|
||||
startActivityForResult(actionCopyToClipboardIntent, requestCodeActionCopyTextToClipboardEdit);
|
||||
break;
|
||||
case setLocationService:
|
||||
Intent actionSetLocationServiceIntent = new Intent(context, ActivityManageActionLocationService.class);
|
||||
// actionSetLocationServiceIntent.putExtra(intentNameActionParameter1, a.getParameter1());
|
||||
actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2());
|
||||
startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit);
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
|
||||
break;
|
||||
@ -619,6 +644,10 @@ public class ActivityManageRule extends Activity
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.router));
|
||||
else if(types[i].toString().equals(Trigger_Enum.subSystemState.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.subsystemstate));
|
||||
else if(types[i].toString().equals(Trigger_Enum.checkVariable.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
||||
else if(types[i].toString().equals(Trigger_Enum.calendarEvent.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.calendar));
|
||||
else
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
@ -627,15 +656,15 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
//User super class to create the View
|
||||
// User super class to create the View
|
||||
View v = super.getView(position, convertView, parent);
|
||||
|
||||
TextView tv = (TextView)v.findViewById(android.R.id.text1);
|
||||
|
||||
//Put the image on the TextView
|
||||
// Put the image on the TextView
|
||||
tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
|
||||
|
||||
//Add margin between image and text (support various screen densities)
|
||||
// Add margin between image and text (support various screen densities)
|
||||
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
|
||||
tv.setCompoundDrawablePadding(dp5);
|
||||
|
||||
@ -844,6 +873,13 @@ public class ActivityManageRule extends Activity
|
||||
startActivityForResult(variableTriggerEditor, requestCodeTriggerCheckVariableAdd);
|
||||
return;
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.calendarEvent)
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.calendarEvent);
|
||||
Intent calendarTriggerEditor = new Intent(myContext, ActivityManageTriggerCalendar.class);
|
||||
startActivityForResult(calendarTriggerEditor, requestCodeTriggerCalendarEventAdd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
getTriggerParameterDialog(context, booleanChoices).show();
|
||||
|
||||
@ -1764,7 +1800,7 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
|
||||
|
||||
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
|
||||
if(data.hasExtra(intentNameActionParameter2))
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
}
|
||||
@ -1977,6 +2013,17 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerCalendarEventAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
|
||||
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
|
||||
newTrigger.setParentRule(ruleToEdit);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerTetheringEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
@ -2016,6 +2063,70 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerCalendarEventEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Trigger editedTrigger = new Trigger();
|
||||
editedTrigger.setTriggerType(Trigger_Enum.calendarEvent);
|
||||
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
|
||||
editedTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
|
||||
editedTrigger.setParentRule(ruleToEdit);
|
||||
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionCopyTextToClipboardAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction.setParentRule(ruleToEdit);
|
||||
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
|
||||
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionCopyTextToClipboardEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
|
||||
|
||||
if(data.hasExtra(intentNameActionParameter2))
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
}
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSetLocationServiceAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction.setParentRule(ruleToEdit);
|
||||
// newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
|
||||
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSetLocationServiceEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
|
||||
// ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
|
||||
|
||||
if(data.hasExtra(intentNameActionParameter2))
|
||||
{
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
|
||||
}
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected AlertDialog getActionTypeDialog()
|
||||
@ -2090,6 +2201,14 @@ public class ActivityManageRule extends Activity
|
||||
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.message));
|
||||
}
|
||||
else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.clipboard));
|
||||
else if(types[i].toString().equals(Action_Enum.takeScreenshot.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.copier));
|
||||
else if(types[i].toString().equals(Action_Enum.setVariable.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
||||
else if(types[i].toString().equals(Action_Enum.setLocationService.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.compass_small));
|
||||
else
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
@ -2310,6 +2429,24 @@ public class ActivityManageRule extends Activity
|
||||
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
|
||||
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundAdd);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.copyToClipboard.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.copyToClipboard);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
|
||||
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.takeScreenshot.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.takeScreenshot);
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
refreshActionList();
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setLocationService.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setLocationService);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class);
|
||||
startActivityForResult(intent, requestCodeActionSetLocationServiceAdd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -32,6 +32,7 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_bluetooth);
|
||||
|
||||
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
|
||||
|
@ -28,6 +28,7 @@ public class ActivityManageTriggerBroadcast extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_broadcasts);
|
||||
|
||||
bBroadcastShowSuggestions = findViewById(R.id.bBroadcastShowSuggestions);
|
||||
|
@ -0,0 +1,349 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageTriggerCalendar extends Activity
|
||||
{
|
||||
CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent;
|
||||
Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection;
|
||||
EditText etCalendarTitle, etCalendarLocation, etCalendarDescription;
|
||||
LinearLayout llCalendarSelection;
|
||||
Button bSaveTriggerCalendar;
|
||||
List<CheckBox> checkboxesCalendars = new ArrayList<>();
|
||||
final static String separator = ",";
|
||||
TextView tvMissingCalendarHint;
|
||||
|
||||
private static String[] directions;
|
||||
ArrayAdapter<String> directionSpinnerAdapter;
|
||||
public static int requestCodePermissionReadCalendar = 815;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_calendar);
|
||||
|
||||
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
|
||||
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
|
||||
spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection);
|
||||
spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection);
|
||||
chkCalendarAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarAllDayEvent);
|
||||
chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy);
|
||||
chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree);
|
||||
chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative);
|
||||
chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice);
|
||||
chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere);
|
||||
|
||||
tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint);
|
||||
|
||||
llCalendarSelection = (LinearLayout)findViewById(R.id.llCalendarSelection);
|
||||
|
||||
etCalendarTitle = (EditText)findViewById(R.id.etCalendarTitle);
|
||||
etCalendarLocation = (EditText)findViewById(R.id.etCalendarLocation);
|
||||
etCalendarDescription = (EditText)findViewById(R.id.etCalendarDescription);
|
||||
|
||||
bSaveTriggerCalendar = (Button)findViewById(R.id.bSaveTriggerCalendar);
|
||||
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringDoesNotContain),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
};
|
||||
directionSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageTriggerCalendar.directions);
|
||||
spinnerCalendarTitleDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarLocationDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter);
|
||||
directionSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this))
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerCalendar.this);
|
||||
builder.setTitle(getResources().getString(R.string.info));
|
||||
builder.setMessage(getResources().getString(R.string.permissionCalendarRequired));
|
||||
builder.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
ActivityManageTriggerCalendar.this.finish();
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
requestPermissions(new String[]{ Manifest.permission.READ_CALENDAR } , requestCodePermissionReadCalendar);
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
else
|
||||
populateCalenderCheckboxes();
|
||||
|
||||
chkCalendarEventActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyHappening);
|
||||
else
|
||||
chkCalendarEventActive.setText(R.string.eventIsCurrentlyNotHappening);
|
||||
}
|
||||
});
|
||||
|
||||
chkCalendarAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
|
||||
{
|
||||
if(checked)
|
||||
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventTrue));
|
||||
else
|
||||
chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventFalse));
|
||||
}
|
||||
});
|
||||
|
||||
bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
String titleDir = Trigger.getMatchCode(spinnerCalendarTitleDirection.getSelectedItem().toString());
|
||||
String title = etCalendarTitle.getText().toString();
|
||||
String descriptionDir = Trigger.getMatchCode(spinnerCalendarDescriptionDirection.getSelectedItem().toString());
|
||||
String description = etCalendarDescription.getText().toString();
|
||||
String locationDir = Trigger.getMatchCode(spinnerCalendarLocationDirection.getSelectedItem().toString());
|
||||
String location = etCalendarLocation.getText().toString();
|
||||
|
||||
List<String> availabilityList = new ArrayList<>();
|
||||
if(chkCalendarAvailabilityBusy.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_BUSY));
|
||||
|
||||
if(chkCalendarAvailabilityFree.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_FREE));
|
||||
|
||||
if(chkCalendarAvailabilityTentative.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_TENTATIVE));
|
||||
|
||||
if(chkCalendarAvailabilityOutOfOffice.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE));
|
||||
|
||||
if(chkCalendarAvailabilityWorkingElsewhere.isChecked())
|
||||
availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE));
|
||||
|
||||
List<CalendarReceiver.AndroidCalendar> selectedCalendarsList = new ArrayList<>();
|
||||
for(CheckBox calCheckbox : checkboxesCalendars)
|
||||
{
|
||||
if(calCheckbox.isChecked())
|
||||
selectedCalendarsList.add((CalendarReceiver.AndroidCalendar) calCheckbox.getTag());
|
||||
}
|
||||
List<String> selectedCalendarsIdArray = new ArrayList<>();
|
||||
for(CalendarReceiver.AndroidCalendar cal : selectedCalendarsList)
|
||||
selectedCalendarsIdArray.add(String.valueOf(cal.calendarId));
|
||||
|
||||
String returnString =
|
||||
titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split +
|
||||
descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split +
|
||||
locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split +
|
||||
String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split +
|
||||
Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()]));
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkCalendarEventActive.isChecked());
|
||||
data.putExtra(ActivityManageRule.intentNameTriggerParameter2, returnString);
|
||||
ActivityManageTriggerCalendar.this.setResult(RESULT_OK, data);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Intent inputIntent = getIntent();
|
||||
if(inputIntent.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
loadValuesIntoGui(inputIntent);
|
||||
}
|
||||
|
||||
private void populateCalenderCheckboxes()
|
||||
{
|
||||
List<CalendarReceiver.AndroidCalendar> calList = CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this);
|
||||
|
||||
if(calList != null)
|
||||
{
|
||||
if(calList.size() > 0)
|
||||
{
|
||||
for (CalendarReceiver.AndroidCalendar cal : calList)
|
||||
{
|
||||
CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this);
|
||||
oneCalCheckbox.setText(cal.toString());
|
||||
oneCalCheckbox.setTag(cal);
|
||||
llCalendarSelection.addView(oneCalCheckbox);
|
||||
checkboxesCalendars.add(oneCalCheckbox);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.noCalendarsOnYourDevice), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
else
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.errorReadingCalendars), ActivityManageTriggerCalendar.this).show();
|
||||
}
|
||||
|
||||
void loadValuesIntoGui(Intent data)
|
||||
{
|
||||
//TODO:try-catch
|
||||
|
||||
if(data.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
|
||||
chkCalendarEventActive.setChecked(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
|
||||
|
||||
if(data.hasExtra(ActivityManageRule.intentNameTriggerParameter2))
|
||||
{
|
||||
String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split, -1);
|
||||
/*
|
||||
0 = titleDir
|
||||
1 = title
|
||||
2 = descriptionDir
|
||||
3 = description
|
||||
4 = locationDir
|
||||
5 = location
|
||||
6 = all day event
|
||||
7 = availability list
|
||||
8 = calendars list
|
||||
*/
|
||||
|
||||
for(int i = 0; i < directions.length; i++)
|
||||
{
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[0]))
|
||||
spinnerCalendarTitleDirection.setSelection(i);
|
||||
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[2]))
|
||||
spinnerCalendarDescriptionDirection.setSelection(i);
|
||||
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[4]))
|
||||
spinnerCalendarLocationDirection.setSelection(i);
|
||||
}
|
||||
|
||||
etCalendarTitle.setText(input[1]);
|
||||
etCalendarDescription.setText(input[3]);
|
||||
etCalendarLocation.setText(input[5]);
|
||||
|
||||
chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[6]));
|
||||
|
||||
String[] availabilities = null;
|
||||
if(!StringUtils.isEmpty(input[7]))
|
||||
availabilities = input[7].split(separator);
|
||||
|
||||
if(availabilities != null)
|
||||
{
|
||||
for (String avail : availabilities)
|
||||
{
|
||||
if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY)
|
||||
chkCalendarAvailabilityBusy.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_FREE)
|
||||
chkCalendarAvailabilityFree.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_TENTATIVE)
|
||||
chkCalendarAvailabilityTentative.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE)
|
||||
chkCalendarAvailabilityOutOfOffice.setChecked(true);
|
||||
else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE)
|
||||
chkCalendarAvailabilityWorkingElsewhere.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
String[] calendars = null;
|
||||
if(!StringUtils.isEmpty(input[8]))
|
||||
calendars = input[8].split(separator);
|
||||
|
||||
if(calendars != null)
|
||||
{
|
||||
List<String> usedCalendarIDs = new ArrayList<>();
|
||||
List<String> unusedCalendarIDs = new ArrayList<>();
|
||||
for (CheckBox checkbox : checkboxesCalendars)
|
||||
{
|
||||
int id = ((CalendarReceiver.AndroidCalendar) checkbox.getTag()).calendarId;
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (calId.equals(String.valueOf(id)))
|
||||
{
|
||||
usedCalendarIDs.add(String.valueOf(id));
|
||||
checkbox.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String calId : calendars)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch((ArrayList<String>) usedCalendarIDs, calId, false, true))
|
||||
unusedCalendarIDs.add(calId);
|
||||
}
|
||||
if (unusedCalendarIDs.size() > 0)
|
||||
{
|
||||
/*
|
||||
A calendar has been configured that has been deleted since. We cannot resolve it.
|
||||
It will be removed with the next save, but we should inform this user
|
||||
of these circumstances.
|
||||
*/
|
||||
|
||||
tvMissingCalendarHint.setText(String.format(getResources().getString(R.string.calendarsMissingHint), Miscellaneous.explode(", ", (ArrayList<String>) unusedCalendarIDs)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
if(requestCode == requestCodePermissionReadCalendar)
|
||||
{
|
||||
if(
|
||||
permissions[0].equals(Manifest.permission.READ_CALENDAR)
|
||||
||
|
||||
permissions[0].equals(Manifest.permission.WRITE_CALENDAR)
|
||||
)
|
||||
{
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
populateCalenderCheckboxes();
|
||||
else
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ public class ActivityManageTriggerCheckVariable extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_check_variable);
|
||||
|
||||
etVariableKeyTrigger = (EditText) findViewById(R.id.etVariableKeyTrigger);
|
||||
|
@ -104,6 +104,7 @@ public class ActivityManageTriggerDeviceOrientation extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_device_orientation);
|
||||
|
||||
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
|
||||
|
@ -39,6 +39,7 @@ public class ActivityManageTriggerNfc extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_nfc);
|
||||
|
||||
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
|
||||
|
@ -258,6 +258,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
|
@ -35,6 +35,7 @@ public class ActivityManageTriggerPhoneCall extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_phone_call);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
|
||||
|
@ -31,6 +31,7 @@ public class ActivityManageTriggerProfile extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_profile);
|
||||
|
||||
bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile);
|
||||
|
@ -21,6 +21,7 @@ public class ActivityManageTriggerSubSystemState extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_subsystemstate);
|
||||
|
||||
rbSubSystemStateWifi = (RadioButton)findViewById(R.id.rbSubSystemStateWifi);
|
||||
|
@ -26,6 +26,7 @@ public class ActivityManageTriggerTethering extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_tethering);
|
||||
|
||||
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
|
||||
|
@ -35,6 +35,7 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_timeframe);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
|
@ -12,11 +12,15 @@ import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
@ -43,12 +47,13 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
List<String> wifiList = new ArrayList<>();
|
||||
ArrayAdapter<String> wifiSpinnerAdapter;
|
||||
private final static int requestCodeLocationPermission = 124;
|
||||
TextView tvWifiTriggerNameLocationNotice;
|
||||
TextView tvWifiTriggerNameLocationNotice, tvWifiTriggerDisconnectionHint;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_manage_trigger_wifi);
|
||||
|
||||
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
|
||||
@ -58,6 +63,9 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
bTriggerWifiSave = (Button) findViewById(R.id.bTriggerWifiSave);
|
||||
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
|
||||
tvWifiTriggerNameLocationNotice = (TextView)findViewById(R.id.tvWifiTriggerNameLocationNotice);
|
||||
tvWifiTriggerDisconnectionHint = (TextView)findViewById(R.id.tvWifiTriggerDisconnectionHint);
|
||||
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
|
||||
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
|
||||
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
|
||||
@ -100,6 +108,11 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
etTriggerWifiName.setText(wifiList.get(position));
|
||||
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,6 +130,41 @@ public class ActivityManageTriggerWifi extends Activity
|
||||
loadWifis();
|
||||
}
|
||||
});
|
||||
|
||||
rbTriggerWifiDisconnected.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && b)
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
etTriggerWifiName.addTextChangedListener(new TextWatcher()
|
||||
{
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
|
||||
{
|
||||
if(etTriggerWifiName.getText().toString().length() > 0 && rbTriggerWifiDisconnected.isChecked())
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tvWifiTriggerDisconnectionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadWifis()
|
||||
|
@ -18,6 +18,8 @@ import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
@ -25,6 +27,8 @@ import android.widget.TextView;
|
||||
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
|
||||
import org.w3c.dom.DOMImplementationSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -47,12 +51,16 @@ public class ActivityPermissions extends Activity
|
||||
private static final int requestCodeForPermissionsNotifications = 12046;
|
||||
private static final int requestCodeForPermissionsDeviceAdmin = 12047;
|
||||
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
|
||||
private static final int requestCodeForPermissionNotificationAccessAndroid13 = 12049;
|
||||
private static final int requestCodeForPermissionsManageOverlay = 12050;
|
||||
private static final int requestCodeForPermissionsAccessibility = 12051;
|
||||
private static final int requestCodeForPermissionsScheduleExactAlarms = 12052;
|
||||
protected String[] specificPermissionsToRequest = null;
|
||||
|
||||
public static String intentExtraName = "permissionsToBeRequested";
|
||||
|
||||
Button bCancelPermissions, bRequestPermissions;
|
||||
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong;
|
||||
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong, tvRestrictionPermissionsNotice;
|
||||
static ActivityPermissions instance = null;
|
||||
|
||||
public final static String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
|
||||
@ -75,6 +83,7 @@ public class ActivityPermissions extends Activity
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.permissions_activity);
|
||||
|
||||
bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions);
|
||||
@ -82,6 +91,7 @@ public class ActivityPermissions extends Activity
|
||||
tvPermissionsExplanation = (TextView)findViewById(R.id.tvPermissionsExplanation);
|
||||
tvPermissionsExplanationSystemSettings = (TextView)findViewById(R.id.tvPermissionsExplanationSystemSettings);
|
||||
tvPermissionsExplanationLong = (TextView)findViewById(R.id.tvPermissionsExplanationLong);
|
||||
tvRestrictionPermissionsNotice = (TextView)findViewById(R.id.tvRestrictionPermissionsNotice);
|
||||
|
||||
bCancelPermissions.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@ -156,7 +166,7 @@ public class ActivityPermissions extends Activity
|
||||
/*
|
||||
Filter location permission and only name it once
|
||||
*/
|
||||
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) | s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
|
||||
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) || s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
|
||||
{
|
||||
if(!locationPermissionExplained)
|
||||
{
|
||||
@ -258,8 +268,7 @@ public class ActivityPermissions extends Activity
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!havePermission(s, context))
|
||||
else if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -297,6 +306,14 @@ public class ActivityPermissions extends Activity
|
||||
String packageName = context.getApplicationContext().getPackageName();
|
||||
return pm.isIgnoringBatteryOptimizations(packageName);
|
||||
}
|
||||
else if (s.equals(Manifest.permission.SYSTEM_ALERT_WINDOW))
|
||||
{
|
||||
return android.provider.Settings.canDrawOverlays(Miscellaneous.getAnyContext());
|
||||
}
|
||||
else if(s.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
return haveAccessibilityAccess(Miscellaneous.getAnyContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = context.checkCallingOrSelfPermission(s);
|
||||
@ -315,6 +332,59 @@ public class ActivityPermissions extends Activity
|
||||
return active;
|
||||
}
|
||||
|
||||
public static boolean haveAccessibilityAccess(Context mContext)
|
||||
{
|
||||
int accessibilityEnabled = 0;
|
||||
|
||||
final String service = mContext.getPackageName() + "/" + BuildConfig.APPLICATION_ID + ".MyAccessibilityService";
|
||||
|
||||
boolean accessibilityFound = false;
|
||||
try
|
||||
{
|
||||
accessibilityEnabled = Settings.Secure.getInt(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
// Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled);
|
||||
}
|
||||
catch (Settings.SettingNotFoundException e)
|
||||
{
|
||||
// Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage());
|
||||
}
|
||||
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
|
||||
|
||||
if (accessibilityEnabled == 1)
|
||||
{
|
||||
String settingValue = Settings.Secure.getString(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
if (settingValue != null)
|
||||
{
|
||||
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
|
||||
splitter.setString(settingValue);
|
||||
while (splitter.hasNext())
|
||||
{
|
||||
String accessibilityService = splitter.next();
|
||||
|
||||
if (accessibilityService.equalsIgnoreCase(service))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return accessibilityFound;
|
||||
}
|
||||
|
||||
public static void requestOverlay()
|
||||
{
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsManageOverlay);
|
||||
}
|
||||
|
||||
public static void requestBindAccessibilityService()
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsAccessibility);
|
||||
}
|
||||
|
||||
public static void requestDeviceAdmin()
|
||||
{
|
||||
if(!haveDeviceAdmin())
|
||||
@ -357,10 +427,13 @@ public class ActivityPermissions extends Activity
|
||||
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
|
||||
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
|
||||
|
||||
for(Profile p : Profile.getProfileCollection())
|
||||
if(!havePermission(Manifest.permission.READ_EXTERNAL_STORAGE, workingContext))
|
||||
{
|
||||
if(p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
for (Profile p : Profile.getProfileCollection())
|
||||
{
|
||||
if (p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
|
||||
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyGeneral)
|
||||
@ -394,27 +467,6 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Not all permissions need to be asked for.
|
||||
*/
|
||||
|
||||
/*if(shouldShowRequestPermissionRationale("android.permission.RECORD_AUDIO"))
|
||||
Toast.makeText(ActivityMainScreen.this, "shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toast.makeText(ActivityMainScreen.this, "not shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();*/
|
||||
|
||||
// addToArrayListUnique("Manifest.permission.RECORD_AUDIO", requiredPermissions);
|
||||
/*int hasPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
|
||||
if (hasPermission == PackageManager.PERMISSION_DENIED)
|
||||
{
|
||||
Toast.makeText(ActivityMainScreen.this, "Don't have record_audio. Requesting...", Toast.LENGTH_LONG).show();
|
||||
// requestPermissions(new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
|
||||
ActivityCompat.requestPermissions(ActivityMainScreen.this, new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMainScreen.this, "Have record_audio.", Toast.LENGTH_LONG).show();*/
|
||||
|
||||
}
|
||||
|
||||
return requiredPermissions.toArray(new String[requiredPermissions.size()]);
|
||||
@ -443,7 +495,8 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
case activityDetection:
|
||||
addToArrayListUnique(permissionNameGoogleActivityDetection, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACTIVITY_RECOGNITION, requiredPermissions);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
addToArrayListUnique(Manifest.permission.ACTIVITY_RECOGNITION, requiredPermissions);
|
||||
break;
|
||||
case airplaneMode:
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
@ -473,6 +526,7 @@ public class ActivityPermissions extends Activity
|
||||
case phoneCall:
|
||||
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.PROCESS_OUTGOING_CALLS, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.READ_CALL_LOG, requiredPermissions);
|
||||
break;
|
||||
case pointOfInterest:
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
@ -505,6 +559,8 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
|
||||
break;
|
||||
case timeFrame:
|
||||
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
|
||||
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
|
||||
break;
|
||||
case usb_host_connection:
|
||||
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
|
||||
@ -514,15 +570,24 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, requiredPermissions);
|
||||
if(
|
||||
(
|
||||
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
|
||||
&&
|
||||
isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
)
|
||||
||
|
||||
Build.VERSION.SDK_INT >= 33
|
||||
)
|
||||
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, requiredPermissions);
|
||||
break;
|
||||
case notification:
|
||||
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
|
||||
break;
|
||||
case calendarEvent:
|
||||
addToArrayListUnique(Manifest.permission.READ_CALENDAR, requiredPermissions);
|
||||
if(Build.VERSION.SDK_INT >= 31 && Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 31)
|
||||
addToArrayListUnique(Manifest.permission.SCHEDULE_EXACT_ALARM, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -630,6 +695,19 @@ public class ActivityPermissions extends Activity
|
||||
// action.getParameter2().contains("eu.faircode.netguard.STOP_PORT_FORWARD")
|
||||
// )
|
||||
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
|
||||
if(Build.VERSION.SDK_INT >= 29)
|
||||
{
|
||||
String parts[];
|
||||
if(action.getParameter2().contains(Action.actionParameter2Split))
|
||||
parts = action.getParameter2().split(Action.actionParameter2Split);
|
||||
else
|
||||
parts = action.getParameter2().split(";");
|
||||
|
||||
// Permission only required for starts of activity, not broadcasts or services
|
||||
|
||||
if(parts[2].equals(ActivityManageActionStartActivity.startByActivityString))
|
||||
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
}
|
||||
break;
|
||||
case triggerUrl:
|
||||
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
|
||||
@ -685,11 +763,17 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case startPhoneCall:
|
||||
addToArrayListUnique(Manifest.permission.CALL_PHONE, requiredPermissions);
|
||||
// addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
|
||||
break;
|
||||
case stopPhoneCall:
|
||||
addToArrayListUnique(Manifest.permission.ANSWER_PHONE_CALLS, requiredPermissions);
|
||||
break;
|
||||
case takeScreenshot:
|
||||
addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions);
|
||||
break;
|
||||
case setLocationService:
|
||||
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -752,14 +836,19 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.WRITE_EXTERNAL_STORAGE:
|
||||
usingElements.add(getResources().getString(R.string.storeSettings));
|
||||
break;
|
||||
case Manifest.permission.SCHEDULE_EXACT_ALARM:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.timeFrame))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.notification))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case permissionNameGoogleActivityDetection:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.closeNotification))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case permissionNameGoogleActivityDetection:
|
||||
case Manifest.permission.ACTIVITY_RECOGNITION:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
@ -774,6 +863,7 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case Manifest.permission.ACCESS_BACKGROUND_LOCATION:
|
||||
usingElements.add(getResources().getString(R.string.googleLocationChicanery));
|
||||
usingElements.add(getResources().getString(R.string.wifiMonitoringAlsoRequiresThis));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
|
||||
@ -858,6 +948,7 @@ public class ActivityPermissions extends Activity
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.PROCESS_OUTGOING_CALLS:
|
||||
case Manifest.permission.READ_CALL_LOG:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.phoneCall))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
@ -885,6 +976,12 @@ public class ActivityPermissions extends Activity
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.SYSTEM_ALERT_WINDOW:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.startOtherActivity))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.startPhoneCall))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.ANSWER_PHONE_CALLS:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.stopPhoneCall))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
@ -932,6 +1029,18 @@ public class ActivityPermissions extends Activity
|
||||
case Manifest.permission.QUERY_ALL_PACKAGES:
|
||||
usingElements.add(getResources().getString(R.string.queryAllPackages));
|
||||
break;
|
||||
case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.takeScreenshot))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.WRITE_SECURE_SETTINGS:
|
||||
for(String ruleName : getRulesUsing(Action.Action_Enum.setLocationService))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
case Manifest.permission.READ_CALENDAR:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
break;
|
||||
}
|
||||
|
||||
return usingElements;
|
||||
@ -940,6 +1049,15 @@ public class ActivityPermissions extends Activity
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
/*
|
||||
All of the following permissions need to be "manually" activated by the user in some
|
||||
buried system menu.
|
||||
In my opinion by mistake the function will be called when the user has just landed
|
||||
on one of those screens, not when he exits it again. To compensate for that onResume()
|
||||
is overridden. This enables the permission screen to automatically close after all
|
||||
required permissions have been granted.
|
||||
*/
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
@ -983,6 +1101,18 @@ public class ActivityPermissions extends Activity
|
||||
if (requestCode == requestCodeForPermissionsBatteryOptimization)
|
||||
if(havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsManageOverlay)
|
||||
if(havePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsAccessibility)
|
||||
if(havePermission(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
|
||||
if (requestCode == requestCodeForPermissionsScheduleExactAlarms)
|
||||
if(havePermission(Manifest.permission.SCHEDULE_EXACT_ALARM, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1033,7 +1163,7 @@ public class ActivityPermissions extends Activity
|
||||
startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
|
||||
return;
|
||||
}
|
||||
if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
@ -1042,18 +1172,88 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.noticeRestrictedPermissions), ActivityPermissions.this).show();
|
||||
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.SYSTEM_ALERT_WINDOW))
|
||||
{
|
||||
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.overlayPermissionHint), ActivityPermissions.this);
|
||||
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestOverlay();
|
||||
}
|
||||
});
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.accessibilityApiPermissionHint), ActivityPermissions.this);
|
||||
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestBindAccessibilityService();
|
||||
}
|
||||
});
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotifications);
|
||||
if(Build.VERSION.SDK_INT >= 33)
|
||||
{
|
||||
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.notificationAccessAndroid13), ActivityPermissions.this);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestNotificationAccess();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestNotificationAccess();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(Manifest.permission.SCHEDULE_EXACT_ALARM))
|
||||
{
|
||||
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.alarmsPermissionHint), ActivityPermissions.this);
|
||||
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialogInterface)
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
requestScheduleExactAlarms();
|
||||
}
|
||||
});
|
||||
diag.show();
|
||||
return;
|
||||
}
|
||||
else if(s.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
|
||||
@ -1085,6 +1285,13 @@ public class ActivityPermissions extends Activity
|
||||
|
||||
return;
|
||||
}
|
||||
else if(s.equalsIgnoreCase(Manifest.permission.WRITE_SECURE_SETTINGS))
|
||||
{
|
||||
AlertDialog diaglog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.writeSecureSettingsNotice), ActivityPermissions.this);
|
||||
diaglog.show();
|
||||
Linkify.addLinks((TextView) diaglog.findViewById(android.R.id.message), Linkify.ALL);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1128,6 +1335,20 @@ public class ActivityPermissions extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
void requestNotificationAccess()
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotifications);
|
||||
}
|
||||
|
||||
|
||||
void requestScheduleExactAlarms()
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
|
||||
startActivityForResult(intent, requestCodeForPermissionsScheduleExactAlarms);
|
||||
}
|
||||
|
||||
|
||||
protected void applyChanges()
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
@ -1506,4 +1727,47 @@ public class ActivityPermissions extends Activity
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 33 && BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
{
|
||||
for (String p : getRequiredPermissions(false))
|
||||
{
|
||||
if (p.equals(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE) || p.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
|
||||
{
|
||||
tvRestrictionPermissionsNotice.setText(getResources().getString(R.string.noticeRestrictedPermissions));
|
||||
|
||||
/*
|
||||
Opening the app's settings directly does not work because the
|
||||
mentioned 3 dots are only displayed when you went there the hard way.
|
||||
*/
|
||||
/*
|
||||
tvRestrictionPermissionsNotice.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
})*/;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String p : getRequiredPermissions(false))
|
||||
{
|
||||
if(!havePermission(p, this))
|
||||
return;
|
||||
}
|
||||
|
||||
// have all
|
||||
setHaveAllPermissions();
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ public class ActivitySettings extends PreferenceActivity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
addPreferencesFromResource(layout.activity_settings);
|
||||
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
|
||||
@ -24,4 +25,11 @@ public class ActivitySettings extends PreferenceActivity
|
||||
chkPrefUpdateCheck.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ public class ActivityVolumeTest extends Activity
|
||||
instance = this;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
Miscellaneous.setDisplayLanguage(this);
|
||||
setContentView(R.layout.activity_volume_calibration);
|
||||
|
||||
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AsyncTasks
|
||||
@ -23,7 +22,7 @@ public class AsyncTasks
|
||||
|
||||
try
|
||||
{
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null).trim();
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null, ActivityManageActionTriggerUrl.methodGet).trim();
|
||||
int latestVersion = Integer.parseInt(result);
|
||||
|
||||
// At this point the update check itself has already been successful.
|
||||
|
@ -34,13 +34,14 @@ import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
protected TextToSpeech ttsEngine = null;
|
||||
protected int ttsStatus = -1;
|
||||
protected final static int notificationId = 1000;
|
||||
protected final static int notificationIdRestrictions = 1005;
|
||||
protected final static int notificationIdLocationRestriction = 1006;
|
||||
@ -97,6 +98,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
this.lockSoundChangesEnd = lockSoundChangesEnd;
|
||||
}
|
||||
|
||||
public int getTtsStatus()
|
||||
{
|
||||
return ttsStatus;
|
||||
}
|
||||
|
||||
protected final IBinder myBinder = new LocalBinder();
|
||||
|
||||
protected LocationProvider myLocationProvider;
|
||||
@ -120,6 +126,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
// Store a reference to myself. Other classes often need a context or something, this can provide that.
|
||||
centralInstance = this;
|
||||
|
||||
Miscellaneous.setDisplayLanguage(AutomationService.this);
|
||||
}
|
||||
|
||||
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
|
||||
@ -215,7 +223,10 @@ public class AutomationService extends Service implements OnInitListener
|
||||
startUpRoutine();
|
||||
|
||||
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
if(getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_MUTABLE);
|
||||
else
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
notificationBuilder = createServiceNotificationBuilder();
|
||||
|
||||
updateNotification();
|
||||
@ -226,7 +237,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
this.isRunning = true;
|
||||
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
|
||||
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
|
||||
|
||||
/*
|
||||
On normal phones the app is supposed to automatically restart in case of any problems.
|
||||
@ -306,7 +318,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
stopRoutine();
|
||||
this.isRunning = false;
|
||||
Toast.makeText(this, getResources().getString(R.string.serviceStopped), Toast.LENGTH_LONG).show();
|
||||
if(Settings.showToasts)
|
||||
Toast.makeText(this, getResources().getString(R.string.serviceStopped), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.serviceStopped), 1);
|
||||
}
|
||||
|
||||
@ -315,8 +328,26 @@ public class AutomationService extends Service implements OnInitListener
|
||||
if (Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate || Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
|
||||
{
|
||||
if (ttsEngine == null)
|
||||
ttsEngine = new TextToSpeech(this, this);
|
||||
} else
|
||||
{
|
||||
ttsEngine = new TextToSpeech(this, new TextToSpeech.OnInitListener()
|
||||
{
|
||||
@Override
|
||||
public void onInit(int status)
|
||||
{
|
||||
ttsStatus = status;
|
||||
|
||||
if (status == TextToSpeech.SUCCESS)
|
||||
{
|
||||
ttsEngine.setLanguage(Locale.getDefault());
|
||||
Miscellaneous.logEvent("i", "TTS engine", "TTS engine available.", 3);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "TTS engine", "TTS engine not available. Status: " + String.valueOf(status), 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ttsEngine != null)
|
||||
ttsEngine.shutdown();
|
||||
@ -490,7 +521,12 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setContentTitle("Automation");
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
@ -498,7 +534,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
Notification defaultNotification = builder.build();
|
||||
|
||||
defaultNotification.icon = R.drawable.ic_launcher;
|
||||
defaultNotification.icon = R.drawable.crane;
|
||||
defaultNotification.when = System.currentTimeMillis();
|
||||
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
@ -545,7 +581,12 @@ public class AutomationService extends Service implements OnInitListener
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
// builder.setContentText(textToDisplay);
|
||||
// builder.setSmallIcon(icon);
|
||||
@ -671,25 +712,26 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < 5; i++)
|
||||
for(int i = 0; i < 60; i++)
|
||||
{
|
||||
if(ttsEngine != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
if(ttsEngine == null || ttsStatus != TextToSpeech.SUCCESS)
|
||||
{
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TTS", "Waiting for a moment to give the TTS service time to load...", 4);
|
||||
Thread.sleep(1000); // give the tts engine time to load
|
||||
Thread.sleep(500); // give the tts engine time to load
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking \"" + text + "\" in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
|
||||
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking " + text + " in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
|
||||
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "TTS engine not available after waiting 30 seconds, yet. Aborting.", 3);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.RingtoneManager;
|
||||
@ -31,6 +32,7 @@ import android.provider.Settings.Secure;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Base64;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -42,7 +44,11 @@ import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
@ -68,6 +74,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@ -75,6 +82,8 @@ import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
@ -111,9 +120,11 @@ import androidx.documentfile.provider.DocumentFile;
|
||||
public class Miscellaneous extends Service
|
||||
{
|
||||
protected static String writeableFolderStringCache = null;
|
||||
public static Context startupContext;
|
||||
|
||||
public static final String lineSeparator = System.getProperty("line.separator");
|
||||
|
||||
public static String downloadURL(String url, String username, String password)
|
||||
public static String downloadURL(String url, String username, String password, String method)
|
||||
{
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
StringBuilder responseBody = new StringBuilder();
|
||||
@ -141,6 +152,8 @@ public class Miscellaneous extends Service
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty ("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
InputStream content = (InputStream)connection.getInputStream();
|
||||
BufferedReader in = new BufferedReader (new InputStreamReader (content));
|
||||
@ -167,33 +180,42 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
}
|
||||
|
||||
public static String downloadURLwithoutCertificateChecking(String url, String username, String password)
|
||||
public static String downloadURLwithoutCertificateChecking(String url, String username, String password, String method)
|
||||
{
|
||||
// HttpClient httpclient = new DefaultHttpClient();
|
||||
// StringBuilder responseBody = new StringBuilder();
|
||||
boolean errorFound = false;
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
HttpParams params = new BasicHttpParams();
|
||||
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
|
||||
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
|
||||
HttpClient httpclient = new DefaultHttpClient(params);
|
||||
httpclient = Actions.getInsecureSslClient(httpclient);
|
||||
|
||||
HttpPost httppost = new HttpPost(url);
|
||||
|
||||
HttpRequestBase httpRequest;
|
||||
if(
|
||||
method.equals(ActivityManageActionTriggerUrl.methodPost)
|
||||
||
|
||||
(username != null && password != null)
|
||||
)
|
||||
httpRequest = new HttpPost(url);
|
||||
else
|
||||
httpRequest = new HttpGet(url);
|
||||
/*httpRequest = new HttpEntityEnclosingRequestBase()
|
||||
{
|
||||
@Override
|
||||
public String getMethod()
|
||||
{
|
||||
return "GET";
|
||||
}
|
||||
};*/
|
||||
|
||||
// Add http simple authentication if specified
|
||||
if(username != null && password != null)
|
||||
{
|
||||
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
||||
// List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
|
||||
httppost.addHeader("Authorization", "Basic " + encodedCredentials);
|
||||
// nameValuePairs.add(new BasicNameValuePair("Authorization", "Basic " + encodedCredentials));
|
||||
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
|
||||
httpRequest.addHeader("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
HttpResponse response = httpclient.execute(httpRequest);
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (entity != null)
|
||||
{
|
||||
@ -204,8 +226,7 @@ public class Miscellaneous extends Service
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
||||
errorFound = true;
|
||||
return "httpError";
|
||||
return "httpError";
|
||||
}
|
||||
// finally
|
||||
// {
|
||||
@ -273,7 +294,7 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
writeToLogFile(type, header, description);
|
||||
|
||||
if(!logCleanerRunning && Math.random() < 0.1) // tidy up with 10% probability
|
||||
if (!logCleanerRunning && Math.random() < 0.1) // tidy up with 10% probability
|
||||
{
|
||||
rotateLogFile(getLogFile());
|
||||
}
|
||||
@ -557,7 +578,10 @@ public class Miscellaneous extends Service
|
||||
returnContext = ActivityPermissions.getInstance().getApplicationContext();
|
||||
if(returnContext != null)
|
||||
return returnContext;
|
||||
|
||||
|
||||
if(startupContext != null)
|
||||
return startupContext;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -609,10 +633,12 @@ public class Miscellaneous extends Service
|
||||
}
|
||||
|
||||
if(source.contains("[serialnr]"))
|
||||
if(Build.VERSION.SDK_INT > 8)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT > 8)
|
||||
source = source.replace("[serialnr]", Secure.getString(context.getContentResolver(), Build.SERIAL));
|
||||
else
|
||||
source = source.replace("[serialnr]", "serialUnknown");
|
||||
}
|
||||
|
||||
if(
|
||||
source.contains("[d]") ||
|
||||
@ -683,7 +709,7 @@ public class Miscellaneous extends Service
|
||||
if(result.length() < 2)
|
||||
result = "0" + result;
|
||||
|
||||
source = source.replace("[s]", String.valueOf(cal.get(Calendar.SECOND)));
|
||||
source = source.replace("[s]", result);
|
||||
}
|
||||
|
||||
if(source.contains("[ms]"))
|
||||
@ -699,7 +725,7 @@ public class Miscellaneous extends Service
|
||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||
|
||||
if (notificationTitle != null && notificationTitle.length() > 0)
|
||||
source = source.replace("[notificationTitle]", notificationTitle);
|
||||
source = source.replace("[notificationTitle]", escapeStringForUrl(notificationTitle));
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationTitle]", "notificationTitle unknown");
|
||||
@ -720,7 +746,7 @@ public class Miscellaneous extends Service
|
||||
String notificationText = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if (notificationText != null && notificationText.length() > 0)
|
||||
source = source.replace("[notificationText]", notificationText);
|
||||
source = source.replace("[notificationText]", escapeStringForUrl(notificationText));
|
||||
else
|
||||
{
|
||||
source = source.replace("[notificationText]", "notificationText unknown");
|
||||
@ -733,6 +759,26 @@ public class Miscellaneous extends Service
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "lastNotification was empty.", 3);
|
||||
}
|
||||
}
|
||||
|
||||
while(source.contains("[variable-"))
|
||||
{
|
||||
int pos1 = source.indexOf("[variable-");
|
||||
int pos2 = source.indexOf("]", pos1);
|
||||
|
||||
int posA = pos1 + "[variable-".length();
|
||||
int posB = source.indexOf("]", posA);
|
||||
|
||||
String variableName = source.substring(posA, posB);
|
||||
|
||||
String replacement;
|
||||
|
||||
if(AutomationService.getInstance().variableMap.containsKey(variableName))
|
||||
replacement = AutomationService.getInstance().variableMap.get(variableName);
|
||||
else
|
||||
replacement = "unknownVariable";
|
||||
|
||||
source = source.substring(0, pos1) + escapeStringForUrl(replacement) + source.substring(pos2 +1);
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "URL after replace", source);
|
||||
|
||||
@ -760,7 +806,7 @@ public class Miscellaneous extends Service
|
||||
alertDialog.setTitle(title);
|
||||
alertDialog.setMessage(message);
|
||||
|
||||
alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener()
|
||||
alertDialog.setPositiveButton(context.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int whichButton)
|
||||
{
|
||||
@ -1135,7 +1181,12 @@ public class Miscellaneous extends Service
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
{
|
||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
builder.setSmallIcon(R.drawable.crane);
|
||||
else
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
}
|
||||
else if(!notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||
builder.setSmallIcon(R.drawable.info);
|
||||
|
||||
@ -1980,4 +2031,53 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
return context.getApplicationContext().getApplicationInfo().targetSdkVersion;
|
||||
}
|
||||
|
||||
public static void setDisplayLanguage(Context context)
|
||||
{
|
||||
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
|
||||
{
|
||||
Locale myLocale;
|
||||
|
||||
if(Settings.displayLanguage.contains("_"))
|
||||
{
|
||||
String[] parts = Settings.displayLanguage.split("_");
|
||||
myLocale = new Locale(parts[0], parts[1]);
|
||||
}
|
||||
else
|
||||
myLocale = new Locale(Settings.displayLanguage);
|
||||
|
||||
Resources res = context.getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
Configuration conf = res.getConfiguration();
|
||||
conf.locale = myLocale;
|
||||
res.updateConfiguration(conf, dm);
|
||||
//Intent refresh = new Intent(this, AndroidLocalize.class);
|
||||
//finish();
|
||||
//startActivity(refresh);
|
||||
}
|
||||
}
|
||||
|
||||
public static String escapeStringForUrl(String input)
|
||||
{
|
||||
String output;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
try
|
||||
{
|
||||
output = URLEncoder.encode(input, String.valueOf(StandardCharsets.UTF_8));
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "URLEncoder", "Error encoding string for URL. Leaving as it is. Error details: " + Log.getStackTraceString(e), 3);
|
||||
output = input;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = Uri.encode(input);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class MyAccessibilityService extends AccessibilityService
|
||||
{
|
||||
static MyAccessibilityService instance;
|
||||
|
||||
public static MyAccessibilityService getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
{
|
||||
instance = new MyAccessibilityService();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceConnected()
|
||||
{
|
||||
super.onServiceConnected();
|
||||
Miscellaneous.logEvent("i", "Accessibility service", "Service started.", 4);
|
||||
}
|
||||
}
|
@ -79,7 +79,7 @@ public class News
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
String newsUrl = "https://server47.de/automation/appNews.php";
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null, ActivityManageActionTriggerUrl.methodGet);
|
||||
|
||||
// Cache content to local storage
|
||||
if(Miscellaneous.writeStringToFile(filePath, newsContent))
|
||||
|
@ -421,14 +421,18 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
public boolean create(Context context)
|
||||
{
|
||||
for(PointOfInterest poi : PointOfInterest.pointOfInterestCollection)
|
||||
if(poi.getName().equals(this.getName()))
|
||||
{
|
||||
if (poi.getName().equals(this.getName()))
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.anotherPoiByThatName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Creating POI", this.toStringLong(), 3);
|
||||
|
||||
PointOfInterest.pointOfInterestCollection.add(this);
|
||||
PointOfInterest.writePoisToFile();
|
||||
|
||||
@ -490,8 +494,10 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
Check for change of rule name END
|
||||
*/
|
||||
|
||||
if (plausibilityCheck())
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Changing POI", "Old name: " + this.oldName + ", new data: " + this.toStringLong(), 3);
|
||||
|
||||
if(PointOfInterest.writePoisToFile())
|
||||
{
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||
import com.jens.automation2.location.CellLocationChangedReceiver;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.BroadcastListener;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.DateTimeListener;
|
||||
import com.jens.automation2.receivers.AutomationListenerInterface;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
@ -145,7 +146,8 @@ public class ReceiverCoordinator
|
||||
}
|
||||
|
||||
// startPhoneStateListener
|
||||
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
ConnectivityReceiver.startConnectivityReceiver(AutomationService.getInstance());
|
||||
@ -209,6 +211,9 @@ public class ReceiverCoordinator
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.screenState))
|
||||
ScreenStateReceiver.startScreenStateReceiver(AutomationService.getInstance());
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.calendarEvent))
|
||||
CalendarReceiver.startCalendarReceiver(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
public static void stopAllReceivers()
|
||||
@ -242,6 +247,7 @@ public class ReceiverCoordinator
|
||||
BluetoothReceiver.stopBluetoothReceiver();
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
CalendarReceiver.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -391,11 +397,11 @@ public class ReceiverCoordinator
|
||||
}
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.headsetPlugged))
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.headsetPlugged))
|
||||
{
|
||||
if(!HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Starting HeadphoneJackListener because used in a new/changed rule.", 4);
|
||||
if(HeadphoneJackListener.getInstance().haveAllPermission())
|
||||
HeadphoneJackListener.getInstance().startListener(AutomationService.getInstance());
|
||||
}
|
||||
@ -404,7 +410,7 @@ public class ReceiverCoordinator
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadphoneJackListenerActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Shutting down HeadphoneJackListener because not used in any rule.", 4);
|
||||
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,10 @@ public class Settings implements SharedPreferences
|
||||
public static int tabsPlacement;
|
||||
public static boolean executeRulesAndProfilesWithSingleClick;
|
||||
public static boolean displayNewsOnMainScreen;
|
||||
public static boolean showToasts;
|
||||
public static boolean automaticUpdateCheck;
|
||||
public static long musicCheckFrequency;
|
||||
public static String displayLanguage;
|
||||
|
||||
public static boolean lockSoundChanges;
|
||||
public static boolean noticeAndroid9MicrophoneShown;
|
||||
@ -130,11 +132,14 @@ public class Settings implements SharedPreferences
|
||||
public static final int default_tabsPlacement = 0;
|
||||
public static final boolean default_executeRulesAndProfilesWithSingleClick = false;
|
||||
public static final boolean default_displayNewsOnMainScreen = false;
|
||||
|
||||
public static final boolean default_showToasts = true;
|
||||
public static final boolean default_automaticUpdateCheck = false;
|
||||
public static final boolean default_lockSoundChanges = false;
|
||||
public static final long default_lastNewsPolltime = -1;
|
||||
public static final long default_lastUpdateCheck = -1;
|
||||
public static final long default_musicCheckFrequency = 2500;
|
||||
public static final String default_displayLanguage = "systemDefaultLanguage";
|
||||
|
||||
@Override
|
||||
public boolean contains(String arg0)
|
||||
@ -270,6 +275,7 @@ public class Settings implements SharedPreferences
|
||||
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
|
||||
|
||||
musicCheckFrequency = Long.parseLong(prefs.getString("musicCheckFrequency", String.valueOf(default_musicCheckFrequency)));
|
||||
displayLanguage = prefs.getString("displayLanguage", default_displayLanguage);
|
||||
|
||||
if(Settings.musicCheckFrequency == 0)
|
||||
Settings.musicCheckFrequency = Settings.default_musicCheckFrequency;
|
||||
@ -277,6 +283,7 @@ public class Settings implements SharedPreferences
|
||||
executeRulesAndProfilesWithSingleClick = prefs.getBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
automaticUpdateCheck = prefs.getBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
displayNewsOnMainScreen = prefs.getBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
showToasts = prefs.getBoolean("showToasts", default_showToasts);
|
||||
|
||||
lockSoundChanges = prefs.getBoolean("lockSoundChanges", default_lockSoundChanges);
|
||||
noticeAndroid9MicrophoneShown = prefs.getBoolean("noticeAndroid9MicrophoneShown", false);
|
||||
@ -472,9 +479,15 @@ public class Settings implements SharedPreferences
|
||||
if(!prefs.contains("displayNewsOnMainScreen") || force)
|
||||
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
|
||||
if(!prefs.contains("showToasts") || force)
|
||||
editor.putBoolean("showToasts", default_showToasts);
|
||||
|
||||
if(!prefs.contains("musicCheckFrequency") || force)
|
||||
editor.putLong("musicCheckFrequency", default_musicCheckFrequency);
|
||||
|
||||
if(!prefs.contains("displayLanguage") || force)
|
||||
editor.putString("displayLanguage", default_displayLanguage);
|
||||
|
||||
if(!prefs.contains("lockSoundChanges") || force)
|
||||
editor.putBoolean("lockSoundChanges", default_lockSoundChanges);
|
||||
|
||||
@ -555,11 +568,14 @@ public class Settings implements SharedPreferences
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
|
||||
editor.putBoolean("automaticUpdateCheck", automaticUpdateCheck);
|
||||
editor.putBoolean("displayNewsOnMainScreen", displayNewsOnMainScreen);
|
||||
editor.putBoolean("showToasts", showToasts);
|
||||
|
||||
if(Settings.musicCheckFrequency == 0)
|
||||
Settings.musicCheckFrequency = Settings.default_musicCheckFrequency;
|
||||
editor.putString("musicCheckFrequency", String.valueOf(musicCheckFrequency));
|
||||
|
||||
editor.putString("displayLanguage", displayLanguage);
|
||||
|
||||
editor.putBoolean("lockSoundChanges", lockSoundChanges);
|
||||
editor.putBoolean("noticeAndroid9MicrophoneShown", noticeAndroid9MicrophoneShown);
|
||||
editor.putBoolean("noticeAndroid10WifiShown", noticeAndroid10WifiShown);
|
||||
|
@ -14,6 +14,7 @@ import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
import com.jens.automation2.receivers.BroadcastListener;
|
||||
import com.jens.automation2.receivers.CalendarReceiver;
|
||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.DeviceOrientationListener;
|
||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
||||
@ -31,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Trigger
|
||||
@ -63,6 +65,7 @@ public class Trigger
|
||||
tethering,
|
||||
subSystemState,
|
||||
checkVariable,
|
||||
calendarEvent,
|
||||
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -123,6 +126,8 @@ public class Trigger
|
||||
return context.getResources().getString(R.string.subSystemState);
|
||||
case checkVariable:
|
||||
return context.getResources().getString(R.string.checkVariable);
|
||||
case calendarEvent:
|
||||
return context.getResources().getString(R.string.calendarEventCapital);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -247,11 +252,14 @@ public class Trigger
|
||||
case subSystemState:
|
||||
if(!checkSubSystemState())
|
||||
result = false;
|
||||
break;
|
||||
case checkVariable:
|
||||
if(!checkVariable())
|
||||
result = false;
|
||||
break;
|
||||
case calendarEvent:
|
||||
if(!checkCalendarEvent())
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -609,6 +617,117 @@ public class Trigger
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean checkCalendarEvent()
|
||||
{
|
||||
try
|
||||
{
|
||||
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
|
||||
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), false);
|
||||
|
||||
/*
|
||||
0 = titleDirection
|
||||
1 = title;
|
||||
2 = descriptionDirection
|
||||
3 = description
|
||||
4 = eventLocationDirection
|
||||
5 = eventLocation
|
||||
6 = all day event
|
||||
7 = availabilityList
|
||||
8 = calendarList
|
||||
*/
|
||||
|
||||
for(CalendarReceiver.CalendarEvent event : calendarEvents)
|
||||
{
|
||||
boolean isActive = getTriggerParameter();
|
||||
if(isActive != event.isCurrentlyActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event has to be currently active: " + String.valueOf(triggerParameter) + ", but is required otherwise.", 5);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[1]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[0], conditions[1], event.title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Title does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[3]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[2], conditions[3], event.description))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Description does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[5]))
|
||||
{
|
||||
if (!Miscellaneous.compare(conditions[4], conditions[5], event.location))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Location does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.parseBoolean(conditions[6]) != event.allDay)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "All day setting does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[7]))
|
||||
{
|
||||
String[] availabilities = conditions[7].split(ActivityManageTriggerCalendar.separator);
|
||||
if (availabilities.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Availability does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(conditions[8]))
|
||||
{
|
||||
String[] calendars = conditions[8].split(ActivityManageTriggerCalendar.separator);
|
||||
if (calendars.length > 0)
|
||||
{
|
||||
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Calendar does not match.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No contradictions found
|
||||
Miscellaneous.logEvent("i", "CalendarCheck", "Event " + event + " matches.", 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
// At this point none of the calendar items matches this trigger
|
||||
|
||||
// If trigger demands no calendar event and there is absolutely no future event, we'll need to check for that.
|
||||
if(calendarEvents.size() == 0)
|
||||
{
|
||||
if(getTriggerParameter() == false)
|
||||
return true;
|
||||
|
||||
// Further criteria don't matter if there are no events to check
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "checkVariable()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean checkBluetooth()
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Checking for bluetooth...", this.getParentRule().getName()), 4);
|
||||
@ -803,13 +922,29 @@ public class Trigger
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name specified, checking that.", this.getParentRule().getName()), 4);
|
||||
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
|
||||
if(WifiBroadcastReceiver.lastConnectedState) //when connected
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()),this.getParentRule().getName()), 3);
|
||||
return false;
|
||||
if (!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), this.getParentRule().getName()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name matches. Rule will apply.", this.getParentRule().getName()), 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name matches. Rule will apply.", this.getParentRule().getName()), 4);
|
||||
{
|
||||
if (
|
||||
!Settings.serviceStartDone
|
||||
||
|
||||
(!WifiBroadcastReceiver.getLastWifiSsidReal().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsidReal().matches(this.getTriggerParameter2()))))
|
||||
{
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsidReal()), this.getParentRule().getName()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name matches. Rule will apply.", this.getParentRule().getName()), 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("No wifi name specified, any will do.", this.getParentRule().getName()), 4);
|
||||
@ -1797,6 +1932,44 @@ public class Trigger
|
||||
else
|
||||
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2));
|
||||
break;
|
||||
case calendarEvent:
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent));
|
||||
|
||||
returnString.append(" (");
|
||||
|
||||
if(triggerParameter)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyHappening));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyNotHappening));
|
||||
|
||||
returnString.append( ", ");
|
||||
|
||||
String[] conditions = triggerParameter2.split(triggerParameter2Split, -1);
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[1]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.title) + " " + conditions[0] + " " + conditions[1] + ", ");
|
||||
if (!StringUtils.isEmpty(conditions[3]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.location) + " " + conditions[2] + " " + conditions[3] + ", ");
|
||||
if (!StringUtils.isEmpty(conditions[5]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", ");
|
||||
|
||||
if(Boolean.parseBoolean(conditions[6]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventTrue) + ", ");
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", ");
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[7]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[7] + ", ");
|
||||
|
||||
if (!StringUtils.isEmpty(conditions[8]))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[8]);
|
||||
|
||||
if (returnString.toString().endsWith(", "))
|
||||
returnString.delete(returnString.length() - 2, returnString.length());
|
||||
|
||||
returnString.append(")");
|
||||
|
||||
break;
|
||||
default:
|
||||
returnString.append("error");
|
||||
break;
|
||||
|
@ -217,7 +217,7 @@ public class XmlFileInterface
|
||||
}
|
||||
serializer.endTag(null, "ProfileCollection");
|
||||
|
||||
|
||||
|
||||
serializer.startTag(null, "RuleCollection");
|
||||
for(int i=0; i<Rule.getRuleCollection().size(); i++)
|
||||
{
|
||||
@ -1286,20 +1286,24 @@ public class XmlFileInterface
|
||||
else
|
||||
newTag = tag.replace("/", Action.intentPairSeparator);
|
||||
|
||||
String[] newTagPieces = newTag.split(";");
|
||||
String[] newTagPieces = new String[0];
|
||||
if(newTag.contains(Action.actionParameter2Split))
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
else
|
||||
newTag.split(";");
|
||||
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeparator)))
|
||||
{
|
||||
newTag = Actions.dummyPackageString + ";" + newTag;
|
||||
newTagPieces = newTag.split(";");
|
||||
newTag = Actions.dummyPackageString + Action.actionParameter2Split + newTag;
|
||||
newTagPieces = newTag.split(Action.actionParameter2Split);
|
||||
}
|
||||
|
||||
if(newTagPieces.length < 3)
|
||||
newTag += ";" + ActivityManageActionStartActivity.startByActivityString;
|
||||
newTag += Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString;
|
||||
else if(newTagPieces.length >= 3)
|
||||
{
|
||||
if(newTagPieces[2].contains(Action.intentPairSeparator))
|
||||
newTag = newTagPieces[0] + ";" + newTagPieces[1] + ";" + ActivityManageActionStartActivity.startByActivityString + ";" + newTagPieces[2];
|
||||
newTag = newTagPieces[0] + Action.actionParameter2Split + newTagPieces[1] + Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString + Action.actionParameter2Split + newTagPieces[2];
|
||||
}
|
||||
|
||||
newAction.setParameter2(newTag);
|
||||
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
|
||||
import com.jens.automation2.ActivityMainScreen;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.BuildConfig;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.PointOfInterest;
|
||||
import com.jens.automation2.R;
|
||||
@ -232,6 +233,7 @@ public class LocationProvider
|
||||
public void startLocationService()
|
||||
{
|
||||
// startPhoneStateListener
|
||||
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||
PhoneStatusListener.startPhoneStatusListener(parentService); // also used to mute anouncements during calls
|
||||
|
||||
// startConnectivityReceiver
|
||||
@ -400,12 +402,12 @@ public class LocationProvider
|
||||
Miscellaneous.logEvent("i", "LocationProvider", this.getParentService().getResources().getString(R.string.applyingSettingsAndRules), 3);
|
||||
|
||||
// *********** SETTING CHANGES ***********
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive())
|
||||
if(Settings.useWifiForPositioning && !WifiBroadcastReceiver.isWifiListenerActive() || Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting WifiReceiver because settings now allow to.", 4);
|
||||
WifiBroadcastReceiver.startWifiReceiver(this);
|
||||
}
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive())
|
||||
else if(!Settings.useWifiForPositioning && WifiBroadcastReceiver.isWifiListenerActive() && !Rule.isAnyRuleUsing(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down WifiReceiver because settings forbid to.", 4);
|
||||
WifiBroadcastReceiver.stopWifiReceiver();
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.jens.automation2.location;
|
||||
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -25,11 +24,19 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
public static LocationProvider parentLocationProvider;
|
||||
public static Boolean wasConnected = false;
|
||||
protected static String lastWifiSsid = "";
|
||||
protected static String lastWifiSsidReal = "";
|
||||
public static boolean lastConnectedState = false;
|
||||
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
|
||||
protected static WifiBroadcastReceiver wifiBrInstance;
|
||||
protected static IntentFilter wifiListenerIntentFilter;
|
||||
protected static boolean wifiListenerActive=false;
|
||||
protected static boolean wifiListenerActive = false;
|
||||
|
||||
final static String unknownSsidName = "<unknown ssid>";
|
||||
|
||||
public static String getLastWifiSsidReal()
|
||||
{
|
||||
return lastWifiSsidReal;
|
||||
}
|
||||
|
||||
public static String getLastWifiSsid()
|
||||
{
|
||||
@ -38,11 +45,18 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
|
||||
public static void setLastWifiSsid(String newWifiSsid)
|
||||
{
|
||||
// Remove double quotes
|
||||
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
|
||||
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
|
||||
|
||||
// If it's a real name, not an empty string, it's stored as the last ssid
|
||||
if(newWifiSsid.length() > 0)
|
||||
{
|
||||
if(newWifiSsid.equals(unknownSsidName))
|
||||
WifiBroadcastReceiver.lastWifiSsidReal = lastWifiSsid;
|
||||
|
||||
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWifiListenerActive()
|
||||
@ -60,24 +74,15 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
// int state = -1;
|
||||
NetworkInfo myWifi = null;
|
||||
|
||||
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) // fired upon disconnection
|
||||
{
|
||||
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
|
||||
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));
|
||||
myWifi = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
|
||||
}
|
||||
|
||||
WifiManager myWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
|
||||
// ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
|
||||
// myWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
// myWifi = state
|
||||
// WifiInfo wifiInfo = myWifiManager.getConnectionInfo();
|
||||
|
||||
// SupplicantState supState = wifiInfo.getSupplicantState();
|
||||
|
||||
|
||||
if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) // fired upon connection
|
||||
{
|
||||
String ssid = myWifiManager.getConnectionInfo().getSSID();
|
||||
@ -120,7 +125,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
}
|
||||
else if(!myWifi.isConnectedOrConnecting()) // really disconnected? because sometimes also fires on connect
|
||||
{
|
||||
if(wasConnected) // wir könnten einfach noch nicht daheim sein
|
||||
if(wasConnected) // we could simply not be home yet
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -214,17 +219,16 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
if(wifiListenerActive)
|
||||
if (wifiListenerActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Wifi Listener", "Stopping wifiListener", 4);
|
||||
wifiListenerActive = false;
|
||||
parentLocationProvider.getParentService().unregisterReceiver(wifiBrInstance);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Wifi Listener", "Error stopping wifiListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -32,21 +32,21 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
if(!batteryReceiverActive)
|
||||
{
|
||||
BatteryReceiver.automationServiceRef = automationServiceRef;
|
||||
|
||||
|
||||
if(batteryInfoReceiverInstance == null)
|
||||
batteryInfoReceiverInstance = new BatteryReceiver();
|
||||
|
||||
|
||||
if(batteryIntentFilter == null)
|
||||
{
|
||||
batteryIntentFilter = new IntentFilter();
|
||||
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
// batteryIntentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
}
|
||||
|
||||
|
||||
batteryStatus = automationServiceRef.registerReceiver(batteryInfoReceiverInstance, batteryIntentFilter);
|
||||
|
||||
|
||||
batteryReceiverActive = true;
|
||||
}
|
||||
}
|
||||
@ -59,16 +59,16 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
automationServiceRef.unregisterReceiver(batteryInfoReceiverInstance);
|
||||
batteryInfoReceiverInstance = null;
|
||||
}
|
||||
|
||||
|
||||
batteryReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isBatteryReceiverActive()
|
||||
{
|
||||
return batteryReceiverActive;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isUsbHostConnected()
|
||||
{
|
||||
return usbHostConnected;
|
||||
@ -80,7 +80,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
}
|
||||
|
||||
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
|
||||
|
||||
|
||||
public static int getCurrentChargingState()
|
||||
{
|
||||
return currentChargingState;
|
||||
@ -90,11 +90,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Received event " + intent.getAction(), 5);
|
||||
|
||||
|
||||
if (intent == null)
|
||||
return;
|
||||
if (context == null)
|
||||
return;
|
||||
return;
|
||||
|
||||
if(intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
|
||||
{
|
||||
@ -105,12 +105,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
try
|
||||
{
|
||||
batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
// int scale = -1;
|
||||
// int voltage = -1;
|
||||
// int temp = -1;
|
||||
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
|
||||
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
|
||||
// int scale = -1;
|
||||
// int voltage = -1;
|
||||
// int temp = -1;
|
||||
// scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
// temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
|
||||
// voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
|
||||
Log.i("Battery", "Level: " + String.valueOf(batteryLevel));
|
||||
this.actionBatteryLevel(context);
|
||||
|
||||
@ -121,7 +121,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
switch(statusPlugged)
|
||||
{
|
||||
case BatteryManager.BATTERY_PLUGGED_AC:
|
||||
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Regular charging", Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Regular charging.", 5);
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
@ -134,10 +134,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
{
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
case BatteryManager.BATTERY_STATUS_FULL:
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
|
||||
this.actionCharging(context);
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
||||
this.actionDischarging(context);
|
||||
break;
|
||||
}
|
||||
@ -148,7 +149,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int isDeviceCharging(Context context)
|
||||
{
|
||||
switch(currentChargingState)
|
||||
@ -163,10 +164,10 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return currentChargingState;
|
||||
}
|
||||
|
||||
|
||||
private void actionCharging(Context context)
|
||||
{
|
||||
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.
|
||||
@ -183,7 +184,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void actionBatteryLevel(Context context)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery level has changed.", 3);
|
||||
@ -195,7 +196,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void actionDischarging(Context context)
|
||||
{
|
||||
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.
|
||||
@ -210,22 +211,22 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
|
||||
this.actionUsbDisconnected(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void actionUsbConnected(Context context)
|
||||
{
|
||||
// Event usbConnected
|
||||
|
||||
|
||||
// Miscellaneous.logEvent("i", "BatteryReceiver", "BATTERY_PLUGGED_USB");
|
||||
|
||||
|
||||
if(!usbHostConnected)
|
||||
{
|
||||
usbHostConnected = true;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
|
||||
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||
@ -234,20 +235,20 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
||||
if(oneRule.getsGreenLight(context))
|
||||
oneRule.activate(automationServiceRef, false);
|
||||
}
|
||||
|
||||
|
||||
this.actionCharging(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void actionUsbDisconnected(Context context)
|
||||
{
|
||||
// Event usbDisConnected
|
||||
|
||||
|
||||
if(usbHostConnected)
|
||||
{
|
||||
usbHostConnected = false;
|
||||
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
|
||||
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
// Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
|
||||
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
||||
|
@ -94,20 +94,21 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event.", 4);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", "Bluetooth event: " + action, 5);
|
||||
|
||||
BluetoothDevice bluetoothDevice = null;
|
||||
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) | action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
{
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED) || action.equals("android.bluetooth.device.action.ACL_CONNECTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
lastAction = action;
|
||||
connectedDevices.add(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothConnectionTo), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) | action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") | action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) || action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECTED") || action.equals("android.bluetooth.device.ACTION_ACL_DISCONNECT_REQUESTED"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
@ -115,7 +116,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
||||
connectedDevices.remove(bluetoothDevice);
|
||||
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDisconnectFrom), bluetoothDevice.getName()), 3);
|
||||
}
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) | action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
else if(action.equals(BluetoothDevice.ACTION_FOUND) || action.equals("android.bluetooth.device.ACTION_FOUND"))
|
||||
{
|
||||
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
lastAffectedDevice = bluetoothDevice;
|
||||
|
@ -52,9 +52,13 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
|
||||
{
|
||||
broadcastsCollection.add(new EventOccurrence(Calendar.getInstance(), intent.getAction()));
|
||||
|
||||
for(String key : intent.getExtras().keySet())
|
||||
Miscellaneous.logEvent("i", "Broadcast received", "Broadcast " + intent.getAction() + " received.", 4);
|
||||
if(intent.getExtras() != null && intent.getExtras().size() > 0)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
for (String key : intent.getExtras().keySet())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
|
||||
|
@ -0,0 +1,412 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class CalendarReceiver extends BroadcastReceiver implements AutomationListenerInterface
|
||||
{
|
||||
static CalendarReceiver calendarReceiverInstance = null;
|
||||
static boolean calendarReceiverActive = false;
|
||||
static IntentFilter calendarIntentFilter = null;
|
||||
private static AutomationService automationServiceRef;
|
||||
private static Intent calendarIntent = null;
|
||||
|
||||
public static final int AVAILABILITY_OUT_OF_OFFICE = 4;
|
||||
public static final int AVAILABILITY_WORKING_ELSEWHERE = 5;
|
||||
public static final String calendarAlarmAction = "ALARM_FOR_CALENDAR";
|
||||
|
||||
static List<AndroidCalendar> calendarsCache = null;
|
||||
static List<CalendarEvent> calendarEventsCache = null;
|
||||
|
||||
static Timer timer = null;
|
||||
static TimerTask timerTask = null;
|
||||
static Calendar nextWakeup = null;
|
||||
static AlarmManager alarmManager = null;
|
||||
static boolean alarmHasChanged = false;
|
||||
|
||||
public static CalendarReceiver getInstance()
|
||||
{
|
||||
if(calendarReceiverInstance == null)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
return calendarReceiverInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "CalendarReceiver", "Received " + intent.getAction(), 5);
|
||||
|
||||
calendarsCache = null;
|
||||
calendarEventsCache = null;
|
||||
|
||||
checkForRules(context);
|
||||
armOrRearmTimer();
|
||||
}
|
||||
else if(intent.getAction().equalsIgnoreCase(calendarAlarmAction))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "AlarmReceiver", "Received alarm for calendar receiver.", 5);
|
||||
routineAtAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkForRules(Context context)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent);
|
||||
for(int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if(ruleCandidates.get(i).getsGreenLight(context))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startListener(AutomationService automationService)
|
||||
{
|
||||
if(!calendarReceiverActive)
|
||||
{
|
||||
if(calendarReceiverInstance == null)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
if(calendarIntentFilter == null)
|
||||
{
|
||||
calendarIntentFilter = new IntentFilter();
|
||||
calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED);
|
||||
// calendarIntentFilter.addDataScheme("content");
|
||||
}
|
||||
|
||||
AutomationService.getInstance().registerReceiver(calendarReceiverInstance, calendarIntentFilter);
|
||||
|
||||
calendarReceiverActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListener(AutomationService automationService)
|
||||
{
|
||||
if(calendarReceiverActive)
|
||||
{
|
||||
if(calendarReceiverInstance != null)
|
||||
{
|
||||
AutomationService.getInstance().unregisterReceiver(calendarReceiverInstance);
|
||||
calendarReceiverInstance = null;
|
||||
}
|
||||
|
||||
calendarReceiverActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerRunning()
|
||||
{
|
||||
return calendarReceiverActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger.Trigger_Enum[] getMonitoredTrigger()
|
||||
{
|
||||
return new Trigger.Trigger_Enum[]{Trigger.Trigger_Enum.calendarEvent};
|
||||
}
|
||||
|
||||
public static class AndroidCalendar
|
||||
{
|
||||
public int calendarId;
|
||||
public String displayName;
|
||||
public String accountString;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return displayName + " (" + accountString + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static class CalendarEvent
|
||||
{
|
||||
public AndroidCalendar calendar;
|
||||
public int calendarId;
|
||||
public String eventId;
|
||||
public String title;
|
||||
public String description;
|
||||
public String location;
|
||||
public String availability;
|
||||
public Calendar start, end;
|
||||
public boolean allDay;
|
||||
|
||||
public boolean isCurrentlyActive()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
return now.getTimeInMillis() >= start.getTimeInMillis() && now.getTimeInMillis() < end.getTimeInMillis();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<AndroidCalendar> readCalendars(Context context)
|
||||
{
|
||||
if(calendarsCache == null)
|
||||
{
|
||||
calendarsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/calendars"),
|
||||
new String[]{ "_id", "calendar_displayName", "ownerAccount", },
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
List<AndroidCalendar> calendarlist = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
AndroidCalendar calendar = new AndroidCalendar();
|
||||
calendar.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
calendar.displayName = cursor.getString(1);
|
||||
calendar.accountString = cursor.getString(2);
|
||||
|
||||
calendarsCache.add(calendar);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
return calendarsCache;
|
||||
}
|
||||
|
||||
public static List<CalendarEvent> readCalendarEvents(Context context, boolean includePastEvents)
|
||||
{
|
||||
if(calendarEventsCache == null)
|
||||
{
|
||||
calendarEventsCache = new ArrayList<>();
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
Uri.parse("content://com.android.calendar/events"),
|
||||
new String[] { "calendar_id", "_id", "title", "description", "allDay", "dtstart", "dtend", "eventLocation", "availability" },
|
||||
null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
// fetching calendars name
|
||||
String CNames[] = new String[cursor.getCount()];
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
for (int i = 0; i < CNames.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalendarEvent event = new CalendarEvent();
|
||||
event.calendarId = Integer.parseInt(cursor.getString(0));
|
||||
|
||||
for(AndroidCalendar cal : readCalendars(context))
|
||||
{
|
||||
if(cal.calendarId == event.calendarId)
|
||||
{
|
||||
event.calendar = cal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.eventId = cursor.getString(1);
|
||||
event.title = cursor.getString(2);
|
||||
event.description = cursor.getString(3);
|
||||
event.allDay = cursor.getString(4).equals("1");
|
||||
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
|
||||
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
|
||||
event.location = cursor.getString(7);
|
||||
event.availability = cursor.getString(8);
|
||||
|
||||
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
|
||||
calendarEventsCache.add(event);
|
||||
}
|
||||
catch (Exception e)
|
||||
{}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
if(cursor != null)
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
return calendarEventsCache;
|
||||
}
|
||||
|
||||
protected static void routineAtAlarm()
|
||||
{
|
||||
checkForRules(Miscellaneous.getAnyContext());
|
||||
|
||||
// Set next timer
|
||||
calculateNextWakeup();
|
||||
armOrRearmTimer();
|
||||
}
|
||||
|
||||
private static void armOrRearmTimer()
|
||||
{
|
||||
PendingIntent pi = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (alarmManager == null)
|
||||
{
|
||||
alarmManager = (AlarmManager) Miscellaneous.getAnyContext().getSystemService(Context.ALARM_SERVICE);
|
||||
|
||||
Intent intent = new Intent(Miscellaneous.getAnyContext(), CalendarReceiver.class);
|
||||
intent.setAction(calendarAlarmAction);
|
||||
pi = PendingIntent.getBroadcast(AutomationService.getInstance(), 0, intent, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timerTask = new TimerTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
routineAtAlarm();
|
||||
}
|
||||
};
|
||||
|
||||
if(timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
timer = new Timer();
|
||||
}
|
||||
|
||||
if(nextWakeup == null)
|
||||
{
|
||||
readCalendarEvents(Miscellaneous.getAnyContext(), false);
|
||||
calculateNextWakeup();
|
||||
}
|
||||
|
||||
// If it's now filled, go on
|
||||
if(nextWakeup != null)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && alarmManager.canScheduleExactAlarms()))
|
||||
{
|
||||
try
|
||||
{
|
||||
alarmManager.cancel(pi);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
Miscellaneous.logEvent("i", "armOrRearmTimer()", "Setting calendar alarm for " + nextWakeup.toString(), 5);
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
|
||||
//alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextWakeup.getTimeInMillis(), pi);
|
||||
}
|
||||
}
|
||||
else
|
||||
timer.schedule(timerTask, nextWakeup.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateNextWakeup()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (nextWakeup != null && nextWakeup.getTimeInMillis() < now.getTimeInMillis())
|
||||
nextWakeup = null;
|
||||
|
||||
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), false);
|
||||
if (events.size() > 0)
|
||||
{
|
||||
for (CalendarEvent event : events)
|
||||
{
|
||||
if (event.isCurrentlyActive())
|
||||
{
|
||||
if (nextWakeup == null || event.end.getTimeInMillis() < nextWakeup.getTimeInMillis())
|
||||
{
|
||||
nextWakeup = event.end;
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Choosing end of event " + event.title + " as next wakeup.", 5);
|
||||
if(!alarmHasChanged)
|
||||
alarmHasChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextWakeup == null || event.start.getTimeInMillis() < nextWakeup.getTimeInMillis())
|
||||
{
|
||||
nextWakeup = event.start;
|
||||
Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Choosing start of event " + event.title + " as next wakeup.", 5);
|
||||
if(!alarmHasChanged)
|
||||
alarmHasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//else
|
||||
// we expect to be called byOnReceive() when new items exist
|
||||
}
|
||||
|
||||
public static void startCalendarReceiver(final AutomationService automationServiceRef)
|
||||
{
|
||||
if (!calendarReceiverActive)
|
||||
{
|
||||
CalendarReceiver.automationServiceRef = automationServiceRef;
|
||||
|
||||
if (calendarReceiverInstance == null)
|
||||
calendarReceiverInstance = new CalendarReceiver();
|
||||
|
||||
if (calendarIntentFilter == null)
|
||||
{
|
||||
calendarIntentFilter = new IntentFilter();
|
||||
calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED);
|
||||
calendarIntentFilter.addDataScheme("content");
|
||||
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
|
||||
}
|
||||
|
||||
calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter);
|
||||
|
||||
calendarReceiverActive = true;
|
||||
|
||||
armOrRearmTimer();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.BuildConfig;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.TimeFrame;
|
||||
@ -28,7 +29,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
||||
{
|
||||
private static AutomationService automationServiceRef;
|
||||
private static AlarmManager centralAlarmManagerInstance;
|
||||
private static boolean alarmListenerActive=false;
|
||||
private static boolean alarmListenerActive = false;
|
||||
private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>();
|
||||
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
|
||||
static PendingIntent alarmPendingIntent = null;
|
||||
@ -243,8 +244,16 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
||||
}
|
||||
|
||||
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
|
||||
if(Miscellaneous.getAnyContext().getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
else
|
||||
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
centralAlarmManagerInstance.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
else
|
||||
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
@ -20,7 +20,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
private static boolean headsetConnected = false;
|
||||
private static int headphoneType = -1;
|
||||
|
||||
protected static boolean headphoneJackListenerActive=false;
|
||||
protected static boolean headphoneJackListenerActive = false;
|
||||
protected static IntentFilter headphoneJackListenerIntentFilter = null;
|
||||
protected static HeadphoneJackListener instance;
|
||||
|
||||
@ -108,7 +108,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
Miscellaneous.logEvent("e", "HeadsetJackListener", "Error starting HeadsetJackListener: " + Log.getStackTraceString(ex), 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,9 @@ package com.jens.automation2.receivers;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
@ -6,10 +6,15 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Build;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
@ -22,6 +27,7 @@ import java.util.ArrayList;
|
||||
|
||||
public class PhoneStatusListener implements AutomationListenerInterface
|
||||
{
|
||||
static int problematicAndroidLevel = 29;
|
||||
protected static String lastPhoneNumber="";
|
||||
protected static int lastPhoneDirection = -1; //0=incoming, 1=outgoing
|
||||
protected static int currentState = -1;
|
||||
@ -70,7 +76,76 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
return currentState;
|
||||
}
|
||||
|
||||
public static class IncomingCallsReceiver extends PhoneStateListener
|
||||
public static interface IncomingCallsReceiver
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected static void workWithIncomingCallData(int state, String incomingNumber)
|
||||
{
|
||||
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
|
||||
{
|
||||
// This status update is actually for an outgoing call
|
||||
setCurrentState(state);
|
||||
|
||||
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setCurrentState(state);
|
||||
setLastPhoneDirection(1);
|
||||
|
||||
if (incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), incomingNumber), 4);
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if (asInstance != null)
|
||||
if (ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IncomingCallsReceiverOld extends PhoneStateListener implements IncomingCallsReceiver
|
||||
{
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber)
|
||||
@ -86,65 +161,42 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
If the last call was outgoing the state has not changed to idle this is kind of a fake alert.
|
||||
*/
|
||||
|
||||
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
|
||||
workWithIncomingCallData(state, incomingNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public static class IncomingCallsReceiverNew extends BroadcastReceiver implements IncomingCallsReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
/*
|
||||
this code detects both incoming and outgoing,
|
||||
if the state changes idle => ringing you know it's an incoming call,
|
||||
if the state changes idle => offhook, you know it's an outgoing call
|
||||
*/
|
||||
|
||||
if (!intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL))
|
||||
{
|
||||
// This status update is actually for an outgoing call
|
||||
setCurrentState(state);
|
||||
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
|
||||
int state = 99;
|
||||
|
||||
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
|
||||
switch(state)
|
||||
switch(stateStr)
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
case "RINGING":
|
||||
state = TelephonyManager.CALL_STATE_RINGING;
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
case "IDLE":
|
||||
state = TelephonyManager.CALL_STATE_IDLE;
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
|
||||
case "OFFHOOK":
|
||||
state = TelephonyManager.CALL_STATE_OFFHOOK;
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for(int i=0; i<ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if(asInstance != null)
|
||||
if(ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setCurrentState(state);
|
||||
setLastPhoneDirection(1);
|
||||
|
||||
if (incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
|
||||
setLastPhoneNumber(incomingNumber);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), incomingNumber), 4);
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
AutomationService asInstance = AutomationService.getInstance();
|
||||
if (asInstance != null)
|
||||
if (ruleCandidates.get(i).getsGreenLight(asInstance))
|
||||
ruleCandidates.get(i).activate(asInstance, false);
|
||||
}
|
||||
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
|
||||
Log.i("test", "test");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -201,7 +253,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
}
|
||||
|
||||
if(incomingCallsReceiverInstance == null)
|
||||
incomingCallsReceiverInstance = new IncomingCallsReceiver();
|
||||
{
|
||||
// if(Build.VERSION.SDK_INT >= 31)
|
||||
// incomingCallsReceiverInstance = new IncomingCallsReceiverNew();
|
||||
// else
|
||||
incomingCallsReceiverInstance = new IncomingCallsReceiverOld();
|
||||
}
|
||||
|
||||
if(outgoingCallsReceiverInstance == null)
|
||||
outgoingCallsReceiverInstance = new OutgoingCallsReceiver();
|
||||
@ -211,8 +268,17 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
if(!incomingCallsReceiverActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->incomingCallsReceiver", 4);
|
||||
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
// if(Build.VERSION.SDK_INT >= problematicAndroidLevel)
|
||||
// {
|
||||
// IntentFilter callsFilter = new IntentFilter();
|
||||
// callsFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
||||
// automationService.registerReceiver((IncomingCallsReceiverNew)incomingCallsReceiverInstance, callsFilter);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
TelephonyManager tm = (TelephonyManager) automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
// }
|
||||
incomingCallsReceiverActive = true;
|
||||
}
|
||||
|
||||
@ -236,8 +302,15 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
||||
if(incomingCallsReceiverActive)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "PhoneStatusListener", "Stopping phoneStatusListener", 4);
|
||||
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
|
||||
// if(Build.VERSION.SDK_INT >= 31)
|
||||
// {
|
||||
// automationService.unregisterReceiver((IncomingCallsReceiverNew)incomingCallsReceiverInstance);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
TelephonyManager tm = (TelephonyManager) automationService.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
tm.listen((IncomingCallsReceiverOld)incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
|
||||
// }
|
||||
incomingCallsReceiverActive = false;
|
||||
}
|
||||
|
||||
|
@ -11,12 +11,13 @@ import com.jens.automation2.Settings;
|
||||
|
||||
public class StartupIntentReceiver extends BroadcastReceiver
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Settings.readFromPersistentStorage(context);
|
||||
|
||||
Miscellaneous.startupContext = context;
|
||||
|
||||
// Miscellaneous.logEvent("i", "Boot event", "Received event: " + intent.getAction(), 5);
|
||||
|
||||
if(Settings.startServiceAtSystemBoot)
|
||||
|
BIN
app/src/main/res/drawable-hdpi/calendar.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable-hdpi/clipboard.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-hdpi/copier.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-hdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable-hdpi/variable.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable-ldpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-mdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-v24/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-xhdpi/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 3.7 KiB |
BIN
app/src/main/res/drawable/crane.png
Normal file
After Width: | Height: | Size: 13 KiB |
@ -37,6 +37,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/generalText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/textToCopy" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCopyToClipboard"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="textShortMessage|textMultiLine" >
|
||||
</EditText>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTextMessageAnnotations"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:text="@string/textMessageAnnotations" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLegend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/urlLegend" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveCopyToClipboard"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_span="2"
|
||||
android:textSize="25dp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/actionSetLocationService"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiExplanation1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/wifiExplanation1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiExplanation2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/wifiExplanation2" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:stretchColumns="1"
|
||||
android:shrinkColumns="1" >
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="@dimen/default_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:text="@string/state" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceOff"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/off" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceSensorsOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_SENSOR_ONLY" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceBatterySaving"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_BATTERY_SAVING" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbActionLocationServiceHighAccuracy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/LOCATION_MODE_HIGH_ACCURACY" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bActionSetLocationServiceSave"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -113,6 +113,7 @@
|
||||
android:text="@string/startAppStartType" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/rgAppStartupType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@ -135,6 +136,12 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/startAppByStartService" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbStartAppByForegroundService"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/startAppByStartForegroundService" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</TableRow>
|
||||
@ -187,6 +194,25 @@
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/className" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etClassName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
@ -304,6 +330,24 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addIntentValue" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:text="@string/intentParametersHint" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="25dp"
|
||||
android:text="@string/variablesOnlyForTypes" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLegend"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/urlLegend" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
|
@ -90,6 +90,34 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/method"
|
||||
android:layout_marginTop="@dimen/fab_margin"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbTriggerUrlMethodGet"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/methodGet" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbTriggerUrlMethodPost"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:text="@string/methodPost" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvTriggerUrlPostParameters"
|
||||
android:layout_width="match_parent"
|
||||
@ -109,6 +137,12 @@
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:text="@string/triggerUrlVariableHint" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveSpeakText"
|
||||
android:layout_marginTop="15dp"
|
||||
|
323
app/src/main/res/layout/activity_manage_trigger_calendar.xml
Normal file
@ -0,0 +1,323 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarEventCapital"
|
||||
android:textSize="25dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectingNoneItemForAllToMatch"/>
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:shrinkColumns="1"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/direction"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarEventActive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/eventIsCurrentlyHappening"
|
||||
android:checked="true"/>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/comparisonCaseInsensitive"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/regularExpressionsIfEquals"
|
||||
android:layout_marginBottom="@dimen/default_margin"/>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/title" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarTitleDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/location" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarLocationDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarLocation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/calendarDescription" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCalendarDescriptionDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCalendarDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/allDayEvent" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAllDayEvent"
|
||||
android:checked="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/selectingNoneItemForAllToMatch" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/availability" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityBusy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringBusy" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityFree"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringFree" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityTentative"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringTentative" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityOutOfOffice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringOutOfOffice" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkCalendarAvailabilityWorkingElsewhere"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/calendarStringWorkingElsewhere" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/calendarAvailabilityTypesUnsupported" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/selectingNoneItemForAllToMatch" />
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/calendars" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llCalendarSelection"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMissingCalendarHint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerCalendar"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -103,6 +103,14 @@
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWifiTriggerDisconnectionHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:textColor="@color/red"
|
||||
android:text="@string/wifiTriggerDisconnectionHint" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bTriggerWifiSave"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
|
@ -59,6 +59,13 @@
|
||||
android:entries="@array/tabsPlacementOptions"
|
||||
android:entryValues="@array/tabsPlacementOptionsValues" />
|
||||
|
||||
<ListPreference
|
||||
android:key="displayLanguage"
|
||||
android:title="@string/displayLanguage"
|
||||
android:summary="@string/displayLanguageSummary"
|
||||
android:entries="@array/displayLanguageOptions"
|
||||
android:entryValues="@array/displayLanguageValues" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="executeRulesAndProfilesWithSingleClick"
|
||||
android:title="@string/executeRulesAndProfilesWithSingleClickTitle" />
|
||||
@ -74,7 +81,12 @@
|
||||
android:title="@string/displayNewsOnMainScreen"
|
||||
android:summary="@string/displayNewsOnMainScreenDescription" />
|
||||
|
||||
</PreferenceCategory>
|
||||
<CheckBoxPreference
|
||||
android:key="showToasts"
|
||||
android:title="@string/showToastsForEvents"
|
||||
android:summary="@string/showToastsForEventsSummary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:summary="@string/soundSettings"
|
||||
|
@ -66,6 +66,12 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRestrictionPermissionsNotice"
|
||||
android:textColor="@color/red"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -1,5 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="languageSystemDefault">System Standard</string>
|
||||
<string name="languageEnglish">Englisch</string>
|
||||
<string name="languageGerman">Deutsch</string>
|
||||
<string name="languageItalian">Italienisch</string>
|
||||
<string name="languageSpanish">Spanisch</string>
|
||||
<string name="languageDutch">Niederländisch</string>
|
||||
<string name="languageRussian">Russisch</string>
|
||||
<string name="languageFrench">Französisch</string>
|
||||
<string name="ruleActivate">Aktiviere Regel %1$s</string>
|
||||
<string name="profileActivate">Aktiviere Profil %1$s</string>
|
||||
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umkehrmodus</string>
|
||||
@ -57,7 +65,7 @@
|
||||
<string name="end">Ende</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="urlToTrigger">URL, die ausgelöst werden soll:</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (< Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung</string>
|
||||
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (< Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[LAST_TRIGGERURL_RESULT] - Das Ergebnis der letzten Ausführung der triggerUrl-Aktion\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
|
||||
<string name="wifi">WLAN</string>
|
||||
<string name="activating">Aktiviere</string>
|
||||
<string name="deactivating">Deaktiviere</string>
|
||||
@ -112,7 +120,7 @@
|
||||
<string name="soundSettings">Ton Einstellungen</string>
|
||||
<string name="showHelp">Hilfe</string>
|
||||
<string name="rules">Regeln</string>
|
||||
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.</string>
|
||||
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.\nDie Begriffe Auslöser und Bedingung werden synonym verwendet. Alle von ihnen sind Bedingungen, aber die letzte, die ihren erforderlichen Wert erfüllt, könnte als Auslöser bezeichnet werden, da sie das letzte Teil des Puzzles ist, um eine Regel auszuführen.</string>
|
||||
<string name="timeframes">Zeiträume</string>
|
||||
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
|
||||
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
|
||||
@ -594,7 +602,7 @@
|
||||
<string name="tabsPlacement">Position der Tableiste</string>
|
||||
<string name="top">Oben</string>
|
||||
<string name="bottom">Unten</string>
|
||||
<string name="tabsPlacementSummary">Wol soll die Taskleiste angezeigt werden?</string>
|
||||
<string name="tabsPlacementSummary">Wo soll die Taskleiste angezeigt werden?</string>
|
||||
<string name="tones">Klingeltöne</string>
|
||||
<string name="miscellaneous">Verschiedenes</string>
|
||||
<string name="dnd">Nicht stören</string>
|
||||
@ -722,7 +730,7 @@
|
||||
<string name="enterBroadcast">Geben Sie eine Aktion für den Broadcast ein.</string>
|
||||
<string name="broadcastExplanation">Diese Aktion erlaubt es, einen Broadcast über das Nachrichtensystem von Android zu verschicken. Das ist für den Benutzer nicht sichtbar, aber Anwendungen, die sich für bestimmte Broadcasts registriert haben, können darauf reagieren.</string>
|
||||
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
|
||||
<string name="logsExplanation">Um eine unnötige Abnutzung Ihres Speichers zu vermeiden, werden Protokolle standardmäßig nicht gespeichert. Wenn Sie also ein Problem haben, aktivieren Sie bitte zuerst die Anmeldeeinstellungen und setzen Sie den Protokollpegel auf 5. Reproduzieren Sie dann das Problem. Erst dann können Protokolle angehängt werden.</string>
|
||||
<string name="logsExplanation">Um eine unnötige Abnutzung Ihres Speichers zu vermeiden, werden Protokolle standardmäßig nicht gespeichert. Wenn Sie also ein Problem haben, aktivieren Sie bitte zuerst die Protokollierungseinstellungen und setzen Sie den Protokollpegel auf 5. Reproduzieren Sie dann das Problem. Erst dann können Protokolle angehängt werden.</string>
|
||||
<string name="directionStringDoesNotContain">enthält nicht</string>
|
||||
<string name="path">Pfad</string>
|
||||
<string name="runExecutable">Programm/Script ausführen</string>
|
||||
@ -771,4 +779,38 @@
|
||||
<string name="checkVariableExplanation">Wenn Sie den Wert der Variablen leer lassen, darf sie nicht gesetzt sein, damit die Bedingung als erfüllt gilt.</string>
|
||||
<string name="variableCheckString">wenn Variable %1$s den Wert %2$s hat</string>
|
||||
<string name="variableCheckStringDeleted">wenn Variable %1$s nicht gesetzt ist</string>
|
||||
<string name="messageType">Nachrichtentyp</string>
|
||||
<string name="sms">SMS</string>
|
||||
<string name="mms">MMS</string>
|
||||
<string name="attachment">Dateianhang</string>
|
||||
<string name="chooseFile">Datei wählen</string>
|
||||
<string name="startAppByStartService">via startService()</string>
|
||||
<string name="showToastsForEvents">Toasts anzeigen</string>
|
||||
<string name="showToastsForEventsSummary">Popups anzeigen, wenn Ereignisse wie Regelausführungen auftreten</string>
|
||||
<string name="notificationAccessAndroid13">Nachdem Sie auf OK geklickt haben, wählen Sie Automatisierung, dann \"Benachrichtigungszugriff zulassen\", dann \"Zulassen\".\n\nAuf einigen Systemen ist diese Einstellung ausgegraut. In diesen Fällen müssen Sie zu \"settings\" -> \"apps\" -> \"Automation\" -> 3-Punkte-Menü -> Gehen Sie diese Einschränkungen auf. Danach kehren Sie hierher zurück.</string>
|
||||
<string name="displayLanguage">Anzeigesprache</string>
|
||||
<string name="displayLanguageSummary">Bestimmte Anzeigesprache wählen</string>
|
||||
<string name="wifiMonitoringAlsoRequiresThis">Diese Berechtigung wird auch benötigt, wenn man die aktuelle WLAN Verbindung auslesen möchte.</string>
|
||||
<string name="copyTextToClipboard">Text in die Zwischenablage kopieren</string>
|
||||
<string name="textToCopy">Text, der kopiert werden soll</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Über anderen Anwendungen anzeigen</string>
|
||||
<string name="overlayPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automation aus und erlauben Sie die Anzeige über anderen Apps.</string>
|
||||
<string name="variablesOnlyForTypes">Variablen sind nur für die Parametertypen String und URI verfügbar</string>
|
||||
<string name="intentParametersHint">Wenn Sie einen Parameter angeben möchten, müssen Sie auch auf \"Intent-Paar hinzufügen\" klicken. Andernfalls werden Ihre Änderungen nicht gespeichert.</string>
|
||||
<string name="languagePolish">Polnisch</string>
|
||||
<string name="languageChineseChina">Chinesisch (China)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Dieser Auslöser ist gültig, wenn Sie gerade die Verbindung zu dem oben angegebenen WLAN getrennt haben ODER während der Dienst noch gestartet wird und wenn Sie mit keinem WLAN verbunden sind. Wenn Sie möchten, dass der Auslöser nur ausgelöst wird, wenn Sie die Verbindung zu einem bestimmten WLAN explizit trennen, fügen Sie einen weiteren Auslöser hinzu: \"Der Dienst wird nicht gestartet\".</string>
|
||||
<string name="className">Klassenname</string>
|
||||
<string name="startAppByStartForegroundService">per startForegroundService()</string>
|
||||
<string name="method">Methode</string>
|
||||
<string name="takeScreenshot">Screenshot erstellen</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">An den Barrierefreiheitsdienst anbinden</string>
|
||||
<string name="bindAccessibilityService">An den Barrierefreiheitsdienst anbinden</string>
|
||||
<string name="accessibilityApiPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automatisierung aus und erlauben Sie die Barrierefreiheits-API.</string>
|
||||
<string name="accessibility_service_explanation">Erforderlich für bestimmte Aktionen.</string>
|
||||
<string name="noticeRestrictedPermissions">Wenn Sie eine der folgenden Berechtigungen nicht erteilen und eine Systemmeldung wie \"Eingeschränkte Berechtigung\" erhalten, müssen Sie zuerst zu den Android-Einstellungen und dann zu den Anwendungen gehen und Automatisierung auswählen. Nun sollten sich 3 Punkte in der oberen rechten Ecke befinden. Klicken Sie auf \"Eingeschränkte Einstellungen zulassen\". Danach sollte die erforderliche Erlaubnis erteilt werden können. Dies sollte nur für die APK-Version der App gelten, nicht für die von F-Droid oder dem Play Store.</string>
|
||||
<string name="setLocationService">Ortungsdienst festlegen</string>
|
||||
<string name="writeSecureSettingsNotice">Leider kann die Erlaubnis WRITE_SECURE_SETTINGS nicht direkt auf Ihrem Android-Gerät erteilt werden. Stattdessen müssen Sie Ihr Gerät an einen Computer anschließen und die Berechtigung über ADB erteilen. Klicken Sie hier, um zu erfahren, wie Sie es gewähren können: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Ortungsdienst</string>
|
||||
<string name="triggerUrlVariableHint">Das Ergebnis dieser Anfrage wird in der Variablen LAST_TRIGGERURL_RESULT gespeichert, wenn Sie es von einer anderen Regel aus überprüfen möchten. Im Falle von HTTP-Fehlern wie 404 ist der Wert \"HTTP_ERROR\".</string>
|
||||
</resources>
|
@ -1,5 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="languageSystemDefault">Predeterminado</string>
|
||||
<string name="languageEnglish">Inglés</string>
|
||||
<string name="languageGerman">Alemán</string>
|
||||
<string name="languageItalian">Italiano</string>
|
||||
<string name="languageSpanish">Español</string>
|
||||
<string name="languageDutch">Holandés</string>
|
||||
<string name="languageRussian">Ruso</string>
|
||||
<string name="languageFrench">Francés</string>
|
||||
<string name="ruleActivate">Estoy activando regla %1$s</string>
|
||||
<string name="profileActivate">Estoy activando perfil %1$s</string>
|
||||
<string name="ruleActivateToggle">Estoy activando regla %1$s en el modo de invertir</string>
|
||||
@ -35,7 +43,7 @@
|
||||
<string name="enterAname">Inserte un nombre.</string>
|
||||
<string name="username">Nombre de usuario</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="continueText">continuar</string>
|
||||
<string name="continueText">Continuar</string>
|
||||
<string name="rule">Regla</string>
|
||||
<string name="android.permission.SEND_SMS">Enviar mensajes SMS</string>
|
||||
<string name="android.permission.READ_CONTACTS">Leer directorio</string>
|
||||
@ -189,7 +197,7 @@
|
||||
<string name="android.permission.RECORD_AUDIO">Grabar audio</string>
|
||||
<string name="android.permission.PROCESS_OUTGOING_CALLS">Detectar llamadas salientes</string>
|
||||
<string name="android.permission.READ_PHONE_STATE">Detectar el estado del dispositivo</string>
|
||||
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer la almacenamiento</string>
|
||||
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer el almacenamiento</string>
|
||||
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Escribir en el almacenamiento</string>
|
||||
<string name="android.permission.WRITE_SETTINGS">Modificar la configuración del dispositivo</string>
|
||||
<string name="android.permission.BATTERY_STATS">Determinar el estado de la bateria</string>
|
||||
@ -359,14 +367,14 @@
|
||||
<string name="networkAccuracy">Red exactitud [m]</string>
|
||||
<string name="minimumTimeForLocationUpdates">Tiempo mínimo para cambio en milisegundos para actualizar posición</string>
|
||||
<string name="timeForUpdate">Tiempo para actualizar [milisegundos]</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (< Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación</string>
|
||||
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (< Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[LAST_TRIGGERURL_RESULT] - El resultado de la última ejecución de la acción triggerUrl\n[variable-VARIABLENAME] - El valor de la variable definida personalizada</string>
|
||||
<string name="screenRotationAlreadyEnabled">Rotación del monitor todavia esta activado.</string>
|
||||
<string name="screenRotationAlreadyDisabled">Rotación del monitor todavia esta desactivado.</string>
|
||||
<string name="needLocationPermForWifiList">Se puede usar la lista de wifis conocidos para determinar los sitios en los cuales estuvo. Por eso el permiso de localización es necesario para cargar la lista de wifis. Si quiere elegir uno de la lista tiene que conceder el permiso. En caso contrario todavia puede introducir un nombre wifi manualmente.</string>
|
||||
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlar conexiones de la app Wireguard</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Adjuntar configuración y procotolo.</string>
|
||||
<string name="rootExplanation">Necesita permiso root para esta función. Después encienda la función \"ejecutar regla manualmente\" para presentar el permiso superuser dialogo. Es necesario elegir \"siempre permitir root para esta app\". En caso contrario la regla no puede funcionar en segundo plano.</string>
|
||||
<string name="helpTextRules">Todas las condiciones están \"Y\"-conectadas. La regla solo va a aplicarse cuando todas las condiciones se aplican. Si quiere \"O\", cree otra regla.</string>
|
||||
<string name="helpTextRules">Todas las condiciones están \"Y\"-conectadas. La regla solo va a aplicarse cuando todas las condiciones se aplican. Si quiere \"O\", cree otra regla.\nLos términos desencadenante y condición se utilizan como sinónimos. Todas ellas son condiciones, pero la última en cumplir con su valor requerido podría llamarse disparador porque es la pieza final del rompecabezas para hacer que se ejecute una regla.</string>
|
||||
<string name="timeBetweenNoiseLevelMeasurementsSummary">Segundos entre dos ensayos de nivel de ruido</string>
|
||||
<string name="timeBetweenNoiseLevelMeasurementsTitle">Segundos entre dos ensayos de nivel de ruido</string>
|
||||
<string name="lengthOfNoiseLevelMeasurementsSummary">Duración en segundos para una prueba de nivel de ruido</string>
|
||||
@ -757,7 +765,7 @@
|
||||
<string name="startPhoneCall">Llamar al número de teléfono</string>
|
||||
<string name="android.permission.CALL_PHONE">Llamar al número de teléfono</string>
|
||||
<string name="makePhoneCallExplanation1">Aquí puede ingresar un número de teléfono al que se llamará sin más indicaciones. Puede usar esto para realizar configuraciones como realizar ajustes en el enrutamiento de llamadas, etc. Por favor, busque los códigos necesarios para esto por su cuenta.</string>
|
||||
<string name="endPhoneCall">Terminar llamda de teléfono</string>
|
||||
<string name="endPhoneCall">Terminar llamada de teléfono</string>
|
||||
<string name="android.permission.ANSWER_PHONE_CALLS">Terminar llamda de teléfono</string>
|
||||
<string name="settingsReferringToRestrictedFeaturesInGoogle">La configuración y/o las reglas hacen referencia a funciones que no se pueden proporcionar en la versión de Google Play. Entre otras cosas que incluye todo lo relacionado con llamadas telefónicas y mensajes de texto.</string>
|
||||
<string name="variableCheckStringDeleted">Si la variable %1$s no está establecida</string>
|
||||
@ -770,4 +778,38 @@
|
||||
<string name="VariableKey">Clave variable</string>
|
||||
<string name="deleteVariable">Eliminar variable</string>
|
||||
<string name="setVariable">Establecer una variable</string>
|
||||
<string name="messageType">Tipo de mensaje</string>
|
||||
<string name="sms">SMS</string>
|
||||
<string name="mms">MMS</string>
|
||||
<string name="attachment">Archivo adjunto</string>
|
||||
<string name="chooseFile">elegir archivo</string>
|
||||
<string name="startAppByStartService">via startService()</string>
|
||||
<string name="showToastsForEvents">Mostrar toasts</string>
|
||||
<string name="showToastsForEventsSummary">Mostrar notificaciones del sistema cuando se producen eventos como ejecuciones de reglas</string>
|
||||
<string name="notificationAccessAndroid13">Después de cliquear en Aceptar, seleccione Automatización y, a continuación, seleccione \"Permitir acceso a notificaciones\", luego \"permitir\".\n\nEn algunos sistemas, esta configuración está atenuada. En esos casos, debe ir a \"configuración\" -> \"aplicaciones\" -> \"Automatización\" -> menú de 3 puntos -> Levante estas restricciones. Luego regreso aquí.</string>
|
||||
<string name="displayLanguage">Idioma de visualización</string>
|
||||
<string name="displayLanguageSummary">Establecer un idioma personalizado para la aplicación</string>
|
||||
<string name="wifiMonitoringAlsoRequiresThis">Este permiso también es necesario si el disparador está utilizando la conexión wifi actual.</string>
|
||||
<string name="copyTextToClipboard">Copiar texto al portapapeles</string>
|
||||
<string name="textToCopy">Texto para copiar</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Dibujar encima otras aplicaciones</string>
|
||||
<string name="overlayPermissionHint">Después de hacer cliquear en Aceptar, se le enviará a un cuadro de diálogo del sistema. Seleccione Automation allí y permita dibujar encima otras aplicaciones.</string>
|
||||
<string name="variablesOnlyForTypes">Las variables solo están disponibles para los tipos de parámetro String y URI</string>
|
||||
<string name="intentParametersHint">Si desea especificar un parámetro, también debe hacer clic en \"Agregar par de intención\". De lo contrario, los cambios no se guardarán.</string>
|
||||
<string name="languagePolish">Polaco</string>
|
||||
<string name="languageChineseChina">Chino (China)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Este activador será válido si acabas de desconectarte del wifi especificado anteriormente O mientras el servicio aún se está iniciando y si no estás conectado a ningún wifi. Si desea que el activador se active solo cuando se desconecte explícitamente de una determinada red WiFi, agregue otro activador \"el servicio no se está iniciando\".</string>
|
||||
<string name="className">Nombre de la clase</string>
|
||||
<string name="startAppByStartForegroundService">a través de startForegroundService((</string>
|
||||
<string name="method">Método</string>
|
||||
<string name="takeScreenshot">Tomar captura de pantalla</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Enlazar al servicio de accesibilidad</string>
|
||||
<string name="bindAccessibilityService">Enlazar al servicio de accesibilidad</string>
|
||||
<string name="accessibilityApiPermissionHint">Después de hacer clic en Aceptar, se le enviará a un cuadro de diálogo del sistema. Seleccione Automatización allí y permita Permitir API de accesibilidad.</string>
|
||||
<string name="accessibility_service_explanation">Requerido para ciertas acciones.</string>
|
||||
<string name="noticeRestrictedPermissions">Si no le otorga a uno el siguiente permiso y un mensaje del sistema como \"Ajuste restringido\", primero debe ir a la configuración de Android, luego a las aplicaciones, elija Automatización. Ahora debería haber 3 puntos en la esquina superior derecha. Haga clic en \"Permitir configuraciones restringidas\". Después de eso, el permiso necesario debería poder otorgarse. Esto solo debería aplicarse a la versión APK de la aplicación, no a las de F-Droid o Play Store.</string>
|
||||
<string name="setLocationService">Encender/desactivar el servicio de ubicación</string>
|
||||
<string name="writeSecureSettingsNotice">Desafortunadamente, el permiso WRITE_SECURE_SETTINGS no se puede otorgar directamente en su dispositivo Android. En su lugar, debe conectar su dispositivo a una computadora y otorgar el permiso a través de ADB. Haga clic aquí para saber cómo otorgarlo: https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Servicio de localización</string>
|
||||
<string name="triggerUrlVariableHint">El resultado de esta solicitud se almacenará en la variable LAST_TRIGGERURL_RESULT si desea verificarlo desde otra regla. En caso de errores HTTP como 404, el valor será \"HTTP_ERROR\".</string>
|
||||
</resources>
|
@ -1,5 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="languageSystemDefault">Valeur par défaut du système</string>
|
||||
<string name="languageEnglish">Anglais</string>
|
||||
<string name="languageGerman">Allemand</string>
|
||||
<string name="languageItalian">Italien</string>
|
||||
<string name="languageSpanish">Espagnol</string>
|
||||
<string name="languageDutch">Néerlandais</string>
|
||||
<string name="languageRussian">Russe</string>
|
||||
<string name="languageFrench">Français</string>
|
||||
<string name="ruleActivate">Activation de la règle %1$s</string>
|
||||
<string name="profileActivate">Activation du profil %1$s</string>
|
||||
<string name="ruleActivateToggle">Activation de la règle %1$s en mode alternatif</string>
|
||||
@ -57,7 +65,7 @@
|
||||
<string name="end">Arrêt</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="urlToTrigger">URL à déclencher :</string>
|
||||
<string name="urlLegend">Variables :\nVous pouvez utiliser les variables suivantes. Lors du déclenchement, elles seront remplacées par les variables correspondantes sur votre appareil. Insérez les parenthèses dans votre texte.\n\n[uniqueid] - Identifiant unique de votre appareil\n[serialnr] - Numéro de série de votre appareil (< Android 9)\n[latitude] - Latitude de votre appraeil\n[longitude] - Longitude de votre appraeil\n[phonenr] - Numéro des derniers appels entrants ou sortants\n[d] - Jour du mois, @ chiffres commençant par 0\n[m] - Valeur numérique du mois, avec @ chiffres\n[Y] - Valeur numérique de l’année, $ chiffres\n[h] - Format horaire 12 heures, 2 chiffres\n[H] - Format horaire 24 heures, 2 chiffres\n[i] - Nombre de minutes, 2 chiffres\n[s] - Nombre de secondes, 2 chiffres\n[ms] - Nombre de millisecondes\n[notificationTitle] - titre de la dernière notification\n[notificationText] - texte de la dernière notification</string>
|
||||
<string name="urlLegend">Variables :\nVous pouvez utiliser les variables suivantes. Lors du déclenchement, elles seront remplacées par les variables correspondantes sur votre appareil. Insérez les parenthèses dans votre texte.\n\n[uniqueid] - Identifiant unique de votre appareil\n[serialnr] - Numéro de série de votre appareil (< Android 9)\n[latitude] - Latitude de votre appraeil\n[longitude] - Longitude de votre appraeil\n[phonenr] - Numéro des derniers appels entrants ou sortants\n[d] - Jour du mois, @ chiffres commençant par 0\n[m] - Valeur numérique du mois, avec @ chiffres\n[Y] - Valeur numérique de l’année, $ chiffres\n[h] - Format horaire 12 heures, 2 chiffres\n[H] - Format horaire 24 heures, 2 chiffres\n[i] - Nombre de minutes, 2 chiffres\n[s] - Nombre de secondes, 2 chiffres\n[ms] - Nombre de millisecondes\n[notificationTitle] - titre de la dernière notification\n[notificationText] - texte de la dernière notification\n[variable-VARIABLENAME] - Valeur de votre variable définie personnalisée</string>
|
||||
<string name="wifi">wifi</string>
|
||||
<string name="activating">Allumer</string>
|
||||
<string name="deactivating">Éteindre</string>
|
||||
@ -112,7 +120,7 @@
|
||||
<string name="soundSettings">Réglages audio</string>
|
||||
<string name="showHelp">Afficher l’aide</string>
|
||||
<string name="rules">Règles</string>
|
||||
<string name="helpTextRules">Tous les déclencheurs d’une règle sont reliés par un lien logique ET, la règle ne s’applique que si tous les déclencheurs sont satisfaits. Pour un lien logique OU, créez une autre règle.</string>
|
||||
<string name="helpTextRules">Tous les déclencheurs d’une règle sont reliés par un lien logique ET, la règle ne s’applique que si tous les déclencheurs sont satisfaits. Pour un lien logique OU, créez une autre règle.\nLes termes déclencheur et condition sont utilisés comme synonymes. Toutes sont des conditions, mais la dernière à atteindre sa valeur requise pourrait être appelée déclencheur car c\'est la dernière pièce du puzzle pour provoquer l\'exécution d\'une règle.</string>
|
||||
<string name="timeframes">Délais d’éxécution</string>
|
||||
<string name="helpTextTimeFrame">Si vous créez une règle avec une période d’éxécution vous avez deux options. Vous pouvez choisir d’éxécuter dans la période OU hors de la période. Quel que soit votre choix l’action ne sera déclenchée qu’une seule fois. Si vous créez une règle avec pour déclencheur \« dans la période xyz \» qui modifie votre profil audio en le passant en mode vibreur cela ne signifie pas que votre téléphone repassera automatiquement en mode sonnerie à la fin de la période. Si vous souhaitez le faire vous devez définir une autre règle avec une autre période.</string>
|
||||
<string name="helpTextSound">Sur l’écran principal vous pouvez utiliser le verrouillage des modifications audio pour temporairement ne pas utiliser les règles de changement des paramètres audio. Par exemple vous pouvez êtes dans un lieu où à un moment où les sonneries peuvent être dérangeantes. Cette fonctionnalité se désactivera automatiquement une fois le temps configuré écoulé. Appuyez sur le bouton + 15 min pour ajouter la durée souhaitée. Une fois activé vous pouvez le désactiver en appuyant sur le bouton \« OUI \» (la règle de gestion des paramètres audio sera de nouveau active).</string>
|
||||
@ -274,6 +282,7 @@
|
||||
<string name="with">avec</string>
|
||||
<string name="phoneNumber">Numéro de téléphone</string>
|
||||
<string name="enterPhoneNumberBlankForAny">Saisissez un numéro de téléphone. Laissez vide pour n’importe quel numéro.</string>
|
||||
<string name="enterPhoneNumber">Entrez le numéro de téléphone.</string>
|
||||
<string name="phoneDirection">Sélectionnez le type \nd’appel</string>
|
||||
<string name="any">tout</string>
|
||||
<string name="incoming">entrant</string>
|
||||
@ -769,4 +778,38 @@
|
||||
<string name="VariableKey">Clé variable</string>
|
||||
<string name="deleteVariable">Supprimer la variable</string>
|
||||
<string name="setVariable">Définir une variable</string>
|
||||
<string name="messageType">Type de message</string>
|
||||
<string name="sms">SMS</string>
|
||||
<string name="mms">MMS</string>
|
||||
<string name="attachment">Attachement</string>
|
||||
<string name="chooseFile">Choisissez un fichier</string>
|
||||
<string name="startAppByStartService">via startService()</string>
|
||||
<string name="showToastsForEvents">Afficher les toasts</string>
|
||||
<string name="showToastsForEventsSummary">Afficher les toasts lorsque des événements tels que des exécutions de règles se produisent</string>
|
||||
<string name="notificationAccessAndroid13">Après avoir cliqué sur OK, sélectionnez Automatisation, puis sélectionnez \"Autoriser l\'accès aux notifications\ », puis \"Autoriser\ ».\n\nSur certains systèmes, ce paramètre est grisé. Dans ces cas, vous devez aller dans \"settings\ » -> \"apps\ » -> \"Automation\ » -> 3-dots-menu -> Levez ces restrictions. Ensuite, revenez ici.</string>
|
||||
<string name="displayLanguage">Langue d\'affichage</string>
|
||||
<string name="displayLanguageSummary">Définir une langue personnalisée pour l\'application</string>
|
||||
<string name="wifiMonitoringAlsoRequiresThis">Cette autorisation est également requise si le déclencheur utilise la connexion wifi actuelle.</string>
|
||||
<string name="copyTextToClipboard">Copier du texte dans le presse-papiers</string>
|
||||
<string name="textToCopy">Texte à copier</string>
|
||||
<string name="android.permission.SYSTEM_ALERT_WINDOW">Dessiner sur d\'autres applications</string>
|
||||
<string name="overlayPermissionHint">Après avoir cliqué sur OK, vous serez redirigé vers une boîte de dialogue système. Veuillez sélectionner Automatisation et autoriser le tirage sur d\'autres applications.</string>
|
||||
<string name="variablesOnlyForTypes">Les variables ne sont disponibles que pour les types de paramètres String et URI</string>
|
||||
<string name="intentParametersHint">Si vous souhaitez spécifier un paramètre, vous devez également cliquer sur « Ajouter une paire d\'intentions ». Sinon, vos modifications ne seront pas enregistrées.</string>
|
||||
<string name="languagePolish">Polonais</string>
|
||||
<string name="languageChineseChina">Chinois (Chine)</string>
|
||||
<string name="wifiTriggerDisconnectionHint">Ce déclencheur sera valide si vous venez de vous déconnecter du wifi spécifié ci-dessus OU alors que le service est encore en cours de démarrage et si vous n\'êtes connecté à aucun wifi. Si vous souhaitez que le déclencheur ne se déclenche que lorsque vous vous déconnectez explicitement d\'un certain wifi, ajoutez un autre déclencheur « le service ne démarre pas ».</string>
|
||||
<string name="className">Nom de la classe</string>
|
||||
<string name="startAppByStartForegroundService">par startForegroundService()</string>
|
||||
<string name="method">Méthode</string>
|
||||
<string name="takeScreenshot">Prendre une capture d\'écran</string>
|
||||
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Se lier au service d\'accessibilité</string>
|
||||
<string name="bindAccessibilityService">Se lier au service d\'accessibilité</string>
|
||||
<string name="accessibilityApiPermissionHint">Après avoir cliqué sur OK, vous serez redirigé vers une boîte de dialogue système. Sélectionnez Automatisation et autorisez l\'option Autoriser l\'API d\'accessibilité.</string>
|
||||
<string name="accessibility_service_explanation">Obligatoire pour certaines actions.</string>
|
||||
<string name="noticeRestrictedPermissions">Si vous ne parvenez pas à accorder à l\'un d\'entre eux l\'autorisation suivante et un message système tel que « Autorisation restreinte », vous devez d\'abord accéder aux paramètres Android, puis aux applications, puis choisir Automatisation. Maintenant, il devrait y avoir 3 points dans le coin supérieur droit. Cliquez sur « Autoriser les paramètres restreints ». Après cela, l\'autorisation nécessaire devrait pouvoir être accordée. Cela ne devrait s\'appliquer qu\'à la version APK de l\'application, pas à celles de F-Droid ou du Play Store.</string>
|
||||
<string name="setLocationService">Définir le service de localisation</string>
|
||||
<string name="writeSecureSettingsNotice">Malheureusement, l\'autorisation WRITE_SECURE_SETTINGS ne peut pas être donnée directement sur votre appareil Android. Au lieu de cela, vous devez connecter votre appareil à un ordinateur et accorder l\'autorisation via ADB. Cliquez ici pour savoir comment l\'accorder : https://server47.de/automation/adb_hack.php</string>
|
||||
<string name="actionSetLocationService">Service de localisation</string>
|
||||
<string name="triggerUrlVariableHint">Le résultat de cette requête sera stocké dans la variable LAST_TRIGGERURL_RESULT si vous souhaitez le vérifier à partir d\'une autre règle. En cas d\'erreurs HTTP comme 404, la valeur sera « HTTP_ERROR ».</string>
|
||||
</resources>
|
||||
|