Compare commits

..

57 Commits

Author SHA1 Message Date
41cf907be3 Merge remote-tracking branch 'origin/development' 2021-12-24 01:50:44 +01:00
ebfceee69f Translations 2021-12-24 01:38:42 +01:00
69283c5fea Translations 2021-12-21 20:02:13 +01:00
fff0bde9d8 Merge remote-tracking branch 'origin/development' into development 2021-12-20 19:58:56 +01:00
f9c76ba951 Rework 2021-12-20 19:58:43 +01:00
d1263b46b6 Refactoring 2021-12-19 22:31:05 +01:00
64801d8ff2 Rework 2021-12-19 17:12:24 +01:00
3d8257aeec Rework 2021-12-19 14:47:46 +01:00
67b2a81647 Rework 2021-12-19 12:58:33 +01:00
3e9590d7d2 Rework 2021-12-18 13:29:47 +01:00
21b8c6c7ec Rework 2021-12-18 02:43:04 +01:00
dc8cc14d20 Rework 2021-12-13 20:03:26 +01:00
4fc1f8a2a9 Rework 2021-12-13 20:03:00 +01:00
d7e1cd44e8 Rework 2021-12-12 20:03:53 +01:00
c1139e1cb8 Rework 2021-12-11 14:15:05 +01:00
03c8a1ff60 Rework 2021-12-11 02:04:45 +01:00
20acd563e7 Refactoring 2021-12-09 22:54:34 +01:00
5ae193847e Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Actions.java
2021-12-09 18:05:58 +01:00
391479b164 Rework 2021-12-09 18:03:00 +01:00
fa578b175d Refactoring 2021-12-08 23:08:05 +01:00
0008642044 Rework 2021-12-08 19:57:27 +01:00
359dd545c7 Merge remote-tracking branch 'origin/transfer_applies_to_trigger' into development 2021-12-08 17:22:33 +01:00
89ac69fd4b Rework 2021-12-08 17:22:18 +01:00
b88801500f Refactoring 2021-12-07 23:10:37 +01:00
128116025f Rework 2021-12-07 16:45:05 +01:00
5d3e89595f description 2021-12-05 22:28:30 +01:00
8e5ad15c34 Rework 2021-12-05 17:24:47 +01:00
8b29dd0985 Rework 2021-12-05 14:51:00 +01:00
c34ec83425 Rework 2021-12-04 13:24:43 +01:00
cdf1a8baa8 Rework 2021-12-04 02:39:37 +01:00
d28ee8d00d Fixed infinite loop 2021-12-03 22:30:34 +01:00
2bb6f81596 Position trigger 2021-11-30 18:25:51 +01:00
6f0dbc9555 Position trigger 2021-11-29 20:14:09 +01:00
a9bd7b9561 Position trigger 2021-11-28 20:01:58 +01:00
81d6ab7b5f Position trigger 2021-11-27 20:22:13 +01:00
034c76fe30 Translations and integrated BT tethering 2021-11-27 02:03:51 +01:00
15637e914d Translations and integrated BT tethering 2021-11-27 01:52:57 +01:00
cd6ed7543c Translations and integrated BT tethering 2021-11-26 19:26:42 +01:00
f991325566 Merge remote-tracking branch 'origin/BT_tethering' into development 2021-11-26 18:56:28 +01:00
b744e76b07 Negative location coordinates allowed 2021-11-23 13:27:09 +01:00
06d63826e6 Donate button 2021-11-20 16:14:21 +01:00
fb87d5e42d BT tethering 2021-11-17 21:46:56 +01:00
17109b12d4 BT tethering 2021-11-15 20:28:38 +01:00
92ca6d6cb4 BT tethering 2021-11-13 14:48:56 +01:00
5fdc68e396 Merge remote-tracking branch 'origin/reoccuring_time_trigger' into development 2021-11-13 12:31:27 +01:00
ab0f2d88b4 Reoccuring time trigger 2021-11-13 02:32:39 +01:00
06a6651fae Reoccuring time trigger 2021-11-13 02:17:36 +01:00
473c464bf7 BT tethering 2021-11-13 01:00:36 +01:00
a5b9ced9ba line break 2021-11-11 10:28:46 +01:00
9cea3f4285 reocc time 2021-11-10 21:47:09 +01:00
0438a58f3e translation 2021-11-09 11:10:06 +01:00
97f32bd012 Reoccuring time 2021-11-08 20:13:11 +01:00
6588443459 reoccuring time 2021-11-07 17:29:00 +01:00
604ab0eb43 miscellaneous 2021-11-07 15:38:42 +01:00
31c4f6c1d1 Fixed crash of edit wifi trigger 2021-11-07 02:09:09 +01:00
0c646b55fc Fixed infinite loop 2021-11-05 22:47:48 +01:00
88cdc366c5 Changelogs 2021-11-04 18:01:30 +01:00
81 changed files with 4922 additions and 3699 deletions

2
.gitignore vendored
View File

@ -148,3 +148,5 @@ fabric.properties
/app/app-release.apk /app/app-release.apk
Automation_settings.xml Automation_settings.xml
/app/googlePlayFlavor/
/.idea/deploymentTargetDropDown.xml

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\jens\.android\avd\Android_11.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-09-24T23:07:53.935197300Z" />
</component>
</project>

View File

@ -11,8 +11,8 @@ android {
compileSdkVersion 29 compileSdkVersion 29
buildToolsVersion '29.0.2' buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy' useLibrary 'org.apache.http.legacy'
versionCode 113 versionCode 114
versionName "1.6.43" versionName "1.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@ -11,8 +11,8 @@
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"attributes": [], "attributes": [],
"versionCode": 113, "versionCode": 114,
"versionName": "1.6.43-googlePlay", "versionName": "1.7-googlePlay",
"outputFile": "app-googlePlayFlavor-release.apk" "outputFile": "app-googlePlayFlavor-release.apk"
} }
], ],

View File

@ -132,10 +132,23 @@
android:scheme="package" />--> android:scheme="package" />-->
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.AlarmListener" /> <receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" /> <receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" /> <receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" /> <activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@ -145,6 +158,7 @@
<activity android:name=".ActivityMaintenance" /> <activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" /> <activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" /> <activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" /> <activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" /> <activity android:name=".ActivityManageActionVibrate" />
<activity <activity
@ -186,6 +200,7 @@
<activity android:name=".ActivityManageActionStartActivity" /> <activity android:name=".ActivityManageActionStartActivity" />
<activity android:name=".ActivityManageTriggerNfc" /> <activity android:name=".ActivityManageTriggerNfc" />
<activity android:name=".ActivityManageActionSpeakText" /> <activity android:name=".ActivityManageActionSpeakText" />
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerBluetooth" /> <activity android:name=".ActivityManageTriggerBluetooth" />
<activity android:name=".ActivityMainProfiles" /> <activity android:name=".ActivityMainProfiles" />
<activity android:name=".ActivityManageProfile" /> <activity android:name=".ActivityManageProfile" />
@ -204,6 +219,7 @@
</service> </service>
<activity android:name=".ActivityPermissions" />
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p--> <!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/> <uses-library android:name="org.apache.http.legacy" android:required="false"/>

File diff suppressed because it is too large Load Diff

View File

@ -291,10 +291,10 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING). * and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/ */
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection(); ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++) for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{ {
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext())) if(allRulesWithActivityDetection.get(i).getsGreenLight(Miscellaneous.getAnyContext()))
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false); allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
} }
} }

View File

@ -129,10 +129,23 @@
android:scheme="package" />--> android:scheme="package" />-->
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.AlarmListener" /> <receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" /> <receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" /> <receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" /> <activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@ -142,6 +155,7 @@
<activity android:name=".ActivityMaintenance" /> <activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" /> <activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" /> <activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" /> <activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" /> <activity android:name=".ActivityManageActionVibrate" />
<activity <activity

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" /> <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.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
@ -123,10 +124,23 @@
android:scheme="package" />--> android:scheme="package" />-->
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.AlarmListener" /> <receiver android:name=".receivers.DateTimeListener" />
<receiver android:name=".receivers.ConnectivityReceiver" /> <receiver android:name=".receivers.ConnectivityReceiver" />
<receiver android:name=".receivers.TimeZoneListener" /> <receiver android:name=".receivers.TimeZoneListener" />
<receiver
android:name=".DeviceAdmin"
android:description="@string/app_name"
android:label="@string/app_name"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<activity android:name=".ActivityManageRule" /> <activity android:name=".ActivityManageRule" />
<activity android:name=".ActivityManageActionTriggerUrl" /> <activity android:name=".ActivityManageActionTriggerUrl" />
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
@ -136,6 +150,7 @@
<activity android:name=".ActivityMaintenance" /> <activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" /> <activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" /> <activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" /> <activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" /> <activity android:name=".ActivityManageActionVibrate" />
<activity <activity

File diff suppressed because it is too large Load Diff

View File

@ -301,7 +301,7 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING). * and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
*/ */
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection(); ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidates(Trigger_Enum.activityDetection);
for(int i=0; i<allRulesWithActivityDetection.size(); i++) for(int i=0; i<allRulesWithActivityDetection.size(); i++)
{ {
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext())) if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))

View File

@ -5,6 +5,7 @@ import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import java.util.ArrayList; import java.util.ArrayList;
@ -13,6 +14,8 @@ import java.util.Locale;
public class Action public class Action
{ {
Rule parentRule = null;
public static final String actionParameter2Split = "ap2split"; public static final String actionParameter2Split = "ap2split";
public static final String intentPairSeperator = "intPairSplit"; public static final String intentPairSeperator = "intPairSplit";
public static final String vibrateSeparator = ","; public static final String vibrateSeparator = ",";
@ -22,6 +25,7 @@ public class Action
setBluetooth, setBluetooth,
setUsbTethering, setUsbTethering,
setWifiTethering, setWifiTethering,
setBluetoothTethering,
setDisplayRotation, setDisplayRotation,
turnWifiOn,turnWifiOff, turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff, turnBluetoothOn,turnBluetoothOff,
@ -29,10 +33,10 @@ public class Action
changeSoundProfile, changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff, turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff, turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation, disableScreenRotation, enableScreenRotation,disableScreenRotation,
startOtherActivity, startOtherActivity,
waitBeforeNextAction, waitBeforeNextAction,
wakeupDevice, turnScreenOnOrOff,
setAirplaneMode, setAirplaneMode,
setDataConnection, setDataConnection,
speakText, speakText,
@ -52,6 +56,8 @@ public class Action
return context.getResources().getString(R.string.actionSetBluetooth); return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering: case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering); return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering: case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering); return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation: case setDisplayRotation:
@ -84,8 +90,8 @@ public class Action
return context.getResources().getString(R.string.startOtherActivity); return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction: case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction); return context.getResources().getString(R.string.waitBeforeNextAction);
case wakeupDevice: case turnScreenOnOrOff:
return context.getResources().getString(R.string.wakeupDevice); return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate: case vibrate:
return context.getResources().getString(R.string.vibrate); return context.getResources().getString(R.string.vibrate);
case setAirplaneMode: case setAirplaneMode:
@ -176,6 +182,13 @@ public class Action
else else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff)); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
} }
else if(this.getAction().equals(Action_Enum.setBluetoothTethering))
{
if(this.getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothTetheringOff));
}
else if(this.getAction().equals(Action_Enum.setDisplayRotation)) else if(this.getAction().equals(Action_Enum.setDisplayRotation))
{ {
if(this.getParameter1()) if(this.getParameter1())
@ -217,9 +230,12 @@ public class Action
{ {
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage)); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
} }
else if(this.getAction().equals(Action_Enum.wakeupDevice)) else if(this.getAction().equals(Action_Enum.turnScreenOnOrOff))
{ {
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wakeupDevice)); if(getParameter1())
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOn));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.turnScreenOff));
} }
else if(this.getAction().equals(Action_Enum.playSound)) else if(this.getAction().equals(Action_Enum.playSound))
{ {
@ -273,6 +289,16 @@ public class Action
return returnString.toString(); return returnString.toString();
} }
public Rule getParentRule()
{
return parentRule;
}
public void setParentRule(Rule parentRule)
{
this.parentRule = parentRule;
}
public static CharSequence[] getActionTypesAsArray() public static CharSequence[] getActionTypesAsArray()
{ {
ArrayList<String> actionTypesList = new ArrayList<String>(); ArrayList<String> actionTypesList = new ArrayList<String>();
@ -370,6 +396,9 @@ public class Action
case setWifiTethering: case setWifiTethering:
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible); Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
break; break;
case setBluetoothTethering:
Actions.BluetoothTetheringClass.setBluetoothTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setDisplayRotation: case setDisplayRotation:
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible); Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
break; break;
@ -379,16 +408,26 @@ public class Action
case waitBeforeNextAction: case waitBeforeNextAction:
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2())); Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
break; break;
case wakeupDevice: case turnScreenOnOrOff:
Actions.wakeupDevice(Long.parseLong(this.getParameter2())); if(getParameter1())
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
try
{ {
Thread.sleep(100); if(StringUtils.isNumeric(this.getParameter2()))
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
else
Actions.wakeupDevice((long)1000);
// wakeupDevice() will create a separate thread. That'll take some time, we wait 100ms.
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} }
catch (InterruptedException e) else
{ {
e.printStackTrace(); Actions.turnOffScreen();
} }
break; break;
case setAirplaneMode: case setAirplaneMode:

View File

@ -5,7 +5,11 @@ import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -43,13 +47,16 @@ import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import java.io.File; import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -304,6 +311,149 @@ public class Actions
return true; return true;
} }
public static class BluetoothTetheringClass
{
static Object instance = null;
static Method setTetheringOn = null;
static Method isTetheringOn = null;
static Object mutex = new Object();
public static Boolean setBluetoothTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "Bluetooth Tethering", "Changing Bluetooth Tethering to " + String.valueOf(desiredState), 4);
// boolean state = isTetheringOn(context);
// if (toggleActionIfPossible)
// {
// Miscellaneous.logEvent("i", "Bluetooth Tethering", context.getResources().getString(R.string.toggling), 2);
// desiredState = !state;
// }
// if (((state && !desiredState) || (!state && desiredState)))
// {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Method mBTPanConnect = null;
String sClassName = "android.bluetooth.BluetoothPan";
try
{
classBluetoothPan = Class.forName(sClassName);
Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
ctor.setAccessible(true);
// Set Tethering ON
Class[] paramSet = new Class[1];
paramSet[0] = boolean.class;
synchronized (mutex)
{
setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);
isTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", null);
instance = ctor.newInstance(context, new BTPanServiceListener(context));
}
classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
mBTPanConnect = classBluetoothPan.getDeclaredMethod("connect", BluetoothDevice.class);
BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
BTPanCtor.setAccessible(true);
BTSrvInstance = BTPanCtor.newInstance(context, new BTPanServiceListener(context));
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0)
{
// Loop through paired devices
for (BluetoothDevice device : pairedDevices)
{
try
{
mBTPanConnect.invoke(BTSrvInstance, device);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
}
return true;
}
catch (NoSuchMethodException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (ClassNotFoundException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch(InvocationTargetException e)
{
/*
Exact error message: "Bluetooth binder is null"
This means this device doesn't have bluetooth.
*/
Miscellaneous.logEvent("e", "Bluetooth Tethering", "Device probably doesn't have bluetooth. " + Log.getStackTraceString(e), 1);
Toast.makeText(context, context.getResources().getString(R.string.deviceDoesNotHaveBluetooth), Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
return false;
}
public static class BTPanServiceListener implements BluetoothProfile.ServiceListener
{
private final Context context;
public BTPanServiceListener(final Context context)
{
this.context = context;
}
@Override
public void onServiceConnected(final int profile, final BluetoothProfile proxy)
{
//Some code must be here or the compiler will optimize away this callback.
try
{
synchronized (mutex)
{
setTetheringOn.invoke(instance, true);
if ((Boolean) isTetheringOn.invoke(instance, null))
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is on", 1);
}
else
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is off", 1);
}
}
}
catch (InvocationTargetException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (IllegalAccessException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
@Override
public void onServiceDisconnected(final int profile)
{
}
}
}
public static boolean setUsbTethering(Context context2, Boolean desiredState, boolean toggleActionIfPossible) public static boolean setUsbTethering(Context context2, Boolean desiredState, boolean toggleActionIfPossible)
{ {
//TODO:toggle not really implemented, yet //TODO:toggle not really implemented, yet
@ -945,23 +1095,96 @@ public class Actions
@Override @Override
public void run() public void run()
{ {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock((WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
wakeLock.acquire();
try try
{ {
Thread.sleep(awakeTime); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
} WakeLock wakeLock = pm.newWakeLock((PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
catch (InterruptedException e) wakeLock.acquire();
{
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
}
wakeLock.release(); try
{
Thread.sleep(awakeTime);
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
}
wakeLock.release();
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "Wakeup device action", "Error while waking up device: " + Log.getStackTraceString(e), 1);
}
} }
} }
/*public static void turnOnScreen()
{
// turn on screen
Miscellaneous.logEvent("i", "Actions", "Turning screen on.", 3);
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
wakeLock.acquire();
}*/
@TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
public static void turnOffScreen()
{
Miscellaneous.logEvent("i", "Actions", "Turning screen off.", 3);
/*params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);*/
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
// wakeLock.acquire();
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , "tag");
// wakeLock.acquire();
// wakeLock.release();
lockScreen();
}
public static void lockScreen()
{
Miscellaneous.logEvent("i", "Actions", "Locking screen.", 3);
// Works, but requires Manifest.permission.BIND_DEVICE_ADMIN
// https://stackoverflow.com/questions/23898406/java-lang-securityexception-no-active-admin-owned-by-uid-10047-for-policy-4-on
DevicePolicyManager deviceManager = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
deviceManager.lockNow();
}
// using root
/*private void turnOffScreen()
{
try
{
Class c = Class.forName("android.os.PowerManager");
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
for(Method m : c.getDeclaredMethods())
{
if(m.getName().equals("goToSleep"))
{
m.setAccessible(true);
if(m.getParameterTypes().length == 1)
{
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
}
}
}
}
catch (Exception e)
{
}
}*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("NewApi") @SuppressLint("NewApi")
public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible) public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible)

View File

@ -9,7 +9,6 @@ import com.jens.automation2.R.layout;
public class ActivityHelp extends Activity public class ActivityHelp extends Activity
{ {
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
@ -19,5 +18,4 @@ public class ActivityHelp extends Activity
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving); TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance()); tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
} }
}
}

View File

@ -19,7 +19,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.jens.automation2.AutomationService.serviceCommands; import com.jens.automation2.AutomationService.serviceCommands;
import com.jens.automation2.receivers.AlarmListener; import com.jens.automation2.receivers.DateTimeListener;
import java.util.ArrayList; import java.util.ArrayList;
@ -254,7 +254,7 @@ public class ActivityMainRules extends ActivityGeneric
try try
{ {
if(AutomationService.isMyServiceRunning(this)) if(AutomationService.isMyServiceRunning(this))
AlarmListener.reloadAlarms(); DateTimeListener.reloadAlarms();
} }
catch(NullPointerException e) catch(NullPointerException e)
{ {

View File

@ -44,7 +44,7 @@ public class ActivityMainScreen extends ActivityGeneric
private static ActivityMainScreen activityMainScreenInstance = null; private static ActivityMainScreen activityMainScreenInstance = null;
private ToggleButton toggleService, tbLockSound; private ToggleButton toggleService, tbLockSound;
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme; private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme, bDonate;
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration; private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration;
private static boolean updateNoteDisplayed = false; private static boolean updateNoteDisplayed = false;
@ -82,6 +82,12 @@ public class ActivityMainScreen extends ActivityGeneric
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration); tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound); tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener); toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
if(!BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
bDonate.setVisibility(View.VISIBLE);
toggleService.setChecked(AutomationService.isMyServiceRunning(this)); toggleService.setChecked(AutomationService.isMyServiceRunning(this));
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener() toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
{ {
@ -111,6 +117,18 @@ public class ActivityMainScreen extends ActivityGeneric
} }
}); });
bDonate.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
String privacyPolicyUrl = "https://server47.de/donate";
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
startActivity(browserIntent);
}
});
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener() tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
{ {
@Override @Override

View File

@ -72,4 +72,4 @@ public class ActivityMainTabLayout extends TabActivity
// setIntent(intent); // setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent); NfcReceiver.checkIntentForNFC(this, intent);
} }
} }

View File

@ -201,6 +201,9 @@ public class ActivityMaintenance extends Activity
try try
{ {
XmlFileInterface.readFile(); XmlFileInterface.readFile();
ActivityMainPoi.getInstance().updateListView();
ActivityMainRules.getInstance().updateListView();
ActivityMainProfiles.getInstance().updateListView();
} }
catch (Exception e) catch (Exception e)
{ {
@ -314,18 +317,9 @@ public class ActivityMaintenance extends Activity
String subject = "Automation logs"; String subject = "Automation logs";
StringBuilder emailBody = new StringBuilder();
emailBody.append("Device details" + Miscellaneous.lineSeparator);
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
emailBody.append("Product: " + android.os.Build.PRODUCT);
emailBody.append("Flavor: " + BuildConfig.FLAVOR);
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName); Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri); Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", getSystemInfo(), uri);
} }
}); });
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null); alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
@ -334,6 +328,19 @@ public class ActivityMaintenance extends Activity
return alertDialog; return alertDialog;
} }
public static String getSystemInfo()
{
StringBuilder systemInfoText = new StringBuilder();
systemInfoText.append("Device details" + Miscellaneous.lineSeparator);
systemInfoText.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
systemInfoText.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
systemInfoText.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
systemInfoText.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
systemInfoText.append("Product: " + android.os.Build.PRODUCT + Miscellaneous.lineSeparator);
systemInfoText.append("Flavor: " + BuildConfig.FLAVOR);
return systemInfoText.toString();
}
@Override @Override
protected void onResume() protected void onResume()
{ {

View File

@ -59,7 +59,7 @@ public class ActivityManageActionSendTextMessage extends Activity
backToRuleManager(); backToRuleManager();
} }
else else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
} }
}); });

View File

@ -44,7 +44,7 @@ public class ActivityManageActionSpeakText extends Activity
backToRuleManager(); backToRuleManager();
} }
else else
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), getResources().getString(R.string.enterPhoneNumberAndText), Toast.LENGTH_LONG).show();
} }
}); });

View File

@ -49,6 +49,9 @@ import java.util.Collections;
public class ActivityManageRule extends Activity public class ActivityManageRule extends Activity
{ {
final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver"; final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver";
public final static String intentNameTriggerParameter1 = "triggerParameter1";
public final static String intentNameActionParameter1 = "actionParameter1";
public final static String intentNameActionParameter2 = "actionParameter2";
public Context context; public Context context;
private Button cmdTriggerAdd, cmdActionAdd, cmdSaveRule; private Button cmdTriggerAdd, cmdActionAdd, cmdSaveRule;
@ -95,6 +98,8 @@ public class ActivityManageRule extends Activity
final static int requestCodeTriggerBluetoothEdit = 6001; final static int requestCodeTriggerBluetoothEdit = 6001;
final static int requestCodeActionScreenBrightnessAdd = 401; final static int requestCodeActionScreenBrightnessAdd = 401;
final static int requestCodeActionScreenBrightnessEdit = 402; final static int requestCodeActionScreenBrightnessEdit = 402;
final static int requestCodeTriggerDeviceOrientationAdd = 301;
final static int requestCodeTriggerDeviceOrientationEdit = 302;
final static int requestCodeTriggerNotificationAdd = 8000; final static int requestCodeTriggerNotificationAdd = 8000;
final static int requestCodeTriggerNfcNotificationEdit = 8001; final static int requestCodeTriggerNfcNotificationEdit = 8001;
final static int requestCodeActionPlaySoundAdd = 501; final static int requestCodeActionPlaySoundAdd = 501;
@ -165,7 +170,13 @@ public class ActivityManageRule extends Activity
{ {
hideKeyboard(); hideKeyboard();
newTrigger = new Trigger(); newTrigger = new Trigger();
getTriggerTypeDialog(context).show();
AlertDialog dia = getTriggerTypeDialog(context);
if(Miscellaneous.isDarkModeEnabled(ActivityManageRule.this))
dia.getListView().setBackgroundColor(getResources().getColor(R.color.darkScreenBackgroundColor));
dia.show();
} }
}); });
@ -175,12 +186,18 @@ public class ActivityManageRule extends Activity
public void onClick(View v) public void onClick(View v)
{ {
hideKeyboard(); hideKeyboard();
getActionTypeDialog().show();
AlertDialog dia = getActionTypeDialog();
if(Miscellaneous.isDarkModeEnabled(ActivityManageRule.this))
dia.getListView().setBackgroundColor(getResources().getColor(R.color.darkScreenBackgroundColor));
dia.show();
} }
}); });
cmdSaveRule.setOnClickListener(new OnClickListener() cmdSaveRule.setOnClickListener(new OnClickListener()
{ {
@Override @Override
public void onClick(View v) public void onClick(View v)
{ {
@ -261,6 +278,12 @@ public class ActivityManageRule extends Activity
wifiEditor.putExtra("wifiName", selectedTrigger.getTriggerParameter2()); wifiEditor.putExtra("wifiName", selectedTrigger.getTriggerParameter2());
startActivityForResult(wifiEditor, requestCodeTriggerWifiEdit); startActivityForResult(wifiEditor, requestCodeTriggerWifiEdit);
break; break;
case deviceOrientation:
Intent devicePositionEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerDeviceOrientation.class);
devicePositionEditor.putExtra(ActivityManageRule.intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
devicePositionEditor.putExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName, selectedTrigger.getTriggerParameter2());
startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit);
break;
default: default:
break; break;
} }
@ -303,6 +326,7 @@ public class ActivityManageRule extends Activity
case triggerUrl: case triggerUrl:
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class); Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class);
ActivityManageActionTriggerUrl.resultingAction = a; ActivityManageActionTriggerUrl.resultingAction = a;
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
activityEditTriggerUrlIntent.putExtra("edit", true); activityEditTriggerUrlIntent.putExtra("edit", true);
startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit); startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit);
break; break;
@ -332,8 +356,8 @@ public class ActivityManageRule extends Activity
case playSound: case playSound:
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class); Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
actionPlaySoundIntent.putExtra("edit", true); actionPlaySoundIntent.putExtra("edit", true);
actionPlaySoundIntent.putExtra("actionParameter1", a.getParameter1()); actionPlaySoundIntent.putExtra(intentNameActionParameter1, a.getParameter1());
actionPlaySoundIntent.putExtra("actionParameter2", a.getParameter2()); actionPlaySoundIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit); startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit);
break; break;
default: default:
@ -403,6 +427,11 @@ public class ActivityManageRule extends Activity
ruleToEdit.setName(etRuleName.getText().toString()); ruleToEdit.setName(etRuleName.getText().toString());
ruleToEdit.setRuleActive(chkRuleActive.isChecked()); ruleToEdit.setRuleActive(chkRuleActive.isChecked());
ruleToEdit.setRuleToggle(chkRuleToggle.isChecked()); ruleToEdit.setRuleToggle(chkRuleToggle.isChecked());
for(Trigger t : ruleToEdit.getTriggerSet())
t.setParentRule(ruleToEdit);
for(Action a : ruleToEdit.getActionSet())
a.setParentRule(ruleToEdit);
} }
private void loadVariablesIntoGui() private void loadVariablesIntoGui()
@ -465,164 +494,175 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.headphone)); items.add(new Item(typesLong[i].toString(), R.drawable.headphone));
else if(types[i].toString().equals(Trigger_Enum.notification.toString())) else if(types[i].toString().equals(Trigger_Enum.notification.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.notification)); items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Trigger_Enum.deviceOrientation.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
} }
ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items) ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items)
{ {
public View getView(int position, View convertView, ViewGroup parent) 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); View v = super.getView(position, convertView, parent);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
//Put the image on the TextView TextView tv = (TextView)v.findViewById(android.R.id.text1);
tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
//Add margin between image and text (support various screen densities) //Put the image on the TextView
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f); tv.setCompoundDrawablesWithIntrinsicBounds(items.get(position).icon, 0, 0, 0);
tv.setCompoundDrawablePadding(dp5);
return v; //Add margin between image and text (support various screen densities)
} int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
}; tv.setCompoundDrawablePadding(dp5);
AlertDialog.Builder builder = new AlertDialog.Builder(this) return v;
.setTitle(getResources().getString(R.string.selectTypeOfTrigger)) }
.setAdapter(adapter, new DialogInterface.OnClickListener() };
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onClick(DialogInterface dialog, int which)
{
triggerType = Trigger_Enum.values()[which];
String[] booleanChoices = null; AlertDialog.Builder builder = new AlertDialog.Builder(this)
if(triggerType == Trigger_Enum.pointOfInterest) .setTitle(getResources().getString(R.string.selectTypeOfTrigger))
.setAdapter(adapter, new DialogInterface.OnClickListener()
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onClick(DialogInterface dialog, int which)
{
triggerType = Trigger_Enum.values()[which];
String[] booleanChoices = null;
if(triggerType == Trigger_Enum.pointOfInterest)
{
if(Miscellaneous.googleToBlameForLocation(false))
{ {
if(Miscellaneous.googleToBlameForLocation(false)) ActivityMainScreen.openGoogleBlamingWindow();
{
ActivityMainScreen.openGoogleBlamingWindow();
return;
}
else
{
if (PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
else
{
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
return;
}
}
}
else if(triggerType == Trigger_Enum.timeFrame)
{
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = newTrigger;
Intent timeFrameEditor = new Intent(myContext, ActivityManageTriggerTimeFrame.class);
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeAdd);
return; return;
} }
else if(triggerType == Trigger_Enum.charging)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
// else if(triggerType == Trigger_Enum.wifiConnection)
// booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.process_started_stopped)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.notification)
{
newTrigger.setTriggerType(Trigger_Enum.notification);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNotification.class);
startActivityForResult(nfcEditor, requestCodeTriggerNotificationAdd);
return;
}
else if(triggerType == Trigger_Enum.airplaneMode)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.roaming)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.phoneCall)
{
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
else if(triggerType == Trigger_Enum.activityDetection)
{
try
{
Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "isPlayServiceAvailable");
if(m != null)
{
boolean available = (Boolean)m.invoke(null);
if(available)
{
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
getTriggerActivityDetectionDialog().show();
}
else
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
}
else
Miscellaneous.messageBox(getResources().getString(R.string.error), getResources().getString(R.string.featureNotInFdroidVersion), ActivityManageRule.this).show();
}
catch (IllegalAccessException | InvocationTargetException e)
{
e.printStackTrace();
}
return;
}
else if(triggerType == Trigger_Enum.nfcTag)
{
if(NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
{
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNfc.class);
startActivityForResult(nfcEditor, requestCodeTriggerNfcTagAdd);
return;
}
}
else if(triggerType == Trigger_Enum.bluetoothConnection)
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
ActivityManageTriggerBluetooth.editedBluetoothTrigger = newTrigger;
Intent bluetoothEditor = new Intent(myContext, ActivityManageTriggerBluetooth.class);
startActivityForResult(bluetoothEditor, requestCodeTriggerBluetoothAdd);
return;
}
else if(triggerType == Trigger_Enum.headsetPlugged)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
if(triggerType == Trigger_Enum.nfcTag)
{
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show();
}
else else
{
if (PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
else
{
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
return;
}
}
}
else if(triggerType == Trigger_Enum.timeFrame)
{
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = newTrigger;
Intent timeFrameEditor = new Intent(myContext, ActivityManageTriggerTimeFrame.class);
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeAdd);
return;
}
else if(triggerType == Trigger_Enum.charging)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
else if(triggerType == Trigger_Enum.deviceOrientation)
{
newTrigger.setTriggerType(Trigger_Enum.deviceOrientation);
Intent devicePositionTriggerEditor = new Intent(myContext, ActivityManageTriggerDeviceOrientation.class);
startActivityForResult(devicePositionTriggerEditor, requestCodeTriggerDeviceOrientationAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
// else if(triggerType == Trigger_Enum.wifiConnection)
// booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.process_started_stopped)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.notification)
{
newTrigger.setTriggerType(Trigger_Enum.notification);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNotification.class);
startActivityForResult(nfcEditor, requestCodeTriggerNotificationAdd);
return;
}
else if(triggerType == Trigger_Enum.airplaneMode)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.roaming)
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
else if(triggerType == Trigger_Enum.phoneCall)
{
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
}
else if(triggerType == Trigger_Enum.activityDetection)
{
try
{
Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "isPlayServiceAvailable");
if(m != null)
{
boolean available = (Boolean)m.invoke(null);
if(available)
{
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
getTriggerActivityDetectionDialog().show();
}
else
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
}
else
Miscellaneous.messageBox(getResources().getString(R.string.error), getResources().getString(R.string.featureNotInFdroidVersion), ActivityManageRule.this).show();
}
catch (IllegalAccessException | InvocationTargetException e)
{
e.printStackTrace();
}
return;
}
else if(triggerType == Trigger_Enum.nfcTag)
{
if(NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
{
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNfc.class);
startActivityForResult(nfcEditor, requestCodeTriggerNfcTagAdd);
return;
}
}
else if(triggerType == Trigger_Enum.bluetoothConnection)
{
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
ActivityManageTriggerBluetooth.editedBluetoothTrigger = newTrigger;
Intent bluetoothEditor = new Intent(myContext, ActivityManageTriggerBluetooth.class);
startActivityForResult(bluetoothEditor, requestCodeTriggerBluetoothAdd);
return;
}
else if(triggerType == Trigger_Enum.headsetPlugged)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
if(triggerType == Trigger_Enum.nfcTag)
{
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show(); getTriggerParameterDialog(context, booleanChoices).show();
} }
}); else
getTriggerParameterDialog(context, booleanChoices).show();
return builder.create(); }
});
return builder.create();
} }
private AlertDialog getTriggerParameterDialog(final Context myContext, final String[] choices) private AlertDialog getTriggerParameterDialog(final Context myContext, final String[] choices)
{ {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
@ -1086,6 +1126,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
//add TriggerUrl //add TriggerUrl
ActivityManageActionTriggerUrl.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionTriggerUrl.resultingAction); ruleToEdit.getActionSet().add(ActivityManageActionTriggerUrl.resultingAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1103,6 +1144,7 @@ public class ActivityManageRule extends Activity
//add TimeFrame //add TimeFrame
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null) if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
{ {
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger); ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList(); this.refreshTriggerList();
} }
@ -1114,6 +1156,7 @@ public class ActivityManageRule extends Activity
//edit TimeFrame //edit TimeFrame
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null) if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
{ {
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList(); this.refreshTriggerList();
} }
else else
@ -1125,6 +1168,7 @@ public class ActivityManageRule extends Activity
{ {
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false)); newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName")); newTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger); ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList(); this.refreshTriggerList();
} }
@ -1133,8 +1177,12 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false)); Trigger editedTrigger = new Trigger();
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName")); editedTrigger.setTriggerType(Trigger_Enum.wifiConnection);
editedTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
editedTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList(); this.refreshTriggerList();
} }
} }
@ -1144,6 +1192,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newAction = ActivityManageActionStartActivity.resultingAction; newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1154,6 +1203,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newAction = ActivityManageActionStartActivity.resultingAction; newAction = ActivityManageActionStartActivity.resultingAction;
newAction.setParentRule(ruleToEdit);
// ruleToEdit.getActionSet().add(newAction); // ruleToEdit.getActionSet().add(newAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1164,6 +1214,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK && ActivityManageTriggerNfc.generatedId != null) if(resultCode == RESULT_OK && ActivityManageTriggerNfc.generatedId != null)
{ {
newTrigger.setNfcTagId(ActivityManageTriggerNfc.generatedId); newTrigger.setNfcTagId(ActivityManageTriggerNfc.generatedId);
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger); ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList(); this.refreshTriggerList();
} }
@ -1185,6 +1236,7 @@ public class ActivityManageRule extends Activity
data.getStringExtra("textDir") + Trigger.triggerParameter2Split + data.getStringExtra("textDir") + Trigger.triggerParameter2Split +
data.getStringExtra("text") data.getStringExtra("text")
); );
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList(); this.refreshTriggerList();
} }
} }
@ -1193,6 +1245,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newTrigger = ActivityManageTriggerNotification.resultingTrigger; newTrigger = ActivityManageTriggerNotification.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList(); this.refreshTriggerList();
} }
} }
@ -1200,6 +1253,7 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger); ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2")); newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2"));
this.refreshTriggerList(); this.refreshTriggerList();
@ -1210,6 +1264,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newTrigger = ActivityManageTriggerPhoneCall.resultingTrigger; newTrigger = ActivityManageTriggerPhoneCall.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList(); this.refreshTriggerList();
} }
} }
@ -1218,6 +1273,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
//add SpeakText //add SpeakText
ActivityManageActionSpeakText.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionSpeakText.resultingAction); ruleToEdit.getActionSet().add(ActivityManageActionSpeakText.resultingAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1227,6 +1283,7 @@ public class ActivityManageRule extends Activity
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
//edit SpeakText //edit SpeakText
ActivityManageActionSpeakText.resultingAction.setParentRule(ruleToEdit);
newAction = ActivityManageActionSpeakText.resultingAction; newAction = ActivityManageActionSpeakText.resultingAction;
this.refreshActionList(); this.refreshActionList();
} }
@ -1236,6 +1293,7 @@ public class ActivityManageRule extends Activity
//add bluetooth trigger //add bluetooth trigger
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null) if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
{ {
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger); ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList(); this.refreshTriggerList();
} }
@ -1247,6 +1305,7 @@ public class ActivityManageRule extends Activity
//edit bluetooth trigger //edit bluetooth trigger
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null) if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
{ {
ActivityManageTriggerBluetooth.editedBluetoothTrigger.setParentRule(ruleToEdit);
this.refreshTriggerList(); this.refreshTriggerList();
} }
else else
@ -1258,6 +1317,7 @@ public class ActivityManageRule extends Activity
{ {
newAction.setParameter1(data.getBooleanExtra("autoBrightness", false)); newAction.setParameter1(data.getBooleanExtra("autoBrightness", false));
newAction.setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0))); newAction.setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0)));
newAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1272,6 +1332,8 @@ public class ActivityManageRule extends Activity
if(data.hasExtra("brightnessValue")) if(data.hasExtra("brightnessValue"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0))); ruleToEdit.getActionSet().get(editIndex).setParameter2(String.valueOf(data.getIntExtra("brightnessValue", 0)));
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
this.refreshActionList(); this.refreshActionList();
} }
} }
@ -1279,6 +1341,7 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra("vibratePattern")); newAction.setParameter2(data.getStringExtra("vibratePattern"));
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
this.refreshActionList(); this.refreshActionList();
@ -1288,6 +1351,8 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra("vibratePattern")) if(data.hasExtra("vibratePattern"))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("vibratePattern")); ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("vibratePattern"));
@ -1298,8 +1363,9 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
newAction.setParameter1(data.getBooleanExtra("actionParameter1", false)); newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra("actionParameter2")); newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction); ruleToEdit.getActionSet().add(newAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1308,11 +1374,13 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
if(data.hasExtra("actionParameter1")) ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra("actionParameter1", false));
if(data.hasExtra("actionParameter2")) if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("actionParameter2")); ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList(); this.refreshActionList();
} }
@ -1321,7 +1389,7 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
//add SendTextMessage ActivityManageActionSendTextMessage.resultingAction.setParentRule(ruleToEdit);
ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction); ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction);
this.refreshActionList(); this.refreshActionList();
} }
@ -1330,15 +1398,39 @@ public class ActivityManageRule extends Activity
{ {
if(resultCode == RESULT_OK) if(resultCode == RESULT_OK)
{ {
//edit SendTextMessage
newAction = ActivityManageActionSendTextMessage.resultingAction; newAction = ActivityManageActionSendTextMessage.resultingAction;
newAction.setParentRule(ruleToEdit);
//ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction); //ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction);
this.refreshActionList(); this.refreshActionList();
} }
} }
else if(requestCode == requestCodeTriggerDeviceOrientationAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerDeviceOrientationEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.deviceOrientation);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
} }
protected Dialog getActionTypeDialog() protected AlertDialog getActionTypeDialog()
{ {
final ArrayList<Item> items = new ArrayList<Item>(); final ArrayList<Item> items = new ArrayList<Item>();
@ -1355,14 +1447,16 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.router)); items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setWifiTethering.toString())) else if(types[i].toString().equals(Action_Enum.setWifiTethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router)); items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setBluetoothTethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else if(types[i].toString().equals(Action_Enum.setDisplayRotation.toString())) else if(types[i].toString().equals(Action_Enum.setDisplayRotation.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.displayrotation)); items.add(new Item(typesLong[i].toString(), R.drawable.displayrotation));
else if(types[i].toString().equals(Action_Enum.waitBeforeNextAction.toString())) else if(types[i].toString().equals(Action_Enum.waitBeforeNextAction.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.wait)); items.add(new Item(typesLong[i].toString(), R.drawable.wait));
else if(types[i].toString().equals(Action_Enum.setAirplaneMode.toString())) else if(types[i].toString().equals(Action_Enum.setAirplaneMode.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.plane)); items.add(new Item(typesLong[i].toString(), R.drawable.plane));
else if(types[i].toString().equals(Action_Enum.wakeupDevice.toString())) else if(types[i].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm)); items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else if(types[i].toString().equals(Action_Enum.changeSoundProfile.toString())) else if(types[i].toString().equals(Action_Enum.changeSoundProfile.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.sound)); items.add(new Item(typesLong[i].toString(), R.drawable.sound));
else if(types[i].toString().equals(Action_Enum.triggerUrl.toString())) else if(types[i].toString().equals(Action_Enum.triggerUrl.toString()))
@ -1455,6 +1549,17 @@ public class ActivityManageRule extends Activity
newAction.setAction(Action_Enum.setWifiTethering); newAction.setAction(Action_Enum.setWifiTethering);
getActionParameter1Dialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
} }
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetoothTethering.toString()))
{
newAction.setAction(Action_Enum.setBluetoothTethering);
getActionParameter1Dialog(ActivityManageRule.this).show();
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH))
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
Miscellaneous.messageBox(context.getResources().getString(R.string.notice), context.getResources().getString(R.string.btTetheringNotice), context).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDisplayRotation.toString())) else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDisplayRotation.toString()))
{ {
newAction.setAction(Action_Enum.setDisplayRotation); newAction.setAction(Action_Enum.setDisplayRotation);
@ -1481,10 +1586,10 @@ public class ActivityManageRule extends Activity
newAction.setAction(Action_Enum.waitBeforeNextAction); newAction.setAction(Action_Enum.waitBeforeNextAction);
getActionWaitBeforeNextActionDialog(ActivityManageRule.this).show(); getActionWaitBeforeNextActionDialog(ActivityManageRule.this).show();
} }
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.wakeupDevice.toString())) else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.turnScreenOnOrOff.toString()))
{ {
newAction.setAction(Action_Enum.wakeupDevice); newAction.setAction(Action_Enum.turnScreenOnOrOff);
getActionWakeupDeviceDialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
} }
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString())) else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString()))
{ {
@ -1492,7 +1597,6 @@ public class ActivityManageRule extends Activity
getActionParameter1Dialog(ActivityManageRule.this).show(); getActionParameter1Dialog(ActivityManageRule.this).show();
if(Build.VERSION.SDK_INT >= 17) if(Build.VERSION.SDK_INT >= 17)
{ {
// Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show();
Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show(); Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
} }
} }
@ -1512,7 +1616,7 @@ public class ActivityManageRule extends Activity
} }
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString())) else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString()))
{ {
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS")) if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, Manifest.permission.SEND_SMS))
{ {
//launch other activity to enter parameters; //launch other activity to enter parameters;
newAction.setAction(Action_Enum.sendTextMessage); newAction.setAction(Action_Enum.sendTextMessage);

View File

@ -0,0 +1,295 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.jens.automation2.receivers.DeviceOrientationListener;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageTriggerDeviceOrientation extends Activity
{
TextView currentAzimuth, currentPitch, currentRoll, tvAppliesAzimuth, tvAppliesPitch, tvAppliesRoll;
Button bApplyPositionValues, bSavePositionValues;
EditText etDesiredAzimuth, etDesiredAzimuthTolerance, etDesiredPitch, etDesiredPitchTolerance, etDesiredRoll, etDesiredRollTolerance;
CheckBox chkDevicePositionApplies;
public static String vectorFieldName = "deviceVector";
boolean editMode = false;
float desiredAzimuth, desiredPitch, desiredRoll, desiredAzimuthTolerance, desiredPitchTolerance, desiredRollTolerance;
public void updateFields(float azimuth, float pitch, float roll)
{
currentAzimuth.setText(Float.toString(azimuth));
currentPitch.setText(Float.toString(pitch));
currentRoll.setText(Float.toString(roll));
try
{
desiredAzimuth = Float.parseFloat(etDesiredAzimuth.getText().toString());
desiredAzimuthTolerance = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
if (Math.abs(azimuth) <= Math.abs(desiredAzimuth - desiredAzimuthTolerance) || Math.abs(azimuth) <= desiredAzimuth + desiredAzimuthTolerance)
{
tvAppliesAzimuth.setText(getResources().getString(R.string.yes));
tvAppliesAzimuth.setTextColor(Color.GREEN);
}
else
{
tvAppliesAzimuth.setText(getResources().getString(R.string.no));
tvAppliesAzimuth.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesAzimuth.setText("");
}
try
{
desiredPitch = Float.parseFloat(etDesiredPitch.getText().toString());
desiredPitchTolerance = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
if (Math.abs(pitch) <= Math.abs(desiredPitch - desiredPitchTolerance) || Math.abs(pitch) <= desiredPitch + desiredPitchTolerance)
{
tvAppliesPitch.setText(getResources().getString(R.string.yes));
tvAppliesPitch.setTextColor(Color.GREEN);
}
else
{
tvAppliesPitch.setText(getResources().getString(R.string.no));
tvAppliesPitch.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesPitch.setText("");
}
try
{
desiredRoll = Float.parseFloat(etDesiredRoll.getText().toString());
desiredRollTolerance = Float.parseFloat(etDesiredRollTolerance.getText().toString());
if (Math.abs(roll) <= Math.abs(desiredRoll - desiredRollTolerance) || Math.abs(roll) <= desiredRoll + desiredRollTolerance)
{
tvAppliesRoll.setText(getResources().getString(R.string.yes));
tvAppliesRoll.setTextColor(Color.GREEN);
}
else
{
tvAppliesRoll.setText(getResources().getString(R.string.no));
tvAppliesRoll.setTextColor(Color.RED);
}
}
catch(Exception e)
{
tvAppliesRoll.setText("");
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_device_orientation);
currentAzimuth = (TextView) findViewById(R.id.tvCurrentAzimuth);
currentPitch = (TextView) findViewById(R.id.tvCurrentOrientationPitch);
currentRoll = (TextView) findViewById(R.id.tvCurrentRoll);
tvAppliesAzimuth = (TextView) findViewById(R.id.tvAppliesAzimuth);
tvAppliesPitch = (TextView) findViewById(R.id.tvAppliesPitch);
tvAppliesRoll = (TextView) findViewById(R.id.tvAppliesRoll);
bApplyPositionValues = (Button) findViewById(R.id.bApplyPositionValues);
bSavePositionValues = (Button) findViewById(R.id.bSavePositionValues);
etDesiredAzimuth = (EditText) findViewById(R.id.etDesiredAzimuth);
etDesiredAzimuthTolerance = (EditText) findViewById(R.id.etDesiredAzimuthTolerance);
etDesiredPitch = (EditText) findViewById(R.id.etDesiredPitch);
etDesiredPitchTolerance = (EditText) findViewById(R.id.etDesiredPitchTolerance);
etDesiredRoll = (EditText) findViewById(R.id.etDesiredRoll);
etDesiredRollTolerance = (EditText) findViewById(R.id.etDesiredRollTolerance);
chkDevicePositionApplies = (CheckBox)findViewById(R.id.chkDevicePositionApplies);
// etDesiredAzimuth.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredPitch.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
// etDesiredRoll.setFilters(new InputFilter[]{new InputFilterMinMax(-180, 180)});
etDesiredAzimuthTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredPitchTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
etDesiredRollTolerance.setFilters(new InputFilter[]{new InputFilterMinMax(0, 180)});
if(getIntent().hasExtra(vectorFieldName))
{
editMode = true;
try
{
boolean chkValue = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true);
chkDevicePositionApplies.setChecked(chkValue);
String values[] = getIntent().getStringExtra(vectorFieldName).split(Trigger.triggerParameter2Split);
etDesiredAzimuth.setText(values[0]);
etDesiredAzimuthTolerance.setText(values[1]);
etDesiredPitch.setText(values[2]);
etDesiredPitchTolerance.setText(values[3]);
etDesiredRoll.setText(values[4]);
etDesiredRollTolerance.setText(values[5]);
}
catch(Exception e)
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show();
Miscellaneous.logEvent("e", "DevicePositionTrigger", "There\'s something wrong with a device position trigger. Content: " + getIntent().getStringExtra(vectorFieldName) + ", " + Log.getStackTraceString(e), 1);
}
}
bApplyPositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(!StringUtils.isEmpty(currentAzimuth.getText()))
etDesiredAzimuth.setText(currentAzimuth.getText());
if(!StringUtils.isEmpty(currentPitch.getText()))
etDesiredPitch.setText(currentPitch.getText());
if(!StringUtils.isEmpty(currentRoll.getText()))
etDesiredRoll.setText(currentRoll.getText());
}
});
bSavePositionValues.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(!checkInputs(true))
{
Toast.makeText(ActivityManageTriggerDeviceOrientation.this, getResources().getString(R.string.enterValidNumbersIntoAllFields), Toast.LENGTH_LONG).show();
}
else
{
// Save
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkDevicePositionApplies.isChecked());
returnData.putExtra(vectorFieldName,
etDesiredAzimuth.getText().toString() + Trigger.triggerParameter2Split +
etDesiredAzimuthTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitch.getText().toString() + Trigger.triggerParameter2Split +
etDesiredPitchTolerance.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRoll.getText().toString() + Trigger.triggerParameter2Split +
etDesiredRollTolerance.getText().toString());
setResult(RESULT_OK, returnData);
finish();
}
}
});
}
boolean checkInputs(boolean showMessages)
{
if(
!StringUtils.isEmpty(etDesiredAzimuth.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuth.getText().toString())
&&
!StringUtils.isEmpty(etDesiredAzimuthTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredAzimuthTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitch.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitch.getText().toString())
&&
!StringUtils.isEmpty(etDesiredPitchTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredPitchTolerance.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRoll.getText().toString()) && Miscellaneous.isNumeric(etDesiredRoll.getText().toString())
&&
!StringUtils.isEmpty(etDesiredRollTolerance.getText().toString()) && Miscellaneous.isNumeric(etDesiredRollTolerance.getText().toString())
)
{
float da = Float.parseFloat(etDesiredAzimuth.getText().toString());
float dp = Float.parseFloat(etDesiredPitch.getText().toString());
float dr = Float.parseFloat(etDesiredRoll.getText().toString());
if(Math.abs(da) > 180 || Math.abs(dp) > 180 || Math.abs(dr) > 180)
{
return false;
}
if(showMessages)
{
float dat = Float.parseFloat(etDesiredAzimuthTolerance.getText().toString());
float dpt = Float.parseFloat(etDesiredPitchTolerance.getText().toString());
float drt = Float.parseFloat(etDesiredRollTolerance.getText().toString());
/*
The user may enter a tolerance of 180° for two directions, but not all three.
Otherwise this trigger would always apply.
*/
if (Math.abs(dat) >= 180 && Math.abs(dpt) >= 180 && Math.abs(drt) >= 180)
{
Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.toleranceOf180OnlyAllowedIn2Fields), ActivityManageTriggerDeviceOrientation.this).show();
return false;
}
}
return true;
}
return false;
}
@Override
protected void onResume()
{
super.onResume();
DeviceOrientationListener.getInstance().startSensorFromConfigActivity(ActivityManageTriggerDeviceOrientation.this, this);
}
@Override
protected void onPause()
{
super.onPause();
DeviceOrientationListener.getInstance().stopSensorFromConfigActivity();
}
public class InputFilterMinMax implements InputFilter
{
private float minimumValue;
private float maximumValue;
public InputFilterMinMax(float minimumValue, float maximumValue)
{
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
}
private boolean isInRange(float a, float b, float c)
{
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
try
{
int input = Integer.parseInt(dest.subSequence(0, dstart).toString() + source + dest.subSequence(dend, dest.length()));
if (isInRange(minimumValue, maximumValue, input))
return null;
}
catch (NumberFormatException nfe)
{
}
return "";
}
}
}

View File

@ -6,11 +6,16 @@ import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.TimePicker; import android.widget.TimePicker;
import android.widget.Toast; import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time; import java.sql.Time;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -18,8 +23,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
{ {
Button bSaveTimeFrame; Button bSaveTimeFrame;
TimePicker startPicker, stopPicker; TimePicker startPicker, stopPicker;
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday; CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday, chkRepeat;
RadioButton radioTimeFrameEntering, radioTimeFrameLeaving; RadioButton radioTimeFrameEntering, radioTimeFrameLeaving;
EditText etRepeatEvery;
public static Trigger editedTimeFrameTrigger = null; public static Trigger editedTimeFrameTrigger = null;
@ -44,7 +50,9 @@ public class ActivityManageTriggerTimeFrame extends Activity
checkSunday = (CheckBox)findViewById(R.id.checkSunday); checkSunday = (CheckBox)findViewById(R.id.checkSunday);
radioTimeFrameEntering = (RadioButton)findViewById(R.id.radioTimeFrameEntering); radioTimeFrameEntering = (RadioButton)findViewById(R.id.radioTimeFrameEntering);
radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving); radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving);
chkRepeat = (CheckBox)findViewById(R.id.chkRepeat);
etRepeatEvery = (EditText)findViewById(R.id.etRepeatEvery);
bSaveTimeFrame.setOnClickListener(new OnClickListener() bSaveTimeFrame.setOnClickListener(new OnClickListener()
{ {
@Override @Override
@ -92,11 +100,43 @@ public class ActivityManageTriggerTimeFrame extends Activity
{ {
Toast.makeText(getBaseContext(), getResources().getString(R.string.selectOneDay), Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), getResources().getString(R.string.selectOneDay), Toast.LENGTH_LONG).show();
return; return;
} }
boolean goOn = false;
if(chkRepeat.isChecked())
{
if(!StringUtils.isEmpty(etRepeatEvery.getText().toString()))
{
try
{
long value = Long.parseLong(etRepeatEvery.getText().toString());
if(value > 0)
{
goOn = true;
}
}
catch(Exception e)
{
}
}
}
else
goOn = true;
if(!goOn)
{
Toast.makeText(getBaseContext(), getResources().getString(R.string.enterRepetitionTime), Toast.LENGTH_LONG).show();
return;
}
if(editedTimeFrameTrigger.getTimeFrame() == null) if(editedTimeFrameTrigger.getTimeFrame() == null)
{
// add new one // add new one
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList)); if(chkRepeat.isChecked())
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, Long.parseLong(etRepeatEvery.getText().toString())));
else
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList, 0));
}
else else
{ {
// edit one // edit one
@ -104,6 +144,11 @@ public class ActivityManageTriggerTimeFrame extends Activity
editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStop(stopTime); editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStop(stopTime);
editedTimeFrameTrigger.getTimeFrame().getDayList().clear(); editedTimeFrameTrigger.getTimeFrame().getDayList().clear();
editedTimeFrameTrigger.getTimeFrame().setDayList(dayList); editedTimeFrameTrigger.getTimeFrame().setDayList(dayList);
if(chkRepeat.isChecked())
editedTimeFrameTrigger.getTimeFrame().setRepetition(Long.parseLong(etRepeatEvery.getText().toString()));
else
editedTimeFrameTrigger.getTimeFrame().setRepetition(0);
} }
editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked()); editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked());
@ -112,6 +157,15 @@ public class ActivityManageTriggerTimeFrame extends Activity
finish(); finish();
} }
}); });
chkRepeat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
etRepeatEvery.setEnabled(isChecked);
}
});
if(editedTimeFrameTrigger.getTimeFrame() != null) if(editedTimeFrameTrigger.getTimeFrame() != null)
loadVariableIntoGui(); loadVariableIntoGui();
@ -158,6 +212,12 @@ public class ActivityManageTriggerTimeFrame extends Activity
break; break;
} }
} }
if(editedTimeFrameTrigger.getTimeFrame().getRepetition() > 0)
{
chkRepeat.setChecked(true);
etRepeatEvery.setText(String.valueOf(editedTimeFrameTrigger.getTimeFrame().getRepetition()));
}
} }
} }

View File

@ -5,6 +5,7 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -46,6 +47,7 @@ public class ActivityPermissions extends Activity
private static final int requestCodeForPermissionsNotificationPolicy = 12044; private static final int requestCodeForPermissionsNotificationPolicy = 12044;
private static final int requestCodeForPermissionsBackgroundLocation = 12045; private static final int requestCodeForPermissionsBackgroundLocation = 12045;
private static final int requestCodeForPermissionsNotifications = 12046; private static final int requestCodeForPermissionsNotifications = 12046;
private static final int requestCodeForPermissionsDeviceAdmin = 12047;
protected String[] specificPermissionsToRequest = null; protected String[] specificPermissionsToRequest = null;
public static String intentExtraName = "permissionsToBeRequested"; public static String intentExtraName = "permissionsToBeRequested";
@ -238,9 +240,9 @@ public class ActivityPermissions extends Activity
if( if(
s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION) s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|| ||
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION) s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
|| ||
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION) s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
) )
{ {
if (!Miscellaneous.googleToBlameForLocation(true)) if (!Miscellaneous.googleToBlameForLocation(true))
@ -282,6 +284,10 @@ public class ActivityPermissions extends Activity
{ {
return verifyNotificationPermission(); return verifyNotificationPermission();
} }
else if (s.equals(Manifest.permission.BIND_DEVICE_ADMIN))
{
return haveDeviceAdmin();
}
else else
{ {
int res = context.checkCallingOrSelfPermission(s); int res = context.checkCallingOrSelfPermission(s);
@ -292,6 +298,33 @@ public class ActivityPermissions extends Activity
return true; return true;
} }
public static boolean haveDeviceAdmin()
{
DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
// ComponentName compName = new ComponentName(ActivityPermissions.getInstance(), DeviceAdmin.class ) ;
ComponentName compName = new ComponentName(Miscellaneous.getAnyContext(), DeviceAdmin.class) ;
boolean active = deviceManger.isAdminActive(compName);
return active;
}
public static void requestDeviceAdmin()
{
if(!haveDeviceAdmin())
{
// deviceManger.removeActiveAdmin(compName);
// }
// else
// {
DevicePolicyManager deviceManger = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName compName = new ComponentName(ActivityPermissions.getInstance(), DeviceAdmin.class) ;
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN );
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN , compName );
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION , Miscellaneous.getAnyContext().getResources().getString(R.string.deviceAdminNote));
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsDeviceAdmin);
}
}
public static String[] getRequiredPermissions(boolean onlyGeneral) public static String[] getRequiredPermissions(boolean onlyGeneral)
{ {
ArrayList<String> requiredPermissions = new ArrayList<String>(); ArrayList<String> requiredPermissions = new ArrayList<String>();
@ -531,6 +564,12 @@ public class ActivityPermissions extends Activity
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0 // https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions); // addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break; break;
case setBluetoothTethering:
//addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case setWifi: case setWifi:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0 // https://stackoverflow.com/questions/32185628/connectivitymanager-requestnetwork-in-android-6-0
@ -557,9 +596,9 @@ public class ActivityPermissions extends Activity
if( if(
action.getParameter2().contains(Actions.wireguard_tunnel_up) action.getParameter2().contains(Actions.wireguard_tunnel_up)
|| ||
action.getParameter2().contains(Actions.wireguard_tunnel_down) action.getParameter2().contains(Actions.wireguard_tunnel_down)
|| ||
action.getParameter2().contains(Actions.wireguard_tunnel_refresh) action.getParameter2().contains(Actions.wireguard_tunnel_refresh)
) )
addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions); addToArrayListUnique(ActivityPermissions.permissionNameWireguard, requiredPermissions);
// if( // if(
@ -587,40 +626,37 @@ public class ActivityPermissions extends Activity
break; break;
case turnUsbTetheringOff: case turnUsbTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break; break;
case turnUsbTetheringOn: case turnUsbTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break; break;
case turnWifiOff: case turnWifiOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break; break;
case turnWifiOn: case turnWifiOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break; break;
case turnWifiTetheringOff: case turnWifiTetheringOff:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break; break;
case turnWifiTetheringOn: case turnWifiTetheringOn:
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions); addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
// addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions); addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break; break;
case waitBeforeNextAction: case waitBeforeNextAction:
break; break;
case wakeupDevice:
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
break;
case playSound: case playSound:
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions); addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
break; break;
case turnScreenOnOrOff:
if(action.getParameter1())
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
else
addToArrayListUnique(Manifest.permission.BIND_DEVICE_ADMIN, requiredPermissions);
break;
default: default:
break; break;
} }
@ -696,13 +732,6 @@ public class ActivityPermissions extends Activity
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.ACCESS_COARSE_LOCATION: case Manifest.permission.ACCESS_COARSE_LOCATION:
// usingElements.add(getResources().getString(R.string.android_permission_ACCESS_COARSE_LOCATION));
usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.ACCESS_FINE_LOCATION: case Manifest.permission.ACCESS_FINE_LOCATION:
usingElements.add(getResources().getString(R.string.manageLocations)); usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest)) for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
@ -759,14 +788,6 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection)) for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
/*case "android.permission.BATTERY_STATS":
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.batteryLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.charging))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;*/
case Manifest.permission.BLUETOOTH_ADMIN: case Manifest.permission.BLUETOOTH_ADMIN:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection)) for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
@ -834,6 +855,10 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.playSound)) for(String ruleName : getRulesUsing(Action.Action_Enum.playSound))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName)); usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break; break;
case Manifest.permission.BIND_DEVICE_ADMIN:
for(String ruleName : getRulesUsing(Action.Action_Enum.turnScreenOnOrOff))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
} }
return usingElements; return usingElements;
@ -860,6 +885,13 @@ public class ActivityPermissions extends Activity
requestPermissions(cachedPermissionsToRequest, true); requestPermissions(cachedPermissionsToRequest, true);
} }
} }
if (requestCode == requestCodeForPermissionsDeviceAdmin)
{
NotificationManager mNotificationManager = (NotificationManager) ActivityPermissions.this.getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager.isNotificationPolicyAccessGranted())
requestPermissions(cachedPermissionsToRequest, true);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{ {
@ -923,12 +955,18 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsWriteSettings); startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
return; return;
} }
if (s.equalsIgnoreCase(Manifest.permission.BIND_DEVICE_ADMIN))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestDeviceAdmin();
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY)) else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
{ {
requiredPermissions.remove(s); requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions; cachedPermissionsToRequest = requiredPermissions;
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS); Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
// intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy); startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
return; return;
} }
@ -968,7 +1006,7 @@ public class ActivityPermissions extends Activity
{ {
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS) if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
&& &&
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()) Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
) )
{ {
requiredPermissions.remove(Manifest.permission.PROCESS_OUTGOING_CALLS); requiredPermissions.remove(Manifest.permission.PROCESS_OUTGOING_CALLS);
@ -978,8 +1016,6 @@ public class ActivityPermissions extends Activity
if(requiredPermissions.contains(Manifest.permission.SEND_SMS)) if(requiredPermissions.contains(Manifest.permission.SEND_SMS))
{ {
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS) if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
// &&
// Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
) )
{ {
requiredPermissions.remove(Manifest.permission.SEND_SMS); requiredPermissions.remove(Manifest.permission.SEND_SMS);
@ -996,11 +1032,8 @@ public class ActivityPermissions extends Activity
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2); Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
// Toast.makeText(ActivityPermissions.this, "Requesting permissions. Amount: " + String.valueOf(requiredPermissions.size()), Toast.LENGTH_LONG).show();
if(requiredPermissions.size() > 0) if(requiredPermissions.size() > 0)
requestPermissions(requiredPermissions.toArray(new String[requiredPermissions.size()]), requestCodeForPermissions); requestPermissions(requiredPermissions.toArray(new String[requiredPermissions.size()]), requestCodeForPermissions);
// else
// Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.permissionsRequiredNotAvailable), ActivityPermissions.this).show();
} }
else else
setHaveAllPermissions(); setHaveAllPermissions();
@ -1018,17 +1051,11 @@ public class ActivityPermissions extends Activity
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{ {
Miscellaneous.logEvent("i", "onRequestPermissionsResult()", "onRequestPermissionsResult()", 3); Miscellaneous.logEvent("i", "onRequestPermissionsResult()", "onRequestPermissionsResult()", 3);
// Toast.makeText(ActivityPermissions.this, "onRequestPermissionsResult()", Toast.LENGTH_LONG).show();
// ArrayList<String> disabledFeatures = new ArrayList<String>();
ArrayList<String> deniedPermissions = new ArrayList<String>(); ArrayList<String> deniedPermissions = new ArrayList<String>();
if (requestCode == requestCodeForPermissions) if (requestCode == requestCodeForPermissions)
{ {
/*ArrayList<String> affectedGeneralList = new ArrayList<String>();
ArrayList<String> affectedTriggersList = new ArrayList<String>();
ArrayList<String> affectedActionList = new ArrayList<String>();*/
for (int i=0; i < grantResults.length; i++) for (int i=0; i < grantResults.length; i++)
{ {
if(permissions[i].equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[i] == PackageManager.PERMISSION_GRANTED) if(permissions[i].equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
@ -1088,8 +1115,8 @@ public class ActivityPermissions extends Activity
if(deniedPermissions.size() > 0) if(deniedPermissions.size() > 0)
{ {
/* /*
The user denied certain permissions. With the exception of write-storage we need to live with that The user denied certain permissions. We need to live with that and simply disable
and simply disable features while keeping the notification alive. The user may dismiss it anyway. features while keeping the notification alive. The user may dismiss it anyway.
*/ */
Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(", ", deniedPermissions), 3); Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(", ", deniedPermissions), 3);
@ -1314,10 +1341,7 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("setWifiTethering", Manifest.permission.WRITE_SETTINGS); mapActionPermissions.put("setWifiTethering", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setWifiTethering", Manifest.permission.CHANGE_NETWORK_STATE); mapActionPermissions.put("setWifiTethering", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setWifiTethering", Manifest.permission.ACCESS_NETWORK_STATE); mapActionPermissions.put("setWifiTethering", Manifest.permission.ACCESS_NETWORK_STATE);
// mapActionPermissions.put("speakText", Manifest.permission.ACCESS_NOTIFICATION_POLICY);
// mapActionPermissions.put("startOtherActivity", "");
mapActionPermissions.put("triggerUrl", Manifest.permission.INTERNET); mapActionPermissions.put("triggerUrl", Manifest.permission.INTERNET);
// Hier müßte ein Hinweis kommen, daß nur die Variablen verwendet werden können, für die es Rechte gibt.
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH_ADMIN); mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH_ADMIN);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH); mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.ACCESS_NETWORK_STATE); mapActionPermissions.put("turnBluetoothOff", Manifest.permission.ACCESS_NETWORK_STATE);
@ -1347,209 +1371,6 @@ public class ActivityPermissions extends Activity
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK); mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK);
} }
/*
<string name="android.permission.SEND_SMS"></string>
<string name="android.permission.SEND_SMS_NO_CONFIRMATION"></string>
<string name="android.permission.RECEIVE_SMS"></string>
<string name="android.permission.RECEIVE_MMS"></string>
<string name="android.permission.RECEIVE_EMERGENCY_BROADCAST"></string>
<string name="android.permission.READ_CELL_BROADCASTS"></string>
<string name="android.permission.READ_SMS"></string>
<string name="android.permission.WRITE_SMS"></string>
<string name="android.permission.RECEIVE_WAP_PUSH"></string>
<string name="android.permission.READ_CONTACTS"></string>
<string name="android.permission.WRITE_CONTACTS"></string>
<string name="android.permission.BIND_DIRECTORY_SEARCH"></string>
<string name="android.permission.READ_CALL_LOG"></string>
<string name="android.permission.WRITE_CALL_LOG"></string>
<string name="android.permission.READ_SOCIAL_STREAM"></string>
<string name="android.permission.WRITE_SOCIAL_STREAM"></string>
<string name="android.permission.READ_PROFILE"></string>
<string name="android.permission.WRITE_PROFILE"></string>
<string name="android.permission.READ_CALENDAR"></string>
<string name="android.permission.WRITE_CALENDAR"></string>
<string name="android.permission.READ_USER_DICTIONARY"></string>
<string name="android.permission.WRITE_USER_DICTIONARY"></string>
<string name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"></string>
<string name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"></string>
<string name="com.android.alarm.permission.SET_ALARM"></string>
<string name="com.android.voicemail.permission.ADD_VOICEMAIL"></string>
<string name="android.permission.ACCESS_FINE_LOCATION"></string>
<string name="android.permission.ACCESS_COARSE_LOCATION"></string>
<string name="android.permission.ACCESS_MOCK_LOCATION"></string>
<string name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></string>
<string name="android.permission.INSTALL_LOCATION_PROVIDER"></string>
<string name="android.permission.INTERNET"></string>
<string name="android.permission.ACCESS_NETWORK_STATE"></string>
<string name="android.permission.ACCESS_WIFI_STATE"></string>
<string name="android.permission.CHANGE_WIFI_STATE"></string>
<string name="android.permission.ACCESS_WIMAX_STATE"></string>
<string name="android.permission.CHANGE_WIMAX_STATE"></string>
<string name="android.permission.BLUETOOTH"></string>
<string name="android.permission.BLUETOOTH_ADMIN"></string>
<string name="android.permission.BLUETOOTH_STACK"></string>
<string name="android.permission.NFC"></string>
<string name="android.permission.CONNECTIVITY_INTERNAL"></string>
<string name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"></string>
<string name="android.permission.GET_ACCOUNTS"></string>
<string name="android.permission.AUTHENTICATE_ACCOUNTS"></string>
<string name="android.permission.USE_CREDENTIALS"></string>
<string name="android.permission.MANAGE_ACCOUNTS"></string>
<string name="android.permission.ACCOUNT_MANAGER"></string>
<string name="android.permission.CHANGE_WIFI_MULTICAST_STATE"></string>
<string name="android.permission.VIBRATE"></string>
<string name="android.permission.FLASHLIGHT"></string>
<string name="android.permission.WAKE_LOCK"></string>
<string name="android.permission.MODIFY_AUDIO_SETTINGS"></string>
<string name="android.permission.MANAGE_USB"></string>
<string name="android.permission.ACCESS_MTP"></string>
<string name="android.permission.HARDWARE_TEST"></string>
<string name="android.permission.NET_ADMIN"></string>
<string name="android.permission.REMOTE_AUDIO_PLAYBACK"></string>
<string name="android.permission.RECORD_AUDIO"></string>
<string name="android.permission.CAMERA"></string>
<string name="android.permission.PROCESS_OUTGOING_CALLS"></string>
<string name="android.permission.MODIFY_PHONE_STATE"></string>
<string name="android.permission.READ_PHONE_STATE"></string>
<string name="android.permission.READ_PRIVILEGED_PHONE_STATE"></string>
<string name="android.permission.CALL_PHONE"></string>
<string name="android.permission.USE_SIP"></string>
<string name="android.permission.READ_EXTERNAL_STORAGE"></string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE"></string>
<string name="android.permission.WRITE_MEDIA_STORAGE"></string>
<string name="android.permission.DISABLE_KEYGUARD"></string>
<string name="android.permission.GET_TASKS"></string>
<string name="android.permission.INTERACT_ACROSS_USERS"></string>
<string name="android.permission.INTERACT_ACROSS_USERS_FULL"></string>
<string name="android.permission.MANAGE_USERS"></string>
<string name="android.permission.GET_DETAILED_TASKS"></string>
<string name="android.permission.REORDER_TASKS"></string>
<string name="android.permission.REMOVE_TASKS"></string>
<string name="android.permission.START_ANY_ACTIVITY"></string>
<string name="android.permission.RESTART_PACKAGES"></string>
<string name="android.permission.KILL_BACKGROUND_PROCESSES"></string>
<string name="android.permission.SYSTEM_ALERT_WINDOW"></string>
<string name="android.permission.SET_WALLPAPER"></string>
<string name="android.permission.SET_WALLPAPER_HINTS"></string>
<string name="android.permission.SET_TIME"></string>
<string name="android.permission.SET_TIME_ZONE"></string>
<string name="android.permission.EXPAND_STATUS_BAR"></string>
<string name="android.permission.READ_SYNC_SETTINGS"></string>
<string name="android.permission.WRITE_SYNC_SETTINGS"></string>
<string name="android.permission.READ_SYNC_STATS"></string>
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
<string name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE"></string>
<string name="android.permission.CHANGE_CONFIGURATION"></string>
<string name="android.permission.WRITE_SETTINGS"></string>
<string name="android.permission.WRITE_GSERVICES"></string>
<string name="android.permission.SET_SCREEN_COMPATIBILITY"></string>
<string name="android.permission.CHANGE_CONFIGURATION"></string>
<string name="android.permission.FORCE_STOP_PACKAGES"></string>
<string name="android.permission.RETRIEVE_WINDOW_CONTENT"></string>
<string name="android.permission.SET_ANIMATION_SCALE"></string>
<string name="android.permission.PERSISTENT_ACTIVITY"></string>
<string name="android.permission.GET_PACKAGE_SIZE"></string>
<string name="android.permission.SET_PREFERRED_APPLICATIONS"></string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED"></string>
<string name="android.permission.BROADCAST_STICKY"></string>
<string name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></string>
<string name="android.permission.MOUNT_FORMAT_FILESYSTEMS"></string>
<string name="android.permission.ASEC_ACCESS"></string>
<string name="android.permission.ASEC_CREATE"></string>
<string name="android.permission.ASEC_DESTROY"></string>
<string name="android.permission.ASEC_MOUNT_UNMOUNT"></string>
<string name="android.permission.ASEC_RENAME"></string>
<string name="android.permission.WRITE_APN_SETTINGS"></string>
<string name="android.permission.SUBSCRIBED_FEEDS_READ"></string>
<string name="android.permission.SUBSCRIBED_FEEDS_WRITE"></string>
<string name="android.permission.CHANGE_NETWORK_STATE"></string>
<string name="android.permission.CLEAR_APP_CACHE"></string>
<string name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"></string>
<string name="android.permission.WRITE_SECURE_SETTINGS"></string>
<string name="android.permission.DUMP"></string>
<string name="android.permission.READ_LOGS"></string>
<string name="android.permission.SET_DEBUG_APP"></string>
<string name="android.permission.SET_PROCESS_LIMIT"></string>
<string name="android.permission.SET_ALWAYS_FINISH"></string>
<string name="android.permission.SIGNAL_PERSISTENT_PROCESSES"></string>
<string name="android.permission.DIAGNOSTIC"></string>
<string name="android.permission.STATUS_BAR"></string>
<string name="android.permission.STATUS_BAR_SERVICE"></string>
<string name="android.permission.FORCE_BACK"></string>
<string name="android.permission.UPDATE_DEVICE_STATS"></string>
<string name="android.permission.INTERNAL_SYSTEM_WINDOW"></string>
<string name="android.permission.MANAGE_APP_TOKENS"></string>
<string name="android.permission.FREEZE_SCREEN"></string>
<string name="android.permission.INJECT_EVENTS"></string>
<string name="android.permission.FILTER_EVENTS"></string>
<string name="android.permission.RETRIEVE_WINDOW_INFO"></string>
<string name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"></string>
<string name="android.permission.MAGNIFY_DISPLAY"></string>
<string name="android.permission.SET_ACTIVITY_WATCHER"></string>
<string name="android.permission.SHUTDOWN"></string>
<string name="android.permission.STOP_APP_SWITCHES"></string>
<string name="android.permission.READ_INPUT_STATE"></string>
<string name="android.permission.BIND_INPUT_METHOD"></string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE"></string>
<string name="android.permission.BIND_TEXT_SERVICE"></string>
<string name="android.permission.BIND_VPN_SERVICE"></string>
<string name="android.permission.BIND_WALLPAPER"></string>
<string name="android.permission.BIND_DEVICE_ADMIN"></string>
<string name="android.permission.SET_ORIENTATION"></string>
<string name="android.permission.SET_POINTER_SPEED"></string>
<string name="android.permission.SET_KEYBOARD_LAYOUT"></string>
<string name="android.permission.INSTALL_PACKAGES"></string>
<string name="android.permission.CLEAR_APP_USER_DATA"></string>
<string name="android.permission.DELETE_CACHE_FILES"></string>
<string name="android.permission.DELETE_PACKAGES"></string>
<string name="android.permission.MOVE_PACKAGE"></string>
<string name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"></string>
<string name="android.permission.GRANT_REVOKE_PERMISSIONS"></string>
<string name="android.permission.ACCESS_SURFACE_FLINGER"></string>
<string name="android.permission.READ_FRAME_BUFFER"></string>
<string name="android.permission.CONFIGURE_WIFI_DISPLAY"></string>
<string name="android.permission.CONTROL_WIFI_DISPLAY"></string>
<string name="android.permission.BRICK"></string>
<string name="android.permission.REBOOT"></string>
<string name="android.permission.DEVICE_POWER"></string>
<string name="android.permission.NET_TUNNELING"></string>
<string name="android.permission.FACTORY_TEST"></string>
<string name="android.permission.BROADCAST_PACKAGE_REMOVED"></string>
<string name="android.permission.BROADCAST_SMS"></string>
<string name="android.permission.BROADCAST_WAP_PUSH"></string>
<string name="android.permission.MASTER_CLEAR"></string>
<string name="android.permission.CALL_PRIVILEGED"></string>
<string name="android.permission.PERFORM_CDMA_PROVISIONING"></string>
<string name="android.permission.CONTROL_LOCATION_UPDATES"></string>
<string name="android.permission.ACCESS_CHECKIN_PROPERTIES"></string>
<string name="android.permission.PACKAGE_USAGE_STATS"></string>
<string name="android.permission.BATTERY_STATS"></string>
<string name="android.permission.BACKUP"></string>
<string name="android.permission.CONFIRM_FULL_BACKUP"></string>
<string name="android.permission.BIND_REMOTEVIEWS"></string>
<string name="android.permission.BIND_APPWIDGET"></string>
<string name="android.permission.BIND_KEYGUARD_APPWIDGET"></string>
<string name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"></string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"></string>
<string name="android.permission.GLOBAL_SEARCH"></string>
<string name="android.permission.GLOBAL_SEARCH_CONTROL"></string>
<string name="android.permission.SET_WALLPAPER_COMPONENT"></string>
<string name="android.permission.READ_DREAM_STATE"></string>
<string name="android.permission.WRITE_DREAM_STATE"></string>
<string name="android.permission.ACCESS_CACHE_FILESYSTEM"></string>
<string name="android.permission.COPY_PROTECTED_DATA"></string>
<string name="android.permission.CRYPT_KEEPER"></string>
<string name="android.permission.READ_NETWORK_USAGE_HISTORY"></string>
<string name="android.permission.MANAGE_NETWORK_POLICY"></string>
<string name="android.permission.MODIFY_NETWORK_ACCOUNTING"></string>
<string name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"></string>
<string name="android.permission.PACKAGE_VERIFICATION_AGENT"></string>
<string name="android.permission.BIND_PACKAGE_VERIFIER"></string>
<string name="android.permission.SERIAL_PORT"></string>
<string name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"></string>
<string name="android.permission.UPDATE_LOCK"></string>
*/
public static boolean isPermissionDeclaratedInManifest(Context context, String permission) public static boolean isPermissionDeclaratedInManifest(Context context, String permission)
{ {
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
@ -1568,12 +1389,11 @@ public class ActivityPermissions extends Activity
ArrayList<String> requestedPermissionsArrayList = new ArrayList<String>(); ArrayList<String> requestedPermissionsArrayList = new ArrayList<String>();
requestedPermissionsArrayList.addAll(requestedPermissionsList); requestedPermissionsArrayList.addAll(requestedPermissionsList);
return (requestedPermissionsArrayList.contains(permission)); return (requestedPermissionsArrayList.contains(permission));
// Log.i(ExConsts.TAG, ""+requestedPermissionsArrayList);
} }
} }
catch (PackageManager.NameNotFoundException e) catch (PackageManager.NameNotFoundException e)
{ {
e.printStackTrace(); Miscellaneous.logEvent("w", "ActivityPermissions", Log.getStackTraceString(e), 2);
} }
return false; return false;

View File

@ -30,14 +30,14 @@ public class ActivityVolumeTest extends Activity
instance = this; instance = this;
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_volume_test); setContentView(R.layout.activity_volume_calibration);
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume); tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
etReferenceValue = (EditText)findViewById(R.id.etReferenceValue); etReferenceValue = (EditText)findViewById(R.id.etReferenceValue);
sbReferenceValue = (SeekBar)findViewById(R.id.sbReferenceValue); sbReferenceValue = (SeekBar)findViewById(R.id.sbReferenceValue);
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeTestExplanation); tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeCalibrationExplanation);
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeTesterExplanation), String.valueOf(volumeRefreshInterval))); tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeCalibrationExplanation), String.valueOf(volumeRefreshInterval)));
etReferenceValue.setText(String.valueOf(Settings.referenceValueForNoiseLevelMeasurements)); etReferenceValue.setText(String.valueOf(Settings.referenceValueForNoiseLevelMeasurements));

View File

@ -199,6 +199,7 @@ public class AutomationService extends Service implements OnInitListener
if (checkStartupRequirements(this, startAtBoot)) if (checkStartupRequirements(this, startAtBoot))
{ {
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1); Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Miscellaneous.logEvent("i", "Service", ActivityMaintenance.getSystemInfo(), 1);
startUpRoutine(); startUpRoutine();
@ -273,16 +274,7 @@ public class AutomationService extends Service implements OnInitListener
public void applySettingsAndRules() public void applySettingsAndRules()
{ {
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate) checkForTtsEngine();
{
if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this);
}
else
{
if (ttsEngine != null)
ttsEngine.shutdown();
}
startLocationProvider(); startLocationProvider();
ReceiverCoordinator.startAllReceivers(); ReceiverCoordinator.startAllReceivers();
@ -305,7 +297,7 @@ public class AutomationService extends Service implements OnInitListener
public void checkForTtsEngine() public void checkForTtsEngine()
{ {
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate | Rule.isAnyRuleUsing(Action.Action_Enum.speakText)) if (Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate || Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
{ {
if (ttsEngine == null) if (ttsEngine == null)
ttsEngine = new TextToSpeech(this, this); ttsEngine = new TextToSpeech(this, this);
@ -352,12 +344,8 @@ public class AutomationService extends Service implements OnInitListener
if(r.isRuleActive()) if(r.isRuleActive())
{ {
if(!r.haveEnoughPermissions()) if(!r.haveEnoughPermissions())
// for (String permission : ActivityPermissions.getPermissionsForRule(r))
{ {
// if (!ActivityPermissions.havePermission(permission, AutomationService.this))
{ {
// r.setRuleActive(false);
// r.change(AutomationService.this);
if(!displayNotification) if(!displayNotification)
{ {
displayNotification = true; displayNotification = true;
@ -410,10 +398,7 @@ public class AutomationService extends Service implements OnInitListener
public void cancelNotification() public void cancelNotification()
{ {
// stopForeground(false);
NotificationManagerCompat.from(AutomationService.this).cancelAll(); NotificationManagerCompat.from(AutomationService.this).cancelAll();
// NotificationManagerCompat.from(AutomationService.this).cancel(ActivityPermissions.notificationIdPermissions);
// NotificationManagerCompat.from(AutomationService.this).cancel(AutomationService.notificationIdRestrictions);
} }
protected void checkForMissingBackgroundLocationPermission() protected void checkForMissingBackgroundLocationPermission()
@ -450,7 +435,6 @@ public class AutomationService extends Service implements OnInitListener
private void stopRoutine() private void stopRoutine()
{ {
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3); Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
// Log.i("STOP", "Stopping");
try try
{ {
myLocationProvider.stopLocationService(); myLocationProvider.stopLocationService();
@ -479,7 +463,6 @@ public class AutomationService extends Service implements OnInitListener
builder.setWhen(System.currentTimeMillis()); builder.setWhen(System.currentTimeMillis());
builder.setContentIntent(myPendingIntent); builder.setContentIntent(myPendingIntent);
// Notification defaultNotification = new Notification();
Notification defaultNotification = builder.build(); Notification defaultNotification = builder.build();
defaultNotification.icon = R.drawable.ic_launcher; defaultNotification.icon = R.drawable.ic_launcher;
@ -497,31 +480,6 @@ public class AutomationService extends Service implements OnInitListener
// defaultNotification.ledOffMS = 1500; // defaultNotification.ledOffMS = 1500;
return builder; return builder;
/*NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(AutomationService.getInstance());
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(Notification.CATEGORY_EVENT);
builder.setWhen(System.currentTimeMillis());
builder.setContentTitle("Automation");
builder.setSmallIcon(R.drawable.ic_launcher);
// builder.setContentText(textToDisplay);
// builder.setSmallIcon(icon);
// builder.setContentIntent(pendingIntent);
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel("notify_001", "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
return builder;*/
} }
protected static NotificationCompat.Builder createDefaultNotificationBuilder() protected static NotificationCompat.Builder createDefaultNotificationBuilder()
@ -571,79 +529,68 @@ public class AutomationService extends Service implements OnInitListener
if(instance != null) if(instance != null)
{ {
// if(Settings.showIconWhenServiceIsRunning) Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
// {
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4); String bodyText="";
String lastRuleString = "";
String bodyText="";
String lastRuleString = ""; if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
{
try
{
PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
}
catch(NullPointerException e)
{
if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
}
}
try try
{ {
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString(); PointOfInterest activePoi = PointOfInterest.getActivePoi();
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
}
} }
catch(Exception e) catch(NullPointerException e)
{ {
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a."; if(
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
&&
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
)
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
else
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
} }
}
String textToDisplay = bodyText + " " + lastRuleString; try
// if(Build.VERSION.SDK_INT < 11) {
// { lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
// myNotification.setLatestEventInfo(instance, "Automation", textToDisplay, myPendingIntent); }
// } catch(Exception e)
// else {
// { lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
if(notificationBuilder == null) }
notificationBuilder = createDefaultNotificationBuilder();
notificationBuilder.setContentText(textToDisplay); String textToDisplay = bodyText + " " + lastRuleString;
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
myNotification = notificationBuilder.build(); if(notificationBuilder == null)
myNotification.defaults = 0; notificationBuilder = createDefaultNotificationBuilder();
// }
notificationBuilder.setContentText(textToDisplay);
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
myNotification = notificationBuilder.build();
myNotification.defaults = 0;
// NotificationManager notificationManager = (NotificationManager) instance.getSystemService(NOTIFICATION_SERVICE); // NotificationManager notificationManager = (NotificationManager) instance.getSystemService(NOTIFICATION_SERVICE);
// hide the notification after its selected // hide the notification after its selected
// myNotification.flags |= Notification.FLAG_AUTO_CANCEL; // myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
myNotification.flags |= Notification.FLAG_NO_CLEAR; myNotification.flags |= Notification.FLAG_NO_CLEAR;
// notificationManager.notify(notificationId, myNotification); // notificationManager.notify(notificationId, myNotification);
instance.startForeground(notificationId, myNotification); instance.startForeground(notificationId, myNotification);
// }
// else
// instance.startForeground(notificationId, null); // do not show icon in task bar
} }
} }
@ -667,18 +614,18 @@ public class AutomationService extends Service implements OnInitListener
**/ **/
public void speak(String text, boolean force) public void speak(String text, boolean force)
{ {
if(text.length() > 0 && (force | Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate)) if(text.length() > 0 && (force || Settings.useTextToSpeechOnNormal || Settings.useTextToSpeechOnSilent || Settings.useTextToSpeechOnVibrate))
{ {
AudioManager myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); AudioManager myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int mode = myAudioManager.getRingerMode(); int mode = myAudioManager.getRingerMode();
if( if(
(mode == AudioManager.RINGER_MODE_NORMAL && Settings.useTextToSpeechOnNormal) (mode == AudioManager.RINGER_MODE_NORMAL && Settings.useTextToSpeechOnNormal)
| ||
(mode == AudioManager.RINGER_MODE_VIBRATE && Settings.useTextToSpeechOnVibrate) (mode == AudioManager.RINGER_MODE_VIBRATE && Settings.useTextToSpeechOnVibrate)
| ||
(mode == AudioManager.RINGER_MODE_SILENT && Settings.useTextToSpeechOnSilent) (mode == AudioManager.RINGER_MODE_SILENT && Settings.useTextToSpeechOnSilent)
| ||
force force
) )
{ {
@ -708,12 +655,12 @@ public class AutomationService extends Service implements OnInitListener
{} {}
} }
} }
Miscellaneous.logEvent("i", "TextToSpeech", "Speaking " + text + " in language " + ttsEngine.getLanguage().toLanguageTag(), 3);
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null); this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
} }
catch(Exception e) catch(Exception e)
{ {
Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3); Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3);
e.printStackTrace();
} }
} }
} }
@ -726,31 +673,6 @@ public class AutomationService extends Service implements OnInitListener
return false; return false;
else else
return true; return true;
// boolean isActivityFound = false;
// ActivityManager activityManager = (ActivityManager)context.getSystemService (Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
// isActivityFound = false;
// for (int i = 0; i < activitys.size(); i++)
// {
// if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.jens.automation/com.jens.automation.ActivityMainScreen}"))
// {
// isActivityFound = true;
// }
// }
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity running status: " + String.valueOf(isActivityFound), 5);
// return isActivityFound;
// ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
//
// for (RunningTaskInfo task : tasks)
// {
// if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
// return true;
// }
//
// return false;
} }
public static boolean isMyServiceRunning(Context context) public static boolean isMyServiceRunning(Context context)
@ -762,7 +684,6 @@ public class AutomationService extends Service implements OnInitListener
{ {
if(AutomationService.class.getName().equals(service.service.getClassName())) if(AutomationService.class.getName().equals(service.service.getClassName()))
{ {
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
return true; return true;
} }
} }
@ -771,9 +692,8 @@ public class AutomationService extends Service implements OnInitListener
{ {
if(Log.getStackTraceString(e).contains("activate")) // Means that a poi has been activated/deactivated. Service is running. if(Log.getStackTraceString(e).contains("activate")) // Means that a poi has been activated/deactivated. Service is running.
return true; return true;
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
} }
return false; return false;
} }
} }

View File

@ -0,0 +1,22 @@
package com.jens.automation2;
import android.app.admin.DeviceAdminReceiver;
import android.content.Context;
import android.content.Intent;
public class DeviceAdmin extends DeviceAdminReceiver
{
@Override
public void onEnabled (Context context , Intent intent)
{
super.onEnabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Got permission BIND_DEVICE_ADMIN.", 3);
}
@Override
public void onDisabled (Context context , Intent intent)
{
super.onDisabled(context , intent) ;
Miscellaneous.logEvent("i", "DeviceAdmin", "Permission BIND_DEVICE_ADMIN taken.", 3);
}
}

View File

@ -14,6 +14,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor; import android.database.Cursor;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
@ -77,6 +78,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.sql.Time; import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -541,6 +544,22 @@ public class Miscellaneous extends Service
return null; return null;
} }
public static boolean isDarkModeEnabled(Context context)
{
int mode = context.getResources().getConfiguration().uiMode;
switch(mode)
{
case 33:
case Configuration.UI_MODE_NIGHT_YES:
return true;
case 17:
case Configuration.UI_MODE_NIGHT_NO:
case Configuration.UI_MODE_NIGHT_UNDEFINED:
default:
return false;
}
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
public static String replaceVariablesInText(String source, Context context) throws Exception public static String replaceVariablesInText(String source, Context context) throws Exception
@ -1133,11 +1152,11 @@ public class Miscellaneous extends Service
} }
catch (IllegalAccessException e) catch (IllegalAccessException e)
{ {
e.printStackTrace(); Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
} }
catch (InvocationTargetException e) catch (InvocationTargetException e)
{ {
e.printStackTrace(); Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
} }
return result; return result;
@ -1532,4 +1551,21 @@ public class Miscellaneous extends Service
else*/ else*/
return PhoneNumberUtils.compare(number1, number2); return PhoneNumberUtils.compare(number1, number2);
} }
public static String formatDate(Date input)
{
DateFormat sdf = null;
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
if(sdf == null && Settings.dateFormat != null)
sdf = new SimpleDateFormat(Settings.dateFormat);
String formattedDate;
if(sdf != null)
formattedDate = sdf.format(input);
else
formattedDate = fallBackFormatter.format(input);
return formattedDate;
}
} }

View File

@ -23,7 +23,7 @@ import java.util.Map;
public class News public class News
{ {
Calendar publishDate; Calendar publishDate;
String applicablePlattform; String applicablePlatform;
Map<String,NewsTranslation> translations = new HashMap<>(); Map<String,NewsTranslation> translations = new HashMap<>();
public static class NewsTranslation public static class NewsTranslation
@ -151,9 +151,9 @@ public class News
String publishDateString = neEl.getElementsByTagName("publishDate").item(0).getTextContent(); String publishDateString = neEl.getElementsByTagName("publishDate").item(0).getTextContent();
newsEntry.setPublishDate(Miscellaneous.calendarFromLong(Long.parseLong(publishDateString) * 1000)); newsEntry.setPublishDate(Miscellaneous.calendarFromLong(Long.parseLong(publishDateString) * 1000));
newsEntry.setApplicablePlattform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent()); newsEntry.setApplicablePlatform(neEl.getElementsByTagName("applicablePlattforms").item(0).getTextContent());
if(newsEntry.getApplicablePlattform().equalsIgnoreCase("all") || newsEntry.getApplicablePlattform().equalsIgnoreCase(BuildConfig.FLAVOR)) if(newsEntry.getApplicablePlatform().equalsIgnoreCase("all") || newsEntry.getApplicablePlatform().equalsIgnoreCase(BuildConfig.FLAVOR))
returnList.add(newsEntry); returnList.add(newsEntry);
} }
} }
@ -199,14 +199,14 @@ public class News
this.publishDate = publishDate; this.publishDate = publishDate;
} }
public String getApplicablePlattform() public String getApplicablePlatform()
{ {
return applicablePlattform; return applicablePlatform;
} }
public void setApplicablePlattform(String applicablePlattform) public void setApplicablePlatform(String applicablePlatform)
{ {
this.applicablePlattform = applicablePlattform; this.applicablePlatform = applicablePlatform;
} }
@NonNull @NonNull

View File

@ -252,8 +252,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService); Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2); Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, true); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0) if(ruleCandidates.size()==0)
{ {
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2); Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@ -264,18 +265,22 @@ public class PointOfInterest implements Comparable<PointOfInterest>
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions()) if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{ {
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2); Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false); ruleCandidates.get(i).activate(parentService, false);
} }
} }
} }
Miscellaneous.logEvent("i", "POI", "Reached POI " + this.getName() + ". Done checking POI rules.", 2);
parentService.updateNotification(); parentService.updateNotification();
ActivityMainScreen.updateMainScreen(); ActivityMainScreen.updateMainScreen();
} }
} }
public void deactivate(AutomationService parentService) public void deactivate(AutomationService parentService)
{ {
if(this.isActivated()) if(this.isActivated())
@ -285,8 +290,9 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Settings.writeSettings(parentService); Settings.writeSettings(parentService);
Miscellaneous.logEvent("i", "POI", "Left POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2); Miscellaneous.logEvent("i", "POI", "Left POI " + this.getName() + ". Checking if there's a rule that applies to that.", 2);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this, false); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.pointOfInterest);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPoi(this);
if(ruleCandidates.size()==0) if(ruleCandidates.size()==0)
{ {
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2); Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " not found in ANY rule.", 2);
@ -296,7 +302,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2); Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(parentService)) if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(parentService))
{ {
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2); Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2);
ruleCandidates.get(i).activate(parentService, false); ruleCandidates.get(i).activate(parentService, false);

View File

@ -5,11 +5,12 @@ import android.util.Log;
import com.jens.automation2.location.CellLocationChangedReceiver; import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.WifiBroadcastReceiver; import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.AlarmListener; import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.AutomationListenerInterface; import com.jens.automation2.receivers.AutomationListenerInterface;
import com.jens.automation2.receivers.BatteryReceiver; import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.receivers.BluetoothReceiver; import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver; import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener; import com.jens.automation2.receivers.HeadphoneJackListener;
import com.jens.automation2.receivers.NoiseListener; import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener; import com.jens.automation2.receivers.PhoneStatusListener;
@ -42,10 +43,11 @@ public class ReceiverCoordinator
Class adClass = Class.forName("ActivityDetectionReceiver"); Class adClass = Class.forName("ActivityDetectionReceiver");
allImplementers = new Class[] { allImplementers = new Class[] {
adClass, adClass,
AlarmListener.class, DateTimeListener.class,
BatteryReceiver.class, BatteryReceiver.class,
BluetoothReceiver.class, BluetoothReceiver.class,
ConnectivityReceiver.class, ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class, HeadphoneJackListener.class,
//NfcReceiver.class, //NfcReceiver.class,
NoiseListener.class, NoiseListener.class,
@ -56,13 +58,12 @@ public class ReceiverCoordinator
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {
// e.printStackTrace();
allImplementers = new Class[] { allImplementers = new Class[] {
AlarmListener.class, DateTimeListener.class,
BatteryReceiver.class, BatteryReceiver.class,
BluetoothReceiver.class, BluetoothReceiver.class,
ConnectivityReceiver.class, ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class, HeadphoneJackListener.class,
//NfcReceiver.class, //NfcReceiver.class,
NoiseListener.class, NoiseListener.class,
@ -155,7 +156,7 @@ public class ReceiverCoordinator
BatteryReceiver.startBatteryReceiver(AutomationService.getInstance()); BatteryReceiver.startBatteryReceiver(AutomationService.getInstance());
// startAlarmListener // startAlarmListener
AlarmListener.startAlarmListener(AutomationService.getInstance()); DateTimeListener.startAlarmListener(AutomationService.getInstance());
TimeZoneListener.startTimeZoneListener(AutomationService.getInstance()); TimeZoneListener.startTimeZoneListener(AutomationService.getInstance());
// startNoiseListener // startNoiseListener
@ -166,15 +167,15 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped)) if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
ProcessListener.startProcessListener(AutomationService.getInstance()); ProcessListener.startProcessListener(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
try try
{ {
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath); Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
//startActivityDetectionReceiver //startActivityDetectionReceiver
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection)) if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null); Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
// ActivityDetectionReceiver.startActivityDetectionReceiver();
}
} }
catch(ClassNotFoundException e) catch(ClassNotFoundException e)
{ {
@ -199,15 +200,15 @@ public class ReceiverCoordinator
WifiBroadcastReceiver.stopWifiReceiver(); WifiBroadcastReceiver.stopWifiReceiver();
BatteryReceiver.stopBatteryReceiver(); BatteryReceiver.stopBatteryReceiver();
TimeZoneListener.stopTimeZoneListener(); TimeZoneListener.stopTimeZoneListener();
AlarmListener.stopAlarmListener(AutomationService.getInstance()); DateTimeListener.stopAlarmListener(AutomationService.getInstance());
NoiseListener.stopNoiseListener(); NoiseListener.stopNoiseListener();
ProcessListener.stopProcessListener(AutomationService.getInstance()); ProcessListener.stopProcessListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
try try
{ {
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath); Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null); Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
} }
catch(ClassNotFoundException e) catch(ClassNotFoundException e)
{ {
@ -216,6 +217,7 @@ public class ReceiverCoordinator
BluetoothReceiver.stopBluetoothReceiver(); BluetoothReceiver.stopBluetoothReceiver();
HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance()); HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
} }
catch(Exception e) catch(Exception e)
{ {
@ -350,6 +352,24 @@ public class ReceiverCoordinator
} }
} }
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
{
if(!DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Starting DevicePositionListener because used in a new/changed rule.", 4);
// if(DevicePositionListener.getInstance().haveAllPermission())
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
}
}
else
{
if(DeviceOrientationListener.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "DevicePositionListener", "Shutting down DevicePositionListener because not used in any rule.", 4);
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
}
}
AutomationService.updateNotification(); AutomationService.updateNotification();
} }
} }

View File

@ -56,6 +56,7 @@ public class Settings implements SharedPreferences
public static boolean rememberLastActivePoi; public static boolean rememberLastActivePoi;
public static int locationRingBufferSize; public static int locationRingBufferSize;
public static long timeBetweenProcessMonitorings; public static long timeBetweenProcessMonitorings;
public static long acceptDeviceOrientationSignalEveryX_MilliSeconds;
public static int activityDetectionFrequency; public static int activityDetectionFrequency;
public static int activityDetectionRequiredProbability; public static int activityDetectionRequiredProbability;
public static boolean privacyLocationing; public static boolean privacyLocationing;
@ -113,6 +114,7 @@ public class Settings implements SharedPreferences
protected static final boolean default_rememberLastActivePoi = true; protected static final boolean default_rememberLastActivePoi = true;
protected static final int default_locationRingBufferSize=3; protected static final int default_locationRingBufferSize=3;
protected static final long default_timeBetweenProcessMonitorings = 60; protected static final long default_timeBetweenProcessMonitorings = 60;
protected static final long default_acceptDevicePositionSignalEveryX_MilliSeconds = 1000;
protected static final int default_activityDetectionFrequency = 60; protected static final int default_activityDetectionFrequency = 60;
protected static final int default_activityDetectionRequiredProbability = 75; protected static final int default_activityDetectionRequiredProbability = 75;
protected static final boolean default_privacyLocationing = false; protected static final boolean default_privacyLocationing = false;
@ -236,6 +238,7 @@ public class Settings implements SharedPreferences
lengthOfNoiseLevelMeasurements = Long.parseLong(prefs.getString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements))); lengthOfNoiseLevelMeasurements = Long.parseLong(prefs.getString("lengthOfNoiseLevelMeasurements", String.valueOf(default_lengthOfNoiseLevelMeasurements)));
referenceValueForNoiseLevelMeasurements = Long.parseLong(prefs.getString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements))); referenceValueForNoiseLevelMeasurements = Long.parseLong(prefs.getString("referenceValueForNoiseLevelMeasurements", String.valueOf(default_referenceValueForNoiseLevelMeasurements)));
timeBetweenProcessMonitorings = Long.parseLong(prefs.getString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings))); timeBetweenProcessMonitorings = Long.parseLong(prefs.getString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings)));
acceptDeviceOrientationSignalEveryX_MilliSeconds = Long.parseLong(prefs.getString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds)));
httpAcceptAllCertificates = prefs.getBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates); httpAcceptAllCertificates = prefs.getBoolean("httpAcceptAllCertificates", default_httpAcceptAllCertificates);
httpAttempts = Integer.parseInt(prefs.getString("httpAttempts", String.valueOf(default_httpAttempts))); httpAttempts = Integer.parseInt(prefs.getString("httpAttempts", String.valueOf(default_httpAttempts)));
@ -431,6 +434,9 @@ public class Settings implements SharedPreferences
if(!prefs.contains("timeBetweenProcessMonitorings") | force) if(!prefs.contains("timeBetweenProcessMonitorings") | force)
editor.putString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings)); editor.putString("timeBetweenProcessMonitorings", String.valueOf(default_timeBetweenProcessMonitorings));
if(!prefs.contains("acceptDevicePositionSignalEveryX_MilliSeconds") | force)
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(default_acceptDevicePositionSignalEveryX_MilliSeconds));
if(!prefs.contains("activityDetectionFrequency") | force) if(!prefs.contains("activityDetectionFrequency") | force)
editor.putString("activityDetectionFrequency", String.valueOf(default_activityDetectionFrequency)); editor.putString("activityDetectionFrequency", String.valueOf(default_activityDetectionFrequency));
@ -526,6 +532,7 @@ public class Settings implements SharedPreferences
editor.putString("httpAttemptGap", String.valueOf(httpAttemptGap)); editor.putString("httpAttemptGap", String.valueOf(httpAttemptGap));
editor.putString("locationRingBufferSize", String.valueOf(locationRingBufferSize)); editor.putString("locationRingBufferSize", String.valueOf(locationRingBufferSize));
editor.putString("timeBetweenProcessMonitorings", String.valueOf(timeBetweenProcessMonitorings)); editor.putString("timeBetweenProcessMonitorings", String.valueOf(timeBetweenProcessMonitorings));
editor.putString("acceptDevicePositionSignalEveryX_MilliSeconds", String.valueOf(acceptDeviceOrientationSignalEveryX_MilliSeconds));
editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency)); editor.putString("activityDetectionFrequency", String.valueOf(activityDetectionFrequency));
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability)); editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
editor.putBoolean("privacyLocationing", privacyLocationing); editor.putBoolean("privacyLocationing", privacyLocationing);

View File

@ -6,70 +6,90 @@ import java.util.ArrayList;
public class TimeFrame public class TimeFrame
{ {
// Defines a timeframe // Defines a timeframe
private Time triggerTimeStart; protected Time triggerTimeStart;
private Time triggerTimeStop; protected Time triggerTimeStop;
protected long repetition;
private ArrayList<Integer> dayList = new ArrayList<Integer>(); protected final static String separator = "/";
public ArrayList<Integer> getDayList()
private ArrayList<Integer> dayList = new ArrayList<Integer>();
public ArrayList<Integer> getDayList()
{
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{ {
return dayList;
}
public void setDayList(ArrayList<Integer> dayList)
{
this.dayList = dayList;
}
public void setDayListFromString(String dayListString)
{
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>();
for(char item : dayListCharArray)
{
// Log.i("Parsing", String.valueOf(item)); // Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item))); dayList.add(Integer.parseInt(String.valueOf(item)));
}
} }
}
public Time getTriggerTimeStart()
public Time getTriggerTimeStart() {
{ return triggerTimeStart;
return triggerTimeStart; }
} public void setTriggerTimeStart(Time triggerTimeStart)
public void setTriggerTimeStart(Time triggerTimeStart) {
{ this.triggerTimeStart = triggerTimeStart;
this.triggerTimeStart = triggerTimeStart; }
}
public Time getTriggerTimeStop() public Time getTriggerTimeStop()
{ {
return triggerTimeStop; return triggerTimeStop;
} }
public void setTriggerTimeStop(Time triggerTimeStop) public void setTriggerTimeStop(Time triggerTimeStop)
{ {
this.triggerTimeStop = triggerTimeStop; this.triggerTimeStop = triggerTimeStop;
} }
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2) public long getRepetition()
{ {
this.setTriggerTimeStart(timeStart); return repetition;
this.setTriggerTimeStop(timeEnd); }
this.setDayList(dayList2);
} public void setRepetition(long repetition)
TimeFrame (String fileContent) {
{ this.repetition = repetition;
String[] dateArray = fileContent.split("/"); // example: timestart/timestop/days[int] }
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1])); public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2, long repetition)
this.setDayListFromString(dateArray[2]); {
} this.setTriggerTimeStart(timeStart);
@Override this.setTriggerTimeStop(timeEnd);
public String toString() this.setDayList(dayList2);
{ this.setRepetition(repetition);
String returnString = this.getTriggerTimeStart().toString() + "/" + this.getTriggerTimeStop().toString() + "/"; }
for(Integer oneDay : this.getDayList()) public TimeFrame (String fileContent)
returnString += String.valueOf(oneDay); {
String[] dateArray = fileContent.split(separator); // example: timestart/timestop/days[int]/repetition
return returnString; this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
} this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
} this.setDayListFromString(dateArray[2]);
if(dateArray.length > 3) // may not exist in old config files
this.setRepetition(Long.parseLong(dateArray[3]));
}
@Override
public String toString()
{
String returnString = this.getTriggerTimeStart().toString() + separator + this.getTriggerTimeStop().toString() + separator;
for(Integer oneDay : this.getDayList())
returnString += String.valueOf(oneDay);
returnString += separator + String.valueOf(repetition);
return returnString;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -764,6 +764,8 @@ public class XmlFileInterface
try try
{ {
newRule.setTriggerSet(readTriggerCollection(parser)); newRule.setTriggerSet(readTriggerCollection(parser));
for(Trigger t : newRule.getTriggerSet())
t.setParentRule(newRule);
} }
catch (XmlPullParserException e) catch (XmlPullParserException e)
{ {
@ -779,6 +781,8 @@ public class XmlFileInterface
try try
{ {
newRule.setActionSet(readActionCollection(parser)); newRule.setActionSet(readActionCollection(parser));
for(Action a : newRule.getActionSet())
a.setParentRule(newRule);
} }
catch (XmlPullParserException e) catch (XmlPullParserException e)
{ {
@ -815,7 +819,15 @@ public class XmlFileInterface
// Starts by looking for the entry tag // Starts by looking for the entry tag
if (name.equals("Trigger")) if (name.equals("Trigger"))
{ {
triggerCollection.add(readTrigger(parser)); try
{
triggerCollection.add(readTrigger(parser));
}
catch (IllegalArgumentException | NullPointerException e)
{
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown trigger found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
}
} }
else else
{ {
@ -826,7 +838,6 @@ public class XmlFileInterface
return (triggerCollection); return (triggerCollection);
} }
private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException private static Trigger readTrigger(XmlPullParser parser) throws IOException, XmlPullParserException
{ {
@ -878,7 +889,7 @@ public class XmlFileInterface
{ {
String triggerEventString = readTag(parser, "TriggerEvent"); String triggerEventString = readTag(parser, "TriggerEvent");
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running")) if(triggerEventString.equals("process_started_stopped") || triggerEventString.equals("process_running"))
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped); newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
else else
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString)); newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
@ -928,7 +939,6 @@ public class XmlFileInterface
} }
else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection) else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection)
{ {
// newTrigger.setWifiName(triggerParameter2);
newTrigger.setTriggerParameter2(triggerParameter2); newTrigger.setTriggerParameter2(triggerParameter2);
} }
else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped) else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped)
@ -1051,7 +1061,15 @@ public class XmlFileInterface
// Starts by looking for the entry tag // Starts by looking for the entry tag
if (name.equals("Action")) if (name.equals("Action"))
{ {
actionCollection.add(readAction(parser)); try
{
actionCollection.add(readAction(parser));
}
catch (IllegalArgumentException | NullPointerException e)
{
Miscellaneous.logEvent("e", "XMLFileInterface", "Unknown action found in config file. File was probably created by a newer program version. Details: " + Log.getStackTraceString(e), 1);
Miscellaneous.messageBox(context.getString(R.string.error), context.getString(R.string.elementSkipped), context).show();
}
} }
else else
{ {
@ -1060,7 +1078,6 @@ public class XmlFileInterface
} }
return (actionCollection); return (actionCollection);
} }
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
{ {
@ -1135,7 +1152,14 @@ public class XmlFileInterface
newAction.setAction(Action_Enum.enableScreenRotation); newAction.setAction(Action_Enum.enableScreenRotation);
else if(actionNameString.equals("disableScreenRotation")) else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation); newAction.setAction(Action_Enum.disableScreenRotation);
// *** deprecated else if(actionNameString.equals("disableScreenRotation"))
newAction.setAction(Action_Enum.disableScreenRotation);
else if(actionNameString.equals("wakeupDevice"))
{
newAction.setAction(Action_Enum.turnScreenOnOrOff);
newAction.setParameter1(true);
}
// *** deprecated
else else
newAction.setAction(Action_Enum.valueOf(actionNameString)); newAction.setAction(Action_Enum.valueOf(actionNameString));
@ -1203,6 +1227,18 @@ public class XmlFileInterface
newAction.setParameter1(false); newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
} }
else if(newAction.getAction().equals(Action_Enum.disableScreenRotation))
{
newAction.setAction(Action_Enum.setDisplayRotation);
newAction.setParameter1(false);
readTag(parser, "ActionParameter1"); //read the tag for the parser to head on
}
else if(newAction.getAction().equals(Action_Enum.turnScreenOnOrOff) && newAction.getParameter1())
{
/*
If param1 == true we will keep it because this action used to be of type wakeUpDevice.
*/
}
else else
// exclusion for deprecated types // exclusion for deprecated types
newAction.setParameter1(Boolean.parseBoolean(readTag(parser, "ActionParameter1"))); newAction.setParameter1(Boolean.parseBoolean(readTag(parser, "ActionParameter1")));
@ -1224,7 +1260,6 @@ public class XmlFileInterface
{ {
newAction.setParameter2(tag); newAction.setParameter2(tag);
} }
/* /*
androidx.security.crypto.MasterKey.Builder androidx.security.crypto.MasterKey.Builder
@ -1283,9 +1318,6 @@ public class XmlFileInterface
} }
} }
} }
// Miscellaneous.logEvent("i", "New Rule from file", newPoi.name + "/" + String.valueOf(newPoi.radius) + "/" + String.valueOf(newPoi.location.getLatitude()) + "/" + String.valueOf(newPoi.location.getLongitude()) + "/" + String.valueOf(newPoi.changeWifiState) + "/" + String.valueOf(newPoi.desiredWifiState) + "/" + String.valueOf(newPoi.changeCameraState) + "/" + String.valueOf(newPoi.desiredCameraState) + "/" + String.valueOf(newPoi.changeSoundSetting) + "/" + String.valueOf(newPoi.desiredSoundSetting));
return newAction; return newAction;
} }

View File

@ -369,7 +369,7 @@ public class CellLocationChangedReceiver extends PhoneStateListener
// Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4); // Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because we have no data connection.", 4);
} }
else else
Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4); Miscellaneous.logEvent("w", "cellReceiver", "Wanted to activate CellLocationChangedReceiver, but Wifi-Receiver says not to.", 4);
} }
else else
Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4); Miscellaneous.logEvent("i", "cellReceiver", "Not starting cellLocationListener because Airplane mode is active or SIM_STATE is not ready.", 4);

View File

@ -121,9 +121,9 @@ public class LocationProvider
if ( if (
locationList.size() >= 1 locationList.size() >= 1
&& &&
locationList.get(locationList.size() - 1).getTime() == newLocation.getTime() locationList.get(locationList.size() - 1).getTime() == newLocation.getTime()
&& &&
locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider()) locationList.get(locationList.size() - 1).getProvider().equals(newLocation.getProvider())
) )
{ {
// This is a duplicate update, do not store it // This is a duplicate update, do not store it
@ -198,10 +198,10 @@ public class LocationProvider
setSpeed(currentSpeed); setSpeed(currentSpeed);
// execute matching rules containing speed // execute matching rules containing speed
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesBySpeed(); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.speed);
for (Rule oneRule : ruleCandidates) for (Rule oneRule : ruleCandidates)
{ {
if (oneRule.applies(this.getParentService())) if(oneRule.getsGreenLight(this.getParentService()))
oneRule.activate(getParentService(), false); oneRule.activate(getParentService(), false);
} }
} }

View File

@ -16,6 +16,7 @@ import com.jens.automation2.PointOfInterest;
import com.jens.automation2.R; import com.jens.automation2.R;
import com.jens.automation2.Rule; import com.jens.automation2.Rule;
import com.jens.automation2.Settings; import com.jens.automation2.Settings;
import com.jens.automation2.Trigger;
import java.util.ArrayList; import java.util.ArrayList;
@ -144,10 +145,10 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static void findRules(AutomationService automationServiceInstance) public static void findRules(AutomationService automationServiceInstance)
{ {
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection(); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.wifiConnection);
for(Rule oneRule : ruleCandidates) for(Rule oneRule : ruleCandidates)
{ {
if(oneRule.applies(automationServiceInstance)) if(oneRule.getsGreenLight(automationServiceInstance))
oneRule.activate(automationServiceInstance, false); oneRule.activate(automationServiceInstance, false);
} }
} }

View File

@ -1,301 +0,0 @@
package com.jens.automation2.receivers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class AlarmListener extends BroadcastReceiver implements AutomationListenerInterface
{
private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance;
// private static Intent alarmIntent;
// private static PendingIntent alarmPendingIntent;
private static boolean alarmListenerActive=false;
private static ArrayList<Long> alarmCandidates = new ArrayList<Long>();
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
public static void startAlarmListener(final AutomationService automationServiceRef)
{
AlarmListener.startAlarmListenerInternal(automationServiceRef);
}
public static void stopAlarmListener(Context context)
{
AlarmListener.stopAlarmListenerInternal();
}
public static boolean isAlarmListenerActive()
{
return alarmListenerActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
Date now = new Date();
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
Time passTime = Time.valueOf(timeString);
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
{
if(allRulesWithNowInTimeFrame.get(i).applies(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
}
setAlarms();
}
public static void setAlarms()
{
alarmCandidates.clear();
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
clearAlarms();
int i=0;
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = null;
// SimpleDateFormat sdf2 = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
// if (cal != null)
// {
// calSetWorkingCopyString2 = sdf2.format(cal.getTime());
// }
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
for(Rule oneRule : allRulesWithTimeFrames)
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
if(oneTrigger.getTriggerType() == Trigger_Enum.timeFrame)
{
Calendar calNow, calSet;
Time setTime;
if(oneTrigger.getTriggerParameter())
setTime = oneTrigger.getTimeFrame().getTriggerTimeStart();
else
setTime = oneTrigger.getTimeFrame().getTriggerTimeStop();
calNow = Calendar.getInstance();
calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// At this point calSet would be a scheduling candidate. It's just the day the might not be right, yet.
long milliSecondsInAWeek = 1000 * 60 * 60 * 24 * 7;
for(int dayOfWeek : oneTrigger.getTimeFrame().getDayList())
{
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
// calSetWorkingCopy.set(Calendar.HOUR_OF_DAY, setTime.getHours());
// calSetWorkingCopy.set(Calendar.MINUTE, setTime.getMinutes());
// calSetWorkingCopy.set(Calendar.SECOND, 0);
// calSetWorkingCopy.set(Calendar.MILLISECOND, 0);
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
// Log.i("AlarmManager", "Today: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + " / Sched.Day: " + String.valueOf(dayOfWeek) + " Difference to target day is: " + String.valueOf(diff));
if(diff == 0) //if we're talking about the current day, is the time still in the future?
{
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours(" + String.valueOf(calSetWorkingCopy.getTime().getHours()) + ") < calNow.getTime().getHours(" + String.valueOf(calNow.getTime().getHours()) + ")");
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours()");
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
{
// Log.i("AlarmManager", "calSetWorkingCopy.getTime().getMinutes() < calNow.getTime().getMinutes()");
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
}
}
else if(diff < 0)
{
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff+7) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
}
else
{
// Miscellaneous.logEvent("i", "AlarmManager", "Adding " + String.valueOf(diff) + " on top of " + String.valueOf(calSetWorkingCopy.get(Calendar.DAY_OF_WEEK)));
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
}
i++;
i=(int)System.currentTimeMillis();
String calSetWorkingCopyString = sdf.format(calSetWorkingCopy.getTime()) + " RequestCode: " + String.valueOf(i);
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of rule: " + oneRule.getName() + " beginning at " + calSetWorkingCopyString);
alarmCandidates.add(calSetWorkingCopy.getTimeInMillis());
// Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmIntent.setData(Uri.parse("myalarms://" + i));
// PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, i, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, calSetWorkingCopy.getTimeInMillis(), milliSecondsInAWeek, alarmPendingIntent);
// requestCodeList.add(i);
}
}
}
}
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = sdf.format(cal.getTime());
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
scheduleNextAlarm();
}
private static void scheduleNextAlarm()
{
Long currentTime = System.currentTimeMillis();
Long scheduleCandidate = null;
if(alarmCandidates.size() == 0)
{
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
return;
}
else if(alarmCandidates.size() == 1)
{
// only one alarm, schedule that
scheduleCandidate = alarmCandidates.get(0);
}
else if(alarmCandidates.size() > 1)
{
scheduleCandidate = alarmCandidates.get(0);
for(long alarmCandidate : alarmCandidates)
{
if(Math.abs(currentTime - alarmCandidate) < Math.abs(currentTime - scheduleCandidate))
scheduleCandidate = alarmCandidate;
}
}
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate, alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate);
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
}
public static void clearAlarms()
{
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for(int requestCode : requestCodeList)
{
Intent alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent);
}
requestCodeList.clear();
}
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
{
if(!alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
AlarmListener.automationServiceRef = givenAutomationServiceRef;
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
alarmListenerActive = true;
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
AlarmListener.setAlarms();
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent);
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
}
private static void stopAlarmListenerInternal()
{
if(alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false;
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
}
public static void reloadAlarms()
{
AlarmListener.setAlarms();
}
@Override
public void startListener(AutomationService automationService)
{
AlarmListener.startAlarmListener(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
AlarmListener.stopAlarmListener(automationService);
}
public static boolean haveAllPermission()
{
return true;
}
@Override
public boolean isListenerRunning()
{
return isAlarmListenerActive();
}
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.timeFrame };
}
}

View File

@ -1,5 +1,6 @@
package com.jens.automation2.receivers; package com.jens.automation2.receivers;
import android.Manifest;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -18,7 +19,7 @@ import java.util.ArrayList;
public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface public class BatteryReceiver extends BroadcastReceiver implements AutomationListenerInterface
{ {
private static int batteryLevel=-1; // initialize with a better value than this private static int batteryLevel = -1; // initialize with a better value than this
public static AutomationService automationServiceRef = null; public static AutomationService automationServiceRef = null;
private static boolean usbHostConnected = false; private static boolean usbHostConnected = false;
@ -26,6 +27,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
private static IntentFilter batteryIntentFilter = null; private static IntentFilter batteryIntentFilter = null;
private static Intent batteryStatus = null; private static Intent batteryStatus = null;
private static BroadcastReceiver batteryInfoReceiverInstance = null; private static BroadcastReceiver batteryInfoReceiverInstance = null;
public static void startBatteryReceiver(final AutomationService automationServiceRef) public static void startBatteryReceiver(final AutomationService automationServiceRef)
{ {
if(!batteryReceiverActive) if(!batteryReceiverActive)
@ -78,11 +80,11 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
return batteryLevel; return batteryLevel;
} }
private static int deviceIsCharging = 0; //0=unknown, 1=no, 2=yes private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
public static int getDeviceIsCharging() public static int getCurrentChargingState()
{ {
return deviceIsCharging; return currentChargingState;
} }
@Override @Override
@ -145,31 +147,6 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
this.actionDischarging(context); this.actionDischarging(context);
break; break;
} }
// }
// else if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED))
// {
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.");
// deviceIsCharging = 2;
// //activate rule(s)
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
// for(int i=0; i<ruleCandidates.size(); i++)
// {
// if(ruleCandidates.get(i).applies(context))
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
// }
// }
// else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED))
// {
//// Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.");
// deviceIsCharging = 1;
// //activate rule(s)
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
// for(int i=0; i<ruleCandidates.size(); i++)
// {
// if(ruleCandidates.get(i).applies(context))
// ruleCandidates.get(i).activate(locationProviderRef.getParentService());
// }
// }
} }
catch(Exception e) catch(Exception e)
{ {
@ -180,7 +157,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
public static int isDeviceCharging(Context context) public static int isDeviceCharging(Context context)
{ {
switch(deviceIsCharging) switch(currentChargingState)
{ {
case 0: case 0:
Miscellaneous.logEvent("w", "ChargingInfo", "Status of device charging was requested. Information isn't available, yet.", 4); Miscellaneous.logEvent("w", "ChargingInfo", "Status of device charging was requested. Information isn't available, yet.", 4);
@ -188,25 +165,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
case 1: case 1:
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is discharging.", 3); Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is discharging.", 3);
break; break;
case 2: case BatteryManager.BATTERY_STATUS_CHARGING:
Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3); Miscellaneous.logEvent("i", "ChargingInfo", "Status of device charging was requested. Device is charging.", 3);
break; break;
} }
return deviceIsCharging; return currentChargingState;
} }
private void actionCharging(Context context) private void actionCharging(Context context)
{ {
if(deviceIsCharging != 2) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed. if(currentChargingState != BatteryManager.BATTERY_STATUS_CHARGING) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{ {
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3); Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is charging or full.", 3);
deviceIsCharging = 2; currentChargingState = BatteryManager.BATTERY_STATUS_CHARGING;
//activate rule(s) //activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(context)) if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false); ruleCandidates.get(i).activate(automationServiceRef, false);
} }
} }
@ -216,25 +194,26 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
{ {
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery level has changed.", 3); Miscellaneous.logEvent("i", "BatteryReceiver", "Battery level has changed.", 3);
//activate rule(s) //activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBatteryLevel(); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.batteryLevel);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(context)) if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false); ruleCandidates.get(i).activate(automationServiceRef, false);
} }
} }
private void actionDischarging(Context context) private void actionDischarging(Context context)
{ {
if(deviceIsCharging != 1) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed. if(currentChargingState != BatteryManager.BATTERY_STATUS_UNKNOWN) // Avoid flooding the log. This event will occur on a regular basis even though charging state wasn't changed.
{ {
Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3); Miscellaneous.logEvent("i", "BatteryReceiver", "Battery is discharging.", 3);
deviceIsCharging = 1; currentChargingState = BatteryManager.BATTERY_STATUS_UNKNOWN;
//activate rule(s) //activate rule(s)
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.charging);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(context)) if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false); ruleCandidates.get(i).activate(automationServiceRef, false);
} }
@ -253,11 +232,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
usbHostConnected = true; usbHostConnected = true;
Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3); Miscellaneous.logEvent("i", "BatteryReceiver", "Connected to computer.", 3);
Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show(); Toast.makeText(context, "Connected to computer.", Toast.LENGTH_LONG).show();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
for(Rule oneRule : ruleCandidates) for(Rule oneRule : ruleCandidates)
{ {
if(oneRule.applies(context)) if(oneRule.getsGreenLight(context))
oneRule.activate(automationServiceRef, false); oneRule.activate(automationServiceRef, false);
} }
@ -274,11 +254,12 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
usbHostConnected = false; usbHostConnected = false;
Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3); Miscellaneous.logEvent("i", "BatteryReceiver", "Disconnected from computer.", 3);
Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show(); Toast.makeText(context, "Disconnected from computer.", Toast.LENGTH_LONG).show();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.usb_host_connection);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
for(Rule oneRule : ruleCandidates) for(Rule oneRule : ruleCandidates)
{ {
if(oneRule.applies(context)) if(oneRule.getsGreenLight(context))
oneRule.activate(automationServiceRef, false); oneRule.activate(automationServiceRef, false);
} }
} }
@ -296,8 +277,8 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
public static boolean haveAllPermission() public static boolean haveAllPermission()
{ {
return ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext()) && return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
ActivityPermissions.havePermission("android.permission.BATTERY_STATS", Miscellaneous.getAnyContext()); ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
} }
@Override @Override

View File

@ -124,10 +124,10 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDeviceInRange), bluetoothDevice.getName()), 3); Miscellaneous.logEvent("i", "BluetoothReceiver", String.format(context.getResources().getString(R.string.bluetoothDeviceInRange), bluetoothDevice.getName()), 3);
} }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection(); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.bluetoothConnection);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(AutomationService.getInstance())) if(ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
ruleCandidates.get(i).activate(AutomationService.getInstance(), false); ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
} }
} }

View File

@ -112,7 +112,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
@SuppressLint("NewApi") @SuppressLint("NewApi")
public static boolean isAirplaneMode(Context context) public static boolean isAirplaneMode(Context context)
{ {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{ {
int value = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0); int value = android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0);
return value != 0; return value != 0;
@ -138,10 +138,11 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
boolean isAirplaneMode = isAirplaneMode(context); boolean isAirplaneMode = isAirplaneMode(context);
automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode); automationServiceRef.getLocationProvider().handleAirplaneMode(isAirplaneMode);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.airplaneMode);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(automationServiceRef)) if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
ruleCandidates.get(i).activate(automationServiceRef, false); ruleCandidates.get(i).activate(automationServiceRef, false);
} }
} }
@ -170,11 +171,12 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
roamingLastState = isRoaming; roamingLastState = isRoaming;
automationServiceRef.getLocationProvider().handleRoaming(isRoaming); automationServiceRef.getLocationProvider().handleRoaming(isRoaming);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.roaming);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(automationServiceRef)) if(ruleCandidates.get(i).getsGreenLight(automationServiceRef))
ruleCandidates.get(i).activate(automationServiceRef, false); ruleCandidates.get(i).activate(automationServiceRef, false);
} }
} }

View File

@ -0,0 +1,433 @@
package com.jens.automation2.receivers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.TimeFrame;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface
{
private static AutomationService automationServiceRef;
private static AlarmManager centralAlarmManagerInstance;
// private static Intent alarmIntent;
// private static PendingIntent alarmPendingIntent;
private static boolean alarmListenerActive=false;
private static ArrayList<ScheduleElement> alarmCandidates = new ArrayList<>();
private static ArrayList<Integer> requestCodeList = new ArrayList<Integer>();
public static void startAlarmListener(final AutomationService automationServiceRef)
{
DateTimeListener.startAlarmListenerInternal(automationServiceRef);
}
public static void stopAlarmListener(Context context)
{
DateTimeListener.stopAlarmListenerInternal();
}
public static boolean isAlarmListenerActive()
{
return alarmListenerActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
Miscellaneous.logEvent("i", "AlarmListener", "Alarm received", 2);
Date now = new Date();
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
Time passTime = Time.valueOf(timeString);
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
// ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
{
if(allRulesWithNowInTimeFrame.get(i).getsGreenLight(context))
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
}
setAlarms();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setAlarms()
{
alarmCandidates.clear();
Calendar calNow = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
clearAlarms();
int i=0;
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// String calSetWorkingCopyString2 = null;
// SimpleDateFormat sdf2 = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
// if (cal != null)
// {
// calSetWorkingCopyString2 = sdf2.format(cal.getTime());
// }
// Miscellaneous.logEvent("i", "AlarmManager", "Setting repeating alarm because of hardcoded test: beginning at " + calSetWorkingCopyString2);
// Intent alarmIntent2 = new Intent(automationServiceRef, AlarmListener.class);
// PendingIntent alarmPendingIntent2 = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent2, 0);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent2);
// requestCodeList.add(0);
ArrayList<Rule> allRulesWithTimeFrames = new ArrayList<Rule>();
allRulesWithTimeFrames = Rule.findRuleCandidates(Trigger_Enum.timeFrame);
// allRulesWithTimeFrames = Rule.findRuleCandidatesByTimeFrame();
/*
* Take care of regular executions, no repetitions in between.
*/
Miscellaneous.logEvent("i", "DateTimeListener", "Checking rules for single run alarm candidates.", 5);
for(Rule oneRule : allRulesWithTimeFrames)
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for single run alarm candidates.", 5);
if(oneRule.isRuleActive())
{
try
{
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for single run alarm candidates.", 5);
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
{
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
Calendar calSet;
Time setTime;
if(oneTrigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
else
setTime = tf.getTriggerTimeStop();
calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// At this point calSet would be a scheduling candidate. It's just the day that might not be right, yet.
for(int dayOfWeek : tf.getDayList())
{
Calendar calSetWorkingCopy = (Calendar) calSet.clone();
int diff = dayOfWeek - calNow.get(Calendar.DAY_OF_WEEK);
if(diff == 0) // We're talking about the current weekday, but is the time still in the future?
{
if(calSetWorkingCopy.getTime().getHours() < calNow.getTime().getHours())
{
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
else if(calSetWorkingCopy.getTime().getHours() == calNow.getTime().getHours())
{
if(calSetWorkingCopy.getTime().getMinutes() <= calNow.getTime().getMinutes())
{
calSetWorkingCopy.add(Calendar.DAY_OF_MONTH, 7); //add a week
}
}
}
else if(diff < 0)
{
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff+7); // it's a past weekday, schedule for next week
}
else
{
calSetWorkingCopy.add(Calendar.DAY_OF_WEEK, diff); // it's a future weekday, schedule for that day
}
i++;
i=(int)System.currentTimeMillis();
sdf.format(calSetWorkingCopy.getTime());
String.valueOf(i);
alarmCandidates.add(new ScheduleElement(calSetWorkingCopy, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
}
}
}
/*
* Only take care of repeated executions.
*/
Miscellaneous.logEvent("i", "DateTimeListener","Checking rules for repeated run alarm candidates.", 5);
for(Rule oneRule : allRulesWithTimeFrames)
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.getName() + " for repeated run alarm candidates.", 5);
if(oneRule.isRuleActive())
{
try
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule " + oneRule.toString() , 5);
for(Trigger oneTrigger : oneRule.getTriggerSet())
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking trigger " + oneTrigger.toString() + " for repeated run alarm candidates.", 5);
if(oneTrigger.getTriggerType().equals(Trigger_Enum.timeFrame))
{
Miscellaneous.logEvent("i", "DateTimeListener","Checking rule trigger " + oneTrigger.toString() , 5);
/*
* Check for next repeated execution:
*
* Check if the rule currently applies....
*
* If no -> do nothing
* If yes -> Take starting time and calculate the next repeated execution
* 1. Take starting time
* 2. Take current time
* 3. Calculate difference, but include check to see if we're after that time,
* be it start or end of the timeframe.
* 4. Take div result +1 and add this on top of starting time
* 5. Is this next possible execution still inside timeframe? Also consider timeframes spanning over midnight
*/
Calendar calSet;
Time setTime;
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(oneTrigger.applies(calNow, Miscellaneous.getAnyContext()))
{
Calendar calSchedule = getNextRepeatedExecutionAfter(oneTrigger, calNow);
alarmCandidates.add(new ScheduleElement(calSchedule, "Rule " + oneRule.getName() + ", trigger " + oneTrigger.toString()));
}
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "DateTimeListener","Error checking anything for rule " + oneRule.toString() + " needs to be added to candicates list: " + Log.getStackTraceString(e), 1);
}
}
}
scheduleNextAlarm();
}
private static void scheduleNextAlarm()
{
Long currentTime = System.currentTimeMillis();
ScheduleElement scheduleCandidate = null;
if(alarmCandidates.size() == 0)
{
Miscellaneous.logEvent("i", "AlarmManager", "No alarms to be scheduled.", 3);
return;
}
else if(alarmCandidates.size() == 1)
{
// only one alarm, schedule that
scheduleCandidate = alarmCandidates.get(0);
}
else if(alarmCandidates.size() > 1)
{
scheduleCandidate = alarmCandidates.get(0);
for(ScheduleElement alarmCandidate : alarmCandidates)
{
if(Math.abs(currentTime - alarmCandidate.time.getTimeInMillis()) < Math.abs(currentTime - scheduleCandidate.time.getTimeInMillis()))
scheduleCandidate = alarmCandidate;
}
}
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(scheduleCandidate.time.getTimeInMillis());
Miscellaneous.logEvent("i", "AlarmManager", "Chose " + sdf.format(calendar.getTime()) + " as next scheduled alarm.", 4);
}
public static void clearAlarms()
{
Miscellaneous.logEvent("i", "AlarmManager", "Clearing possibly standing alarms.", 4);
for(int requestCode : requestCodeList)
{
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, requestCode, alarmIntent, 0);
// Miscellaneous.logEvent("i", "AlarmManager", "Clearing alarm with request code: " + String.valueOf(requestCode));
centralAlarmManagerInstance.cancel(alarmPendingIntent);
}
requestCodeList.clear();
}
private static void startAlarmListenerInternal(AutomationService givenAutomationServiceRef)
{
if(!alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Starting alarm listener.", 4);
DateTimeListener.automationServiceRef = givenAutomationServiceRef;
centralAlarmManagerInstance = (AlarmManager)automationServiceRef.getSystemService(automationServiceRef.ALARM_SERVICE);
// alarmIntent = new Intent(automationServiceRef, AlarmListener.class);
// alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, 0);
alarmListenerActive = true;
Miscellaneous.logEvent("i", "AlarmListener", "Alarm listener started.", 4);
DateTimeListener.setAlarms();
// // get a Calendar object with current time
// Calendar cal = Calendar.getInstance();
// // add 5 minutes to the calendar object
// cal.add(Calendar.SECOND, 10);
// centralAlarmManagerInstance.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, alarmPendingIntent);
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to start AlarmListener. But it's already active.", 5);
}
private static void stopAlarmListenerInternal()
{
if(alarmListenerActive)
{
Miscellaneous.logEvent("i", "AlarmListener", "Stopping alarm listener.", 4);
clearAlarms();
// centralAlarmManagerInstance.cancel(alarmPendingIntent);
alarmListenerActive = false;
}
else
Miscellaneous.logEvent("i", "AlarmListener", "Request to stop AlarmListener. But it's not running.", 5);
}
public static void reloadAlarms()
{
DateTimeListener.setAlarms();
}
@Override
public void startListener(AutomationService automationService)
{
DateTimeListener.startAlarmListener(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
DateTimeListener.stopAlarmListener(automationService);
}
public static boolean haveAllPermission()
{
return true;
}
@Override
public boolean isListenerRunning()
{
return isAlarmListenerActive();
}
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.timeFrame };
}
static class ScheduleElement implements Comparable<ScheduleElement>
{
Calendar time;
String reason;
public ScheduleElement(Calendar timestamp, String reason)
{
super();
this.time = timestamp;
this.reason = reason;
}
@Override
public int compareTo(ScheduleElement o)
{
if(time.getTimeInMillis() == o.time.getTimeInMillis())
return 0;
if(time.getTimeInMillis() < o.time.getTimeInMillis())
return -1;
else
return 1;
}
@Override
public String toString()
{
return Miscellaneous.formatDate(time.getTime()) + ", reason : " + reason;
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
Time setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
{
if(trigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
else
setTime = tf.getTriggerTimeStop();
calSet = (Calendar) now.clone();
calSet.set(Calendar.HOUR_OF_DAY, setTime.getHours());
calSet.set(Calendar.MINUTE, setTime.getMinutes());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
// if(this.applies(null))
// {
// If the starting time is a day ahead remove 1 day.
if(calSet.getTimeInMillis() > now.getTimeInMillis())
calSet.add(Calendar.DAY_OF_MONTH, -1);
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calSet.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
long nextScheduleTimestamp = (calSet.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition());
Calendar calSchedule = Calendar.getInstance();
calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000);
/*
* Das war mal aktiviert. Allerdings: Die ganze Funktion liefert zurück, wenn die Regel NOCH nicht
* zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten.
*/
// if(trigger.checkDateTime(calSchedule.getTime(), false))
// {
return calSchedule;
// }
// }
}
else
Miscellaneous.logEvent("i", "DateTimeListener", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5);
return null;
}
}

View File

@ -0,0 +1,251 @@
package com.jens.automation2.receivers;
import static android.content.Context.SENSOR_SERVICE;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import com.jens.automation2.ActivityManageTriggerDeviceOrientation;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Settings;
import com.jens.automation2.Trigger;
import java.util.ArrayList;
import java.util.Calendar;
public class DeviceOrientationListener implements SensorEventListener, AutomationListenerInterface
{
// https://developer.android.com/guide/topics/sensors/sensors_position#java
ActivityManageTriggerDeviceOrientation activityManageTriggerDeviceOrientationInstance = null;
//the Sensor Manager
private SensorManager sManager;
static DeviceOrientationListener instance = null;
boolean isRunning = false;
Calendar now = null;
static Calendar lastTimeSignalArrived = null;
static int sensorValueCounter = 0;
// Gravity rotational data
private float gravity[];
// Magnetic rotational data
private float magnetic[]; //for magnetic rotational data
private float accels[] = new float[3];
private float mags[] = new float[3];
private float[] values = new float[3];
// azimuth, pitch and roll
private float azimuth;
private float pitch;
private float roll;
boolean applies = false;
boolean flipped = false;
boolean toggable = false;
public static DeviceOrientationListener getInstance()
{
if (instance == null)
instance = new DeviceOrientationListener();
return instance;
}
public float getAzimuth()
{
return azimuth;
}
public float getPitch()
{
return pitch;
}
public float getRoll()
{
return roll;
}
public void startSensorFromConfigActivity(Context context, ActivityManageTriggerDeviceOrientation activityManageTriggerDeviceOrientationInstance)
{
this.activityManageTriggerDeviceOrientationInstance = activityManageTriggerDeviceOrientationInstance;
if(!isRunning)
{
sManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
/*
register the sensor listener to listen to the gyroscope sensor, use the
callbacks defined in this class, and gather the sensor information as quick
as possible
*/
isRunning = true;
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
}
}
public void stopSensorFromConfigActivity()
{
activityManageTriggerDeviceOrientationInstance = null;
if(isRunning)
{
if(!Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
{
//unregister the sensor listener
sManager.unregisterListener(this);
isRunning = false;
}
}
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1)
{
//Do nothing.
}
@Override
public void onSensorChanged(SensorEvent event)
{
switch (event.sensor.getType())
{
case Sensor.TYPE_MAGNETIC_FIELD:
mags = event.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER:
accels = event.values.clone();
break;
}
if (mags != null && accels != null)
{
gravity = new float[9];
magnetic = new float[9];
SensorManager.getRotationMatrix(gravity, magnetic, accels, mags);
float[] outGravity = new float[9];
SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X, SensorManager.AXIS_Z, outGravity);
SensorManager.getOrientation(outGravity, values);
azimuth = values[0] * 57.2957795f;
pitch = values[1] * 57.2957795f;
roll = values[2] * 57.2957795f;
mags = null;
accels = null;
}
//else it will output the Roll, Pitch and Yawn values
if(activityManageTriggerDeviceOrientationInstance != null)
activityManageTriggerDeviceOrientationInstance.updateFields(azimuth, pitch, roll);
/*
For some reason the first 3 values after starting the listener
are crap.
*/
if(sensorValueCounter > 3)
{
now = Calendar.getInstance();
if (lastTimeSignalArrived == null || now.getTimeInMillis() >= lastTimeSignalArrived.getTimeInMillis() + Settings.acceptDeviceOrientationSignalEveryX_MilliSeconds)
{
lastTimeSignalArrived = now;
Miscellaneous.logEvent("i", "DeviceOrientation", "Got device orientation update: azimuth: " + String.valueOf(azimuth) + ", pitch: " + String.valueOf(pitch) + ", roll: " + String.valueOf(pitch), 4);
if (AutomationService.isMyServiceRunning(Miscellaneous.getAnyContext()))
{
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.deviceOrientation);
for (int i = 0; i < ruleCandidates.size(); i++)
{
if (ruleCandidates.get(i).getsGreenLight(Miscellaneous.getAnyContext()))
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
}
}
else
sensorValueCounter++;
}
@Override
public void startListener(AutomationService automationService)
{
if(!isRunning)
{
sManager = (SensorManager) Miscellaneous.getAnyContext().getSystemService(SENSOR_SERVICE);
/*
register the sensor listener to listen to the gyroscope sensor, use the
callbacks defined in this class, and gather the sensor information as quick
as possible
*/
isRunning = true;
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
public void stopListener(AutomationService automationService)
{
this.activityManageTriggerDeviceOrientationInstance = null;
if(isRunning)
{
//unregister the sensor listener
sManager.unregisterListener(this);
isRunning = false;
}
}
@Override
public boolean isListenerRunning()
{
return isRunning;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.deviceOrientation};
}
/*
Azimuth (degrees of rotation about the -z axis).
This is the angle between the device's current compass direction and magnetic north. If the top edge of the
device faces magnetic north, the azimuth is 0 degrees; if the top edge faces south, the azimuth is 180 degrees.
Similarly, if the top edge faces east, the azimuth is 90 degrees, and if the top edge faces west, the azimuth is 270 degrees.
Pitch (degrees of rotation about the x axis).
This is the angle between a plane parallel to the device's screen and a plane parallel to the ground. If you hold the device
parallel to the ground with the bottom edge closest to you and tilt the top edge of the device toward the ground, the pitch
angle becomes positive. Tilting in the opposite direction moving the top edge of the device away from the groundcauses
the pitch angle to become negative. The range of values is -180 degrees to 180 degrees.
Roll (degrees of rotation about the y axis).
This is the angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground.
If you hold the device parallel to the ground with the bottom edge closest to you and tilt the left edge of the
device toward the ground, the roll angle becomes positive. Tilting in the opposite directionmoving the right
edge of the device toward the ground causes the roll angle to become negative. The range of values is -90 degrees
to 90 degrees.
Computes the device's orientation based on the rotation matrix.
When it returns, the array values are as follows:
values[0]: Azimuth, angle of rotation about the -z axis. This value represents the angle between the device's y axis and the magnetic north pole. When facing north, this angle is 0, when facing south, this angle is π. Likewise, when facing east, this angle is π/2, and when facing west, this angle is -π/2. The range of values is -π to π.
values[1]: Pitch, angle of rotation about the x axis. This value represents the angle between a plane parallel to the device's screen and a plane parallel to the ground. Assuming that the bottom edge of the device faces the user and that the screen is face-up, tilting the top edge of the device toward the ground creates a positive pitch angle. The range of values is -π to π.
values[2]: Roll, angle of rotation about the y axis. This value represents the angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground. Assuming that the bottom edge of the device faces the user and that the screen is face-up, tilting the left edge of the device toward the ground creates a positive roll angle. The range of values is -π/2 to π/2.
Applying these three rotations in the azimuth, pitch, roll order transforms an identity matrix to the rotation matrix passed into this method. Also, note that all three orientation angles are expressed in radians.
*/
}

View File

@ -1,5 +1,6 @@
package com.jens.automation2.receivers; package com.jens.automation2.receivers;
import android.Manifest;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -73,11 +74,12 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
headsetConnected = true; headsetConnected = true;
Miscellaneous.logEvent("i", "HeadphoneJackListener", "Headset " + name + " plugged in.", 4); Miscellaneous.logEvent("i", "HeadphoneJackListener", "Headset " + name + " plugged in.", 4);
} }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected()); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.headsetPlugged);
// ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
if(ruleCandidates.get(i).applies(context)) if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(AutomationService.getInstance(), false); ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
} }
} }
@ -133,7 +135,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
public static boolean haveAllPermission() public static boolean haveAllPermission()
{ {
return ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext()); return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext());
} }

View File

@ -19,6 +19,7 @@ import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous; import com.jens.automation2.Miscellaneous;
import com.jens.automation2.R; import com.jens.automation2.R;
import com.jens.automation2.Rule; import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -171,10 +172,10 @@ public class NfcReceiver
} }
else else
{ {
ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidatesByNfc(); ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidates(Trigger.Trigger_Enum.nfcTag);
for(int i=0; i<allRulesWithNfcTags.size(); i++) for(int i=0; i<allRulesWithNfcTags.size(); i++)
{ {
if(allRulesWithNfcTags.get(i).applies(asInstance)) if(allRulesWithNfcTags.get(i).getsGreenLight(asInstance))
allRulesWithNfcTags.get(i).activate(asInstance, false); allRulesWithNfcTags.get(i).activate(asInstance, false);
} }
} }

View File

@ -30,10 +30,10 @@ public class NoiseListener implements AutomationListenerInterface
noiseLevelDb = msg.getData().getLong("noiseLevelDb"); noiseLevelDb = msg.getData().getLong("noiseLevelDb");
// execute matching rules containing noise // execute matching rules containing noise
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByNoiseLevel(); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.noiseLevel);
for(Rule oneRule : ruleCandidates) for(Rule oneRule : ruleCandidates)
{ {
if(oneRule.applies(automationService)) if(oneRule.getsGreenLight(automationService))
oneRule.activate(automationService, false); oneRule.activate(automationService, false);
} }
} }

View File

@ -89,19 +89,12 @@ public class NotificationListener extends NotificationListenerService
lastNotification.title = title; lastNotification.title = title;
lastNotification.text = text; lastNotification.text = text;
// if(lastResponseToNotification == null || lastResponseToNotification.getTimeInMillis() < lastNotification.publishTime.getTimeInMillis()) ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
// { for (int i = 0; i < ruleCandidates.size(); i++)
// lastResponseToNotification = Calendar.getInstance(); {
if(ruleCandidates.get(i).getsGreenLight(NotificationListener.this))
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification); ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
for (int i = 0; i < ruleCandidates.size(); i++) }
{
if (ruleCandidates.get(i).applies(NotificationListener.this))
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
// }
// else
// Miscellaneous.logEvent("e", "NotificationCheck", "Ignoring notification as it is old.", 5);
} }
return false; return false;

View File

@ -109,12 +109,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
break; break;
} }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
AutomationService asInstance = AutomationService.getInstance(); AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null) if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance)) if(ruleCandidates.get(i).getsGreenLight(asInstance))
ruleCandidates.get(i).activate(asInstance, false); ruleCandidates.get(i).activate(asInstance, false);
} }
} }
@ -141,12 +141,12 @@ public class PhoneStatusListener implements AutomationListenerInterface
break; break;
} }
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionIncoming); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
for (int i = 0; i < ruleCandidates.size(); i++) for (int i = 0; i < ruleCandidates.size(); i++)
{ {
AutomationService asInstance = AutomationService.getInstance(); AutomationService asInstance = AutomationService.getInstance();
if (asInstance != null) if (asInstance != null)
if (ruleCandidates.get(i).applies(asInstance)) if (ruleCandidates.get(i).getsGreenLight(asInstance))
ruleCandidates.get(i).activate(asInstance, false); ruleCandidates.get(i).activate(asInstance, false);
} }
} }
@ -168,22 +168,18 @@ public class PhoneStatusListener implements AutomationListenerInterface
*/ */
setLastPhoneDirection(2); setLastPhoneDirection(2);
// TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
// int newState = tm.getCallState();
// setCurrentState(newState);
setCurrentState(TelephonyManager.CALL_STATE_RINGING); setCurrentState(TelephonyManager.CALL_STATE_RINGING);
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setLastPhoneNumber(phoneNumber); setLastPhoneNumber(phoneNumber);
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4); Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing); ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
for(int i=0; i<ruleCandidates.size(); i++) for(int i=0; i<ruleCandidates.size(); i++)
{ {
AutomationService asInstance = AutomationService.getInstance(); AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null) if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance)) if(ruleCandidates.get(i).getsGreenLight(asInstance))
ruleCandidates.get(i).activate(asInstance, false); ruleCandidates.get(i).activate(asInstance, false);
} }
} }

View File

@ -43,34 +43,27 @@ public class ProcessListener implements AutomationListenerInterface
@Override @Override
public void handleMessage(Message msg) public void handleMessage(Message msg)
{ {
// try Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.processMonitoring), automationService.getResources().getString(R.string.messageReceivedStatingProcessMonitoringIsComplete), 5);
// { // This will take care of results delivered by the actual monitoring instance
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.processMonitoring), automationService.getResources().getString(R.string.messageReceivedStatingProcessMonitoringIsComplete), 5);
// This will take care of results delivered by the actual monitoring instance for(String entry : getRunningApps())
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.runningApp), entry, 5);
for(String entry : getRunningApps())
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.runningApp), entry, 5); // execute matching rules containing processes
if(getRecentlyStartedApps().size()>0 | getRecentlyStoppedApps().size()>0)
// execute matching rules containing processes {
if(getRecentlyStartedApps().size()>0 | getRecentlyStoppedApps().size()>0) for(String entry : getRecentlyStartedApps())
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStarted), entry, 3);
for(String entry : getRecentlyStoppedApps())
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStopped), entry, 3);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.process_started_stopped);
for(int i=0; i<ruleCandidates.size(); i++)
{ {
for(String entry : getRecentlyStartedApps()) if(ruleCandidates.get(i).getsGreenLight(automationService))
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStarted), entry, 3); ruleCandidates.get(i).activate(automationService, false);
for(String entry : getRecentlyStoppedApps())
Miscellaneous.logEvent("i", automationService.getResources().getString(R.string.appStopped), entry, 3);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByProcess();
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).applies(automationService))
ruleCandidates.get(i).activate(automationService, false);
}
} }
// } }
// catch(Exception e)
// {
// Miscellaneous.logEvent("e", "Noise level", "Error in workHandler->handleMessage(): " + e.getMessage());
// }
} }
}; };

View File

@ -77,12 +77,12 @@ public class TimeZoneListener extends BroadcastReceiver implements AutomationLis
if(action.equals(Intent.ACTION_TIMEZONE_CHANGED)) if(action.equals(Intent.ACTION_TIMEZONE_CHANGED))
{ {
Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3); Miscellaneous.logEvent("i", "TimeZoneListener", "Device timezone changed. Reloading alarms.", 3);
AlarmListener.reloadAlarms(); DateTimeListener.reloadAlarms();
} }
else if(action.equals(Intent.ACTION_TIME_CHANGED)) else if(action.equals(Intent.ACTION_TIME_CHANGED))
{ {
Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 4); Miscellaneous.logEvent("i", "TimeZoneListener", "Device time changed. Reloading alarms.", 4);
AlarmListener.reloadAlarms(); DateTimeListener.reloadAlarms();
} }
} }
@Override @Override

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -57,7 +57,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"
android:inputType="numberDecimal" /> android:inputType="numberSigned" />
</TableRow> </TableRow>
@ -72,14 +72,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/longitude" android:text="@string/longitude"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
android:id="@+id/etPoiLongitude" android:id="@+id/etPoiLongitude"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"
android:inputType="numberDecimal" /> android:inputType="numberSigned" />
</TableRow> </TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/deviceOrientationExplanation"
android:layout_marginBottom="@dimen/default_margin" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationAzimuth"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvCurrentAzimuth"
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationPitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvCurrentOrientationPitch"
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationRoll"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvCurrentRoll"
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/bApplyPositionValues"
android:text="@string/apply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/default_margin" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0"
android:stretchColumns="1">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:text=""
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="@string/orientation"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="@string/tolerance"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="@string/wouldCurrentlyApply"
android:singleLine="false"
android:maxLines="2"
android:lines="2"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationAzimuth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin" />
<EditText
android:id="@+id/etDesiredAzimuth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:enabled="false"
android:inputType="number" />
<EditText
android:id="@+id/etDesiredAzimuthTolerance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:inputType="number" />
<TextView
android:id="@+id/tvAppliesAzimuth"
android:gravity="center_horizontal"
android:text="@string/unknown"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationPitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin" />
<EditText
android:id="@+id/etDesiredPitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:enabled="false"
android:inputType="number" />
<EditText
android:id="@+id/etDesiredPitchTolerance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:inputType="number" />
<TextView
android:id="@+id/tvAppliesPitch"
android:gravity="center_horizontal"
android:text="@string/unknown"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:text="@string/orientationRoll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin" />
<EditText
android:id="@+id/etDesiredRoll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:enabled="false"
android:inputType="number" />
<EditText
android:id="@+id/etDesiredRollTolerance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:inputType="number" />
<TextView
android:id="@+id/tvAppliesRoll"
android:gravity="center_horizontal"
android:text="@string/unknown"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<CheckBox
android:id="@+id/chkDevicePositionApplies"
android:checked="true"
android:text="@string/mustApply"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/explanationDeviceOrientationDirection" />
<Button
android:id="@+id/bSavePositionValues"
android:text="@string/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin" />
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>

View File

@ -45,6 +45,18 @@
</TableRow> </TableRow>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/automationNotificationsIgnored" />
<TableRow <TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin"> android:layout_marginBottom="@dimen/activity_vertical_margin">
@ -78,6 +90,13 @@
</TableRow> </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 <TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin"> android:layout_marginBottom="@dimen/activity_vertical_margin">
@ -106,6 +125,13 @@
</LinearLayout> </LinearLayout>
</TableRow> </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 <TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin"> android:layout_marginBottom="@dimen/activity_vertical_margin">

View File

@ -119,6 +119,34 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/sunday" /> android:text="@string/sunday" />
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/chkRepeat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/repeatEveryXseconds" />
<EditText
android:id="@+id/etRepeatEvery"
android:layout_marginLeft="@dimen/default_margin"
android:minWidth="75dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:inputType="numberSigned" />
</LinearLayout>
<Button <Button
android:id="@+id/bSaveTimeFrame" android:id="@+id/bSaveTimeFrame"

View File

@ -262,6 +262,18 @@
android:inputType="number"></EditTextPreference> android:inputType="number"></EditTextPreference>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory
android:summary="@string/deviceOrientationSettings"
android:title="@string/deviceOrientationSettings">
<EditTextPreference
android:key="acceptDevicePositionSignalEveryX_MilliSeconds"
android:summary="@string/deviceOrientationTimeAcceptIntervalSummary"
android:title="@string/deviceOrientationTimeAcceptIntervalTitle"
android:inputType="number"></EditTextPreference>
</PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:summary="@string/activityDetection" android:summary="@string/activityDetection"

View File

@ -6,10 +6,10 @@
android:layout_margin="@dimen/default_margin" > android:layout_margin="@dimen/default_margin" >
<TextView <TextView
android:id="@+id/tvVolumeTestExplanation" android:id="@+id/tvVolumeCalibrationExplanation"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/volumeTesterExplanation" android:text="@string/volumeCalibrationExplanation"
android:layout_marginBottom="20dp" /> android:layout_marginBottom="20dp" />
<TableLayout <TableLayout
@ -26,6 +26,7 @@
<TextView <TextView
android:id="@+id/tvCurrentVolume" android:id="@+id/tvCurrentVolume"
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="0dB" android:text="0dB"
@ -45,6 +46,7 @@
<EditText <EditText
android:id="@+id/etReferenceValue" android:id="@+id/etReferenceValue"
android:layout_marginLeft="@dimen/default_margin"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="5" android:layout_weight="5"

View File

@ -332,6 +332,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top" android:layout_gravity="top"
android:text="@string/settings" /> android:text="@string/settings" />
<Button
android:id="@+id/bDonate"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="@string/donate" />
</LinearLayout> </LinearLayout>

View File

@ -2,7 +2,7 @@
<resources> <resources>
<string name="ruleActivate">Aktiviere Regel %1$s</string> <string name="ruleActivate">Aktiviere Regel %1$s</string>
<string name="profileActivate">Aktiviere Profil %1$s</string> <string name="profileActivate">Aktiviere Profil %1$s</string>
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umschaltmodus</string> <string name="ruleActivateToggle">Aktiviere Regel %1$s im Umkehrmodus</string>
<string name="addPoi">Ort hinzufügen</string> <string name="addPoi">Ort hinzufügen</string>
<string name="addRule">Regel hinzufügen</string> <string name="addRule">Regel hinzufügen</string>
<string name="poiList">Orts-Liste:</string> <string name="poiList">Orts-Liste:</string>
@ -63,7 +63,7 @@
<string name="deactivating">Deaktiviere</string> <string name="deactivating">Deaktiviere</string>
<string name="bluetoothFailed">Änderung des Bluetooth Status fehlgeschlagen. Verfügt dieses Gerät über Bluetooth?</string> <string name="bluetoothFailed">Änderung des Bluetooth Status fehlgeschlagen. Verfügt dieses Gerät über Bluetooth?</string>
<string name="urlTooShort">Die Adresse ist zu kurz. Sie muß aus mindestens 10 Buchstaben bestehen.</string> <string name="urlTooShort">Die Adresse ist zu kurz. Sie muß aus mindestens 10 Buchstaben bestehen.</string>
<string name="textTooShort">Der Text ist zu kurz. Er muß aus mindestens 10 Buchstaben bestehen.</string> <string name="enterPhoneNumberAndText">Geben Sie eine Telefonnummer und einen Text ein.</string>
<string name="selectTypeOfTrigger">Welche Art von Auslöser</string> <string name="selectTypeOfTrigger">Welche Art von Auslöser</string>
<string name="entering">betrete</string> <string name="entering">betrete</string>
<string name="leaving">verlasse</string> <string name="leaving">verlasse</string>
@ -116,8 +116,8 @@
<string name="timeframes">Zeiträume</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="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string> <string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
<string name="toggableRules">Umkehrbare Regeln</string> <string name="toggableRules">Unschaltbare Regeln</string>
<string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umschaltbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umschaltbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string> <string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umkehrbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umkehrbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
<string name="helpTextProcessMonitoring">Wenn Sie eine Regel mit einer Prozess Überwachung erstellen, wird die Anwendung in regelmäßigen Abständen nach diesem Prozess schauen. Wie häufig können Sie in den Einstellungen festlegen. Das mag zwar in vielen Fällen langsam reagieren, aber eine permanente Überwachung würde zuviel Akkuleistung kosten. Und das Betriebssystem stellt dafür keinen Broadcast zur Verfügung.</string> <string name="helpTextProcessMonitoring">Wenn Sie eine Regel mit einer Prozess Überwachung erstellen, wird die Anwendung in regelmäßigen Abständen nach diesem Prozess schauen. Wie häufig können Sie in den Einstellungen festlegen. Das mag zwar in vielen Fällen langsam reagieren, aber eine permanente Überwachung würde zuviel Akkuleistung kosten. Und das Betriebssystem stellt dafür keinen Broadcast zur Verfügung.</string>
<string name="helpTitleEnergySaving">Energiespareinstellungen</string> <string name="helpTitleEnergySaving">Energiespareinstellungen</string>
<string name="helpTextEnergySaving">Viele Gerätehersteller versuchen Energie zu sparen, indem die Hintergrundaktivitäten vieler Anwendungen eingeschränkt werden. Unglücklicherweise führt das häufig dazu, dass diese Anwendungen nicht mehr zufällig funktionieren; das gilt auch für Automation. Schauen Sie sich <a href="https://dontkillmyapp.com/">diese Seite</a> an, um herauszufinden, wie Sie Automation auf Ihrem Gerät von dieser Behandlung ausschließen können.</string> <string name="helpTextEnergySaving">Viele Gerätehersteller versuchen Energie zu sparen, indem die Hintergrundaktivitäten vieler Anwendungen eingeschränkt werden. Unglücklicherweise führt das häufig dazu, dass diese Anwendungen nicht mehr zufällig funktionieren; das gilt auch für Automation. Schauen Sie sich <a href="https://dontkillmyapp.com/">diese Seite</a> an, um herauszufinden, wie Sie Automation auf Ihrem Gerät von dieser Behandlung ausschließen können.</string>
@ -305,7 +305,7 @@
<string name="currentId">Aktuelle Bezeichnung:</string> <string name="currentId">Aktuelle Bezeichnung:</string>
<string name="nfcTagDataNotUsable">Tag Daten nicht nutzbar, neu schreiben</string> <string name="nfcTagDataNotUsable">Tag Daten nicht nutzbar, neu schreiben</string>
<string name="nfcBringTagIntoRangeToRead">Bringen Sie einen Tag in Reichweite, um ihn zu lesen.</string> <string name="nfcBringTagIntoRangeToRead">Bringen Sie einen Tag in Reichweite, um ihn zu lesen.</string>
<string name="toggleRule">Umschaltregel</string> <string name="toggleRule">Umkehrregel</string>
<string name="toggling">Schalte um</string> <string name="toggling">Schalte um</string>
<string name="toggle">umzuschalten</string> <string name="toggle">umzuschalten</string>
<string name="overlapBetweenPois">Überschneidung mit Ort %1$s von %2$s Metern festgestellt. Reduzieren Sie den Radius um mindestens diesen Wert.</string> <string name="overlapBetweenPois">Überschneidung mit Ort %1$s von %2$s Metern festgestellt. Reduzieren Sie den Radius um mindestens diesen Wert.</string>
@ -337,7 +337,7 @@
<string name="outgoingCallTo">Ausgehender Telefonanruf von %1$s.</string> <string name="outgoingCallTo">Ausgehender Telefonanruf von %1$s.</string>
<string name="actionSpeakText">Text sprechen</string> <string name="actionSpeakText">Text sprechen</string>
<string name="textToSpeak">Zu sprechender Text</string> <string name="textToSpeak">Zu sprechender Text</string>
<string name="toggleNotAllowed">Die Umschaltfunktion ist momentan nur für Regeln erlaubt, die NFC Tags als Auslöser haben. Für weitere Informationen lesen Sie die Hilfe.</string> <string name="toggleNotAllowed">Die Umkehrfunktion ist momentan nur für Regeln erlaubt, die NFC Tags als Auslöser haben. Für weitere Informationen lesen Sie die Hilfe.</string>
<string name="errorReadingPoisAndRulesFromFile">Fehler beim Lesen von Orten und Regeln aus Datei.</string> <string name="errorReadingPoisAndRulesFromFile">Fehler beim Lesen von Orten und Regeln aus Datei.</string>
<string name="noDataChangedReadingAnyway">Es scheint als wären keine Datenänderungen gespeichert worden. Allerdings könnten Änderungen im Speicher sein, die zurückgenommen werden müssen. Daher wird die Einstellungsdatei neu geladen.</string> <string name="noDataChangedReadingAnyway">Es scheint als wären keine Datenänderungen gespeichert worden. Allerdings könnten Änderungen im Speicher sein, die zurückgenommen werden müssen. Daher wird die Einstellungsdatei neu geladen.</string>
<string name="bluetoothConnection">Bluetooth Verbindung</string> <string name="bluetoothConnection">Bluetooth Verbindung</string>
@ -410,8 +410,8 @@
<string name="noProfileChangeSoundLocked">Profil wird nicht aktiviert. Zuletzt aktiviertes Profil ist gesperrt worden.</string> <string name="noProfileChangeSoundLocked">Profil wird nicht aktiviert. Zuletzt aktiviertes Profil ist gesperrt worden.</string>
<string name="currentVolume">Momentane Lautstärke</string> <string name="currentVolume">Momentane Lautstärke</string>
<string name="enterValidReferenceValue">Geben Sie einen gültigen Referenzwert ein.</string> <string name="enterValidReferenceValue">Geben Sie einen gültigen Referenzwert ein.</string>
<string name="volumeTest">Lautstärkentest</string> <string name="volumeTest">Lautstärkekalibrierung</string>
<string name="volumeTesterExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string> <string name="volumeCalibrationExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
<string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string> <string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string> <string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string>
<string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string> <string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string>
@ -537,7 +537,7 @@
<string name="notificationTriggerExplanation">Dieser Auslöser reagiert auf Benachrichtigungen anderer Anwendung im Benachrichtigungsbereich von Android (oder wenn diese geschlossen werden). Sie können eine bestimmte Anwendung festlegen, von die Nachricht stammen muß. Wenn nicht, zählt jede Benachrichtigung. Sie können auch Zeichenketten für Titel oder Nachrichteninhalt festlegen, die enthalten sein müssen. Die Groß-/Kleinschreibung wird hierbei nicht berücksichtigt.</string> <string name="notificationTriggerExplanation">Dieser Auslöser reagiert auf Benachrichtigungen anderer Anwendung im Benachrichtigungsbereich von Android (oder wenn diese geschlossen werden). Sie können eine bestimmte Anwendung festlegen, von die Nachricht stammen muß. Wenn nicht, zählt jede Benachrichtigung. Sie können auch Zeichenketten für Titel oder Nachrichteninhalt festlegen, die enthalten sein müssen. Die Groß-/Kleinschreibung wird hierbei nicht berücksichtigt.</string>
<string name="addParameters">Parameter hinzufügen</string> <string name="addParameters">Parameter hinzufügen</string>
<string name="errorRunningRule">Fehler beim Ausführen einer Regel.</string> <string name="errorRunningRule">Fehler beim Ausführen einer Regel.</string>
<string name="startAppChoiceNote">Hier haben Sie 2 grundsätzliche Optionen:\n\n1. Sie können ein Programm starten, indem Sie eine Activity auswählen.\nStellen Sie sich das so vor, daß Sie ein bestimmtes Fenster einer Anwendung vorauswählen, in das man direkt springt. Behalten Sie im Kopf, daß das nicht immer funktionieren wird. Das liegt daran, daß die Fenster einer Anwendung miteinander interagieren können, sich u.U. Parameter übergeben. Wenn man jetzt ganz kalt in ein bestimmtes Fenster springt, könnte dieses zum Start z.B. bestimmte Parameter erwarten - die fehlen. So könnte es passieren, daß das Fenster zwar versucht zu öffnen, das aber nicht klappt und es somit nie wirlich sichtbar wird. Versuchen Sie\'s trotzdem!\nSie können den Pfad manuell eingeben, sollten aber den Auswählen-Knopf benutzen. Wenn Sie es dennoch manuell eingeben, geben Sie den PackageName ins obere Feld ein und den vollen Pfad der Activity ins untere.\n\n2. Auswahl per Action\nIm Gegensatz zur Auswahl eines bestimmten Fensters, können Sie ein Programm auch über eine Action starten lassen. Stellen Sie sich das so vor als würden Sie in den Wald rufen \"Ich hätte gerne XYZ\" und falls eine Anwendung installiert ist, die das liefern kann, wird sie gestartet. Ein gutes Beispiel wäre zum Beispiel "Browser starten" - es könnten sogar mehrere installiert sein, die das können (aber normalerweise gibts eine, die als Standard eingestellt ist).\nDiese Action müssen Sie manuell eingeben. Der PackageName ist hier optional. Behalten Sie dabei im Auge, daß mögliche Variablen nicht aufgelöst werden. Beispielsweise werden Sie häufig im Internet finden, daß man die Kamera über die Action \"MediaStore.ACTION_IMAGE_CAPTURE\" starten kann. Das ist grundsätzlich nicht richtig, wird aber nicht direkt funktionieren, denn das ist nur eine Variable. Sie müssen dann einen Blick in die Android Dokumentation werfen, wo Sie sehen werden, daß sich hinter dieser Variable eigentlich der Wert \"android.media.action.IMAGE_CAPTURE\" verbirgt. Gibt man diesen in das Feld ein, wird\'s funktionieren.</string> <string name="startAppChoiceNote">Hier haben Sie 2 grundsätzliche Optionen:\n\n1. Sie können ein Programm starten, indem Sie eine Activity auswählen.\nStellen Sie sich das so vor, daß Sie ein bestimmtes Fenster einer Anwendung vorauswählen, in das man direkt springt. Behalten Sie im Kopf, daß das nicht immer funktionieren wird. Das liegt daran, daß die Fenster einer Anwendung miteinander interagieren können, sich u.U. Parameter übergeben. Wenn man jetzt ganz kalt in ein bestimmtes Fenster springt, könnte dieses zum Start z.B. bestimmte Parameter erwarten - die fehlen. So könnte es passieren, daß das Fenster zwar versucht zu öffnen, das aber nicht klappt und es somit nie wirlich sichtbar wird. Versuchen Sie\'s trotzdem!\nSie können den Pfad manuell eingeben, sollten aber den Auswählen-Knopf benutzen. Wenn Sie es dennoch manuell eingeben, geben Sie den PackageName ins obere Feld ein und den vollen Pfad der Activity ins untere.\n\n2. Auswahl per Action\nIm Gegensatz zur Auswahl eines bestimmten Fensters, können Sie ein Programm auch über eine Action starten lassen. Stellen Sie sich das so vor als würden Sie in den Wald rufen \"Ich hätte gerne XYZ\" und falls eine Anwendung installiert ist, die das liefern kann, wird sie gestartet. Ein gutes Beispiel wäre zum Beispiel "Browser starten" - es könnten sogar mehrere installiert sein, die das können (aber normalerweise gibts eine, die als Standard eingestellt ist).\nDiese Action müssen Sie manuell eingeben. Der PackageName ist hier optional. Behalten Sie dabei im Auge, daß mögliche Variablen nicht aufgelöst werden. Beispielsweise werden Sie häufig im Internet finden, daß man die Kamera über die Action \"MediaStore.ACTION_IMAGE_CAPTURE\" starten kann. Das ist grundsätzlich richtig, wird aber nicht direkt funktionieren, denn das ist nur eine Variable. Sie müssen dann einen Blick in die Android Dokumentation werfen, wo Sie sehen werden, daß sich hinter dieser Variable eigentlich der Wert \"android.media.action.IMAGE_CAPTURE\" verbirgt. Gibt man diesen in das Feld ein, wird\'s funktionieren.</string>
<string name="cantFindSoundFile">Kann die Audiodatei %1$s nicht finden und daher auch nicht abspielen.</string> <string name="cantFindSoundFile">Kann die Audiodatei %1$s nicht finden und daher auch nicht abspielen.</string>
<string name="startAppByActivity">per Activity</string> <string name="startAppByActivity">per Activity</string>
<string name="startAppByAction">per Action</string> <string name="startAppByAction">per Action</string>
@ -595,4 +595,49 @@
<string name="bottom">Unten</string> <string name="bottom">Unten</string>
<string name="tabsPlacementSummary">Wol soll die Taskleiste angezeigt werden?</string> <string name="tabsPlacementSummary">Wol soll die Taskleiste angezeigt werden?</string>
<string name="tones">Klingeltöne</string> <string name="tones">Klingeltöne</string>
<string name="miscellaneous">Verschiedenes</string>
<string name="dnd">Nicht stören</string>
<string name="dndOff">Nicht stören aus</string>
<string name="dndAlarms">Alarme durchlassen</string>
<string name="dndPriority">Prioritätsbenachrichtigungen durchlassen</string>
<string name="dndNothing">Nichts durchlassen</string>
<string name="repeatEveryXseconds">Alle x Sekunden wiederholen</string>
<string name="repeatEveryXsecondsWithVariable">alle %1$s Sekunden wiederholen</string>
<string name="donate">Spenden</string>
<string name="notice">Hinweis</string>
<string name="automationNotificationsIgnored">Wenn Sie keine bestimmte Anwendung auswählen, werden Benachrichtigungen von Automation selbst ignoriert, um Schleifen zu verhindern.</string>
<string name="elementSkipped">Ein Element der Konfigurationsdatei konnte nicht gelesen werden. Die Datei könnte von einer neueren Programmversion erstellt worden sein.</string>
<string name="permissionsRequiredNotAvailable">Ihre Regeln benötigen Berechtigungen, die die installierte Variante von Automation nicht unterstützt.</string>
<string name="dndRemarks">Feineinstellungen (wie Telefonanrufe erlauben, Auswählen bestimmter Telefonnummern, etc.) können nur in den Systemeinstellungen gesetzt werden.</string>
<string name="wifiApi30">Weil Google wieder einen weiteren Teil von Android kaputt gemacht hat, können ab API 30 nur noch jede WLANs angezeigt werden, die sich gegenwärtig in Reichweite befinden, nicht mehr alle, zu denen das Gerät einmal verbunden war.</string>
<string name="smsDialogNotice">Wenn Sie in diesem Programm noch keine SMS-senden Aktion benutzt haben, zeigt Android wahrscheinlich beim ersten Ausführen einen Bestätigungsdialog an. Sie müssen das Häkchen bei \"Immer erlauben\" setzen und bestätigen, wenn Sie möchten, daß diese Aktion im Hintergrund ausgeführt werden kann. Es wird daher empfohlen, diese Regel einmalig manuell auszuführen, um diesen Dialog zu provozieren.</string>
<string name="silentTriggersDnd">Hinweis: Der Stumm-Modus löst auf neuren Geräten häufig die Funktion \"Nicht stören\" aus. Wenn das auf Ihrem Gerät passiert, wird empfohlen stattdessen den Normalen Modus zu verwenden und alle Lautstärken auf 0 zu reduzieren.</string>
<string name="deviceOrientation">Geräteausrichtung</string>
<string name="tolerance">Toleranz (0-180)</string>
<string name="orientationAzimuth">Azimut:</string>
<string name="orientationPitch">Neigung:</string>
<string name="enterValidNumbersIntoAllFields">Geben Sie gültige Nummern in allen Feldern ein.</string>
<string name="orientationRoll">Rollen:</string>
<string name="wouldCurrentlyApply">Würde gerade zutreffen?</string>
<string name="deviceIsInCertainOrientation">Das Gerät hat eine bestimmte Ausrichtung</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">Eine Toleranz von 180 ist nur für zwei Toleranz-Felder erlaubt, nicht alle drei. Andernfalls würde der Auslöser immer zutreffen.</string>
<string name="unknown">unbekannt</string>
<string name="orientation">Ausrichtung</string>
<string name="turnScreenOnOrOff">Bildschirm ein- oder ausschalten</string>
<string name="turnScreenOn">Bildschirm einschalten</string>
<string name="turnScreenOff">Bildschirm ausschalten</string>
<string name="mustApply">Muß zutreffen</string>
<string name="deviceOrientationTimeAcceptIntervalTitle">Signal Häufigkeit</string>
<string name="deviceOrientationTimeAcceptIntervalSummary">Neue Signale nur alle x Millisekunden akzeptieren</string>
<string name="deviceOrientationSettings">Geräteausrichtungseinstellungen</string>
<string name="explanationDeviceOrientationDirection">Wenn das Häkchen gesetzt ist, bedeutet das, daß das Geräte in der angegebenen Ausrichtung sein muß. Wenn es nicht gesetzt ist, führt jede andere Ausrichtung zu einem positiven Ergebnis.</string>
<string name="deviceOrientationExplanation">Wenn Sie Ihr Gerät bewegen, werden die Zahlen unten aktualisiert. Was Sie hier sehen können, ist die momentane Ausrichtung Ihres Geräts, gemessen in Grad. Wenn das Gerät in der gewünschten Ausrichtung ist, klicken Sie den \"übernehmen\" Knopf, um die Werte in die \"gewünscht\" Felder zu übertragen.\nWeil es sehr unwahrscheinlich ist, daß Sie diese exakte Ausrichtung jemals wieder erreichen, müssen Sie Toleranzen eingeben. Dies ist der Winkel in Grad, der in jede Richtung noch akzeptiert wird. 15° entsprechen somit einem Gesamtwinkel von 30°, 15 in jede Richtung.\nWenn Ihnen nur eine bestimmte Achse wichtig ist, können Sie eine Toleranz von 180° für die anderen beiden Richtungen angeben.</string>
<string name="actionSetBluetoothTethering">Bluetooth Tethering</string>
<string name="actionTurnBluetoothTetheringOn">Bluetooth Tethering einschalten</string>
<string name="actionTurnBluetoothTetheringOff">Bluetooth Tethering ausschalten</string>
<string name="enterRepetitionTime">Sie müssen eine positive Ganzzahl als Wiederholungszeit eingeben.</string>
<string name="btTetheringNotice">Diese Funktion funktioniert bestätigt bis einschließlich Android 8.0. Ab einer höheren Version funktioniert sie nicht mehr, aber ich ich kann mangels physischer Geräte nicht sagen, aber welcher genau. Unter Android 11 funktioniert es definitiv nicht mehr. Wenn Sie eine Version dazwischen haben, lassen Sie mich bitte wissen, ob es funktioniert oder nicht.</string>
<string name="triggerWrong">Mit diesem Auslöser stimmt etwas nicht. Er konnte nicht korrekt geladen werden.</string>
<string name="android.permission.BIND_DEVICE_ADMIN">Geräte Administrator</string>
<string name="deviceAdminNote">Geräte Administrator Rechte werden für mindestens 1 Regel benötigt, die Sie angelegt haben.</string>
</resources> </resources>

View File

@ -333,7 +333,7 @@
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leer notificaciónes del sistema</string> <string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leer notificaciónes del sistema</string>
<string name="bluetoothFailed">No pude activar o desactivar Bluetooth. Tiene el dispositvo Bluetooth?</string> <string name="bluetoothFailed">No pude activar o desactivar Bluetooth. Tiene el dispositvo Bluetooth?</string>
<string name="urlTooShort">El url tiene que tener mínimo 10 caracteres.</string> <string name="urlTooShort">El url tiene que tener mínimo 10 caracteres.</string>
<string name="textTooShort">El texto tiene que tener mínimo 10 caracteres.</string> <string name="enterPhoneNumberAndText">Introduce un número de teléfono y un mensaje de texto.</string>
<string name="onOff">On/Off</string> <string name="onOff">On/Off</string>
<string name="useTextToSpeechOnNormalSummary">Usar TextToSpeech en un perfil normal</string> <string name="useTextToSpeechOnNormalSummary">Usar TextToSpeech en un perfil normal</string>
<string name="useTextToSpeechOnVibrateSummary">Usar TextToSpeech en un perfil vibración</string> <string name="useTextToSpeechOnVibrateSummary">Usar TextToSpeech en un perfil vibración</string>
@ -472,7 +472,7 @@
<string name="showIcon">Monstrar icono</string> <string name="showIcon">Monstrar icono</string>
<string name="showIconWhenServiceIsRunning">Monstrar icono cuando el servicio esta activo (ocultando solo funciona antes Android 7)</string> <string name="showIconWhenServiceIsRunning">Monstrar icono cuando el servicio esta activo (ocultando solo funciona antes Android 7)</string>
<string name="currentVolume">Volumen actual</string> <string name="currentVolume">Volumen actual</string>
<string name="volumeTest">Prueba de volumen</string> <string name="volumeTest">Calibrado de volumen</string>
<string name="permissionsTitle">Permisos necesarios</string> <string name="permissionsTitle">Permisos necesarios</string>
<string name="disabledFeatures">Funciones desactivadas</string> <string name="disabledFeatures">Funciones desactivadas</string>
<string name="invalidDevice">Dispositivo no valido.</string> <string name="invalidDevice">Dispositivo no valido.</string>
@ -547,7 +547,7 @@
<string name="permissionsExplanationSmall">Para activar la función que será usada, mas permisos son necesarios. Cliquee continuar para los requisitos.</string> <string name="permissionsExplanationSmall">Para activar la función que será usada, mas permisos son necesarios. Cliquee continuar para los requisitos.</string>
<string name="storeSettings">Leer y guardar configuración.</string> <string name="storeSettings">Leer y guardar configuración.</string>
<string name="featuresDisabled">CUIDADO: Funciones estan desactivadas, Automation esta en modo limitado. Cliquee aqui para mas informacion.</string> <string name="featuresDisabled">CUIDADO: Funciones estan desactivadas, Automation esta en modo limitado. Cliquee aqui para mas informacion.</string>
<string name="volumeTesterExplanation">Para calcular un valor dB para determinar el nivel del ruido de fondo tiene que especificar un valor de referencia fisico. Por favor lea el articulo en Wikipedia para mas información. Este valor será probablemente diferente para todos los dispositivos. Mueva el regulador para cambiar el valor. Cuanto mas alto el valor de referencia menos será el valor dB. Las mediciónes se harán cada %1$s segundos y el resultado aparecerá abajo. Presione atrás cuando encuentre un valor indicado.</string> <string name="volumeCalibrationExplanation">Para calcular un valor dB para determinar el nivel del ruido de fondo tiene que especificar un valor de referencia fisico. Por favor lea el articulo en Wikipedia para mas información. Este valor será probablemente diferente para todos los dispositivos. Mueva el regulador para cambiar el valor. Cuanto mas alto el valor de referencia menos será el valor dB. Las mediciónes se harán cada %1$s segundos y el resultado aparecerá abajo. Presione atrás cuando encuentre un valor indicado.</string>
<string name="systemSettingsNote1">El permiso para cambiar ajustes del OS es necesario (incluso cosas simples como activar bluetooth o wifi). Despues de cliquear continuar una ventana aparecerá en la cual tiene que activar eso para Automation. Entonces cliquee el boton atrás.</string> <string name="systemSettingsNote1">El permiso para cambiar ajustes del OS es necesario (incluso cosas simples como activar bluetooth o wifi). Despues de cliquear continuar una ventana aparecerá en la cual tiene que activar eso para Automation. Entonces cliquee el boton atrás.</string>
<string name="systemSettingsNote2">Mas permisos serán requeridos en un segundo dialogo luego.</string> <string name="systemSettingsNote2">Mas permisos serán requeridos en un segundo dialogo luego.</string>
<string name="appRequiresPermissiontoAccessExternalStorage">Automation necesita acceso al almacenamiento externo para leer su configuración y reglas.</string> <string name="appRequiresPermissiontoAccessExternalStorage">Automation necesita acceso al almacenamiento externo para leer su configuración y reglas.</string>
@ -578,7 +578,7 @@
<string name="settingsReferringToRestrictedFeatures">Su configuración y/o reglas actualmente referencian caracteristicas no-libres no seran proveidas en la versión F-Droid. Esto incluye determinar su actual actividad fisica.</string> <string name="settingsReferringToRestrictedFeatures">Su configuración y/o reglas actualmente referencian caracteristicas no-libres no seran proveidas en la versión F-Droid. Esto incluye determinar su actual actividad fisica.</string>
<string name="filesHaveBeenMovedTo">Automation ahora usa otra ruta para guardar sus archivos. Todos sus archivos de Automation fueron desplazados aqui: \"%s\". El permiso del almacenamiento externo todavia no es necesario; puede revocarlo. Sera eliminado en una futura versión.</string> <string name="filesHaveBeenMovedTo">Automation ahora usa otra ruta para guardar sus archivos. Todos sus archivos de Automation fueron desplazados aqui: \"%s\". El permiso del almacenamiento externo todavia no es necesario; puede revocarlo. Sera eliminado en una futura versión.</string>
<string name="newsOptIn">Quiere recibir noticias (solo importantes) en la pantalla principal? Estas serán descargadas de la pagina del desarollador. No habrán notificaciones inoportunas, solo un texto en la pantalla principal cuando abra la app.</string> <string name="newsOptIn">Quiere recibir noticias (solo importantes) en la pantalla principal? Estas serán descargadas de la pagina del desarollador. No habrán notificaciones inoportunas, solo un texto en la pantalla principal cuando abra la app.</string>
<string name="filesStoredAt">Config y archivos de log seran guardados en el directorio %1$s. Cliquee en este texto para abrir un administrador de archivos. Desafortunadamente solo funciona en un dispositivo rooted. PARA OTROS DISP.: Simplemente use el boton para crear un backup.</string> <string name="filesStoredAt">Config y archivos de log seran guardados en el directorio %1$s. Cliquee en este texto para abrir un administrador de archivos. Desafortunadamente solo funciona en un dispositivo rooted.\n\nPARA OTROS DISP.: Simplemente use el boton para crear un backup.</string>
<string name="notificationTriggerExplanation">Esta condición responde a todas las aplicaciones que abren o cierran notificaciones en el areal notificaciones. Puedes especificar otra aplicación de que la notificación tiene que venir. Si no la notificación puede originarse de cualquier app. Tambien puedes especificar strings que (/no) tienen que estar en en titulo o el texto de la notificación. La comparación es insensible a minúsculas y mayúsculas.</string> <string name="notificationTriggerExplanation">Esta condición responde a todas las aplicaciones que abren o cierran notificaciones en el areal notificaciones. Puedes especificar otra aplicación de que la notificación tiene que venir. Si no la notificación puede originarse de cualquier app. Tambien puedes especificar strings que (/no) tienen que estar en en titulo o el texto de la notificación. La comparación es insensible a minúsculas y mayúsculas.</string>
<string name="alwaysPlayExplanation">Si este ajuste esta activo el sonido será reproducido siempre. Si esta inactivo el sonido solo será reproducido si su dispositivo ni esta en mute ni en vibración. Pero si esta activo cambiará el volumen. Tambien si su dispositivo esta en el modo timbre el volumen multimedia no será cambiado por ejemplo. En resumen si el volumen multimedia esta en mute no escuchará nada.</string> <string name="alwaysPlayExplanation">Si este ajuste esta activo el sonido será reproducido siempre. Si esta inactivo el sonido solo será reproducido si su dispositivo ni esta en mute ni en vibración. Pero si esta activo cambiará el volumen. Tambien si su dispositivo esta en el modo timbre el volumen multimedia no será cambiado por ejemplo. En resumen si el volumen multimedia esta en mute no escuchará nada.</string>
<string name="shareConfigAndLogExplanation">Esto comenzará un nuevo email con su config y los archivos de log adjunto como archivo zip. No será enviado automaticamente. Todavia tiene que cliquear \"enviar\". Tambien puede cambiar el receptor a si mismo por ejemplo.</string> <string name="shareConfigAndLogExplanation">Esto comenzará un nuevo email con su config y los archivos de log adjunto como archivo zip. No será enviado automaticamente. Todavia tiene que cliquear \"enviar\". Tambien puede cambiar el receptor a si mismo por ejemplo.</string>
@ -594,4 +594,49 @@
<string name="locationEngineDisabledLong">Desafortunadamente su posición todavia no puede ser determinada. Gratitud va para Google por su sabiduria y amabilidad infinita.\n\nDejenme explicarselo mas. Comenzando con Android 10 un nuevo permiso se introdujo que es necesario para determinar la posición en el fondo (que es necesario para una app como esta). Aunque lo considero una buena idea, conlleva a una chicana para desarolladores.\n\nCuando se esta desarrollando una app se puede intentar calificar para este permiso mientras se sigue un catalogo de condiciones. Desafortunadamente nuevas versiones de mi app fueron rechazadas por un periodo de trés meses. Cumplé todas las condiciones, pero Google\'s mierda servicio para desarolladores afirmó que no. Despues de presentar pruebas, que cumplí con todo, recibí una respuesta de \"No puedo ayudarte mas.\". En algun momento me rendí.\n\nComo consecuencia la version Google Play todavia no sabe usar la locación como una condición. Mi única alternativa fue remover la applicación de Google Play.\n\nLo siento mucho, pero hicé todo lo posible para discutir con un support que no sabe aprobar la prueba de Turing repetidamente.\n\nLa noticia positiva: Usted todavia puede tener todo!\n\nAutomation ahora es open source y se puede encontrar en F-Droid. Es un app store que se preocupa por su privacidad - en vez de solo simular eso. Simplemente guarde su configuración, desinstale la app, instale la de F-Droid, restaure su configuración - terminado.\n\nCliquee aqui para averiguar más:</string> <string name="locationEngineDisabledLong">Desafortunadamente su posición todavia no puede ser determinada. Gratitud va para Google por su sabiduria y amabilidad infinita.\n\nDejenme explicarselo mas. Comenzando con Android 10 un nuevo permiso se introdujo que es necesario para determinar la posición en el fondo (que es necesario para una app como esta). Aunque lo considero una buena idea, conlleva a una chicana para desarolladores.\n\nCuando se esta desarrollando una app se puede intentar calificar para este permiso mientras se sigue un catalogo de condiciones. Desafortunadamente nuevas versiones de mi app fueron rechazadas por un periodo de trés meses. Cumplé todas las condiciones, pero Google\'s mierda servicio para desarolladores afirmó que no. Despues de presentar pruebas, que cumplí con todo, recibí una respuesta de \"No puedo ayudarte mas.\". En algun momento me rendí.\n\nComo consecuencia la version Google Play todavia no sabe usar la locación como una condición. Mi única alternativa fue remover la applicación de Google Play.\n\nLo siento mucho, pero hicé todo lo posible para discutir con un support que no sabe aprobar la prueba de Turing repetidamente.\n\nLa noticia positiva: Usted todavia puede tener todo!\n\nAutomation ahora es open source y se puede encontrar en F-Droid. Es un app store que se preocupa por su privacidad - en vez de solo simular eso. Simplemente guarde su configuración, desinstale la app, instale la de F-Droid, restaure su configuración - terminado.\n\nCliquee aqui para averiguar más:</string>
<string name="startAppChoiceNote">Aqui tiene 2 opciones generales:\\n\\n1. Puede encender un programa seleccionando un activity. Imagine eso como preseleccionar una pantalla/ventana especifica de una aplicación. Tenga en cuenta que no siempre funcionará. Eso es porque las ventanas de una app pueden interactuar entre ellas, por ejemplo dar parametros. Si se abre una ventana especifica directamente esta interacción todavia no ha ocurrido y la ventana se podría cerrar al instante (por lo tanto nunca será presentada). Pruebe esto sin embargo! Puede introducir una trayectoria de una activity manualmente, pero es recomendable usar el boton \"Elegir\". Si decide introducir la trayectoria de la app manualmente en la casilla de arriba y la trayectoria completa de una activity en la de abajo.\\n\\n2.Elección con action\\nContrariamente a elegir una ventana especifica, tambien puede encender una app con un action. Es similar a llamar \"Queria xyz\" y si hay una app que le puede ayudar a usted sera encendida. Un ejemplo bueno seria \"abrir browser\" - podria tener multiples (una normalemente es el valor predeterminado). Usted necesita introducirlo manualmente, PackageName es opcional aqui. Tenga en cuenta las variables no seran resueltas. Si por ejemplo quiere encender la camara usando \"MediaStore.ACTION_IMAGE_CAPTURE\" no va a funcionar. Tiene que mirar en la documentación de Android y usar el valor real de esta variable que - en este ejemplo - seria \"android.media.action.IMAGE_CAPTURE\".</string> <string name="startAppChoiceNote">Aqui tiene 2 opciones generales:\\n\\n1. Puede encender un programa seleccionando un activity. Imagine eso como preseleccionar una pantalla/ventana especifica de una aplicación. Tenga en cuenta que no siempre funcionará. Eso es porque las ventanas de una app pueden interactuar entre ellas, por ejemplo dar parametros. Si se abre una ventana especifica directamente esta interacción todavia no ha ocurrido y la ventana se podría cerrar al instante (por lo tanto nunca será presentada). Pruebe esto sin embargo! Puede introducir una trayectoria de una activity manualmente, pero es recomendable usar el boton \"Elegir\". Si decide introducir la trayectoria de la app manualmente en la casilla de arriba y la trayectoria completa de una activity en la de abajo.\\n\\n2.Elección con action\\nContrariamente a elegir una ventana especifica, tambien puede encender una app con un action. Es similar a llamar \"Queria xyz\" y si hay una app que le puede ayudar a usted sera encendida. Un ejemplo bueno seria \"abrir browser\" - podria tener multiples (una normalemente es el valor predeterminado). Usted necesita introducirlo manualmente, PackageName es opcional aqui. Tenga en cuenta las variables no seran resueltas. Si por ejemplo quiere encender la camara usando \"MediaStore.ACTION_IMAGE_CAPTURE\" no va a funcionar. Tiene que mirar en la documentación de Android y usar el valor real de esta variable que - en este ejemplo - seria \"android.media.action.IMAGE_CAPTURE\".</string>
<string name="tones">Sonidos</string> <string name="tones">Sonidos</string>
<string name="dnd">No interrumpir</string>
<string name="donate">Donar</string>
<string name="notice">Nota</string>
<string name="deviceOrientation">Orientación</string>
<string name="tolerance">Tolerancia</string>
<string name="orientationAzimuth">" Acimut:"</string>
<string name="turnScreenOff">apagar pantalla</string>
<string name="turnScreenOn">encender pantalla</string>
<string name="actionSetBluetoothTethering">Enrutador Bluetooth</string>
<string name="actionTurnBluetoothTetheringOn">activar enrutador Bluetooth</string>
<string name="actionTurnBluetoothTetheringOff">desactivar enrutador Bluetooth</string>
<string name="miscellaneous">Misceláneo</string>
<string name="dndOff">No interrumpir apagado</string>
<string name="dndPriority">Permitir notificaciones prioritarias</string>
<string name="dndAlarms">Permitir alarmas</string>
<string name="dndNothing">Permitir nada</string>
<string name="unknown">desconocido</string>
<string name="orientation">Orientación</string>
<string name="turnScreenOnOrOff">Activar o desactivar pantalla</string>
<string name="mustApply">Debe aplicar</string>
<string name="deviceOrientationTimeAcceptIntervalTitle">Frecuencia de señal</string>
<string name="deviceOrientationSettings">Configuración del orientación del dispositivo</string>
<string name="android.permission.BIND_DEVICE_ADMIN">Administrador del dispositivo</string>
<string name="orientationRoll">Rotación:</string>
<string name="orientationPitch">Inclinación:</string>
<string name="wouldCurrentlyApply">¿Se aplicaría actualmente?</string>
<string name="repeatEveryXseconds">Repetir cada x segundos</string>
<string name="repeatEveryXsecondsWithVariable">repetir cada %1$s segundos</string>
<string name="permissionsRequiredNotAvailable">Sus reglas requerían permisos que no se pueden solicitar a este tipo instalado de Automation.</string>
<string name="automationNotificationsIgnored">Si no elige una aplicación específica, sino que elige \"Cualquier aplicación\", las notificaciones de Automatización se ignorarán para evitar bucles.</string>
<string name="enterRepetitionTime">Debe insertar un valor positivo no decimal para el tiempo de repetición.</string>
<string name="elementSkipped">No se pudo leer un elemento del archivo de configuración. El archivoo puede haber sido creado por una versión más reciente del programa.</string>
<string name="enterValidNumbersIntoAllFields">Introduzca números válidos en todos los campos.</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">Se permite una tolerancia de 180 solo para 2 campos de tolerancia, no para todos los 3. De lo contrario, el disparador SIEMPRE se aplicaría.</string>
<string name="triggerWrong">Hay algo mal con este condición. No se pudo cargar correctamente.</string>
<string name="deviceOrientationTimeAcceptIntervalSummary">Aceptar nuevas señales de movimiento cada x milisegundos</string>
<string name="deviceAdminNote">Se requieren permisos de administrador de dispositivo para al mens 1 reglas que haya creado.</string>
<string name="dndRemarks">El ajuste fino (como permitir llamadas telefónicas, elegir números específicos, etc.) solo se puede hacer desde la configuración del sistema.</string>
<string name="btTetheringNotice">Se confirma que esta función funcionará hasta Android 8.0. A partir de alguna versión superior deja de funcionar, pero debido a la falta de dispositivos físicos no puedo decir cuál es. En Android 11 definitivamente ya no funciona. Si tiene una versión intermedia, hágamelo saber si está funcionando o no.</string>
<string name="deviceIsInCertainOrientation">el dispositivo esta en una orientación determinada</string>
<string name="explanationDeviceOrientationDirection">Si la casilla de verificación está marcada, significa que el dispositivo debe estar en la orientación que especifique. Si no está marcado, cualquier orientación que NO coincida con sus criterios servirá.</string>
<string name="silentTriggersDnd">OBSERVACIÓN: El modo silencioso a menudo activa No-Interrumpir en dispositivos más nuevos. Si eso sucede en su dispositivo, le recomiendo usar el modo normal en su lugar y reducir todos los volúmenes a cero.</string>
<string name="wifiApi30">Porque Google arruinó otra parte de Android, a partir de API 30 solo se puede mostrar los wifi actualmente visibles, ya no todos que su positivo tiene conectados.</string>
<string name="smsDialogNotice">Si no ha utilizado una acción de envío de sms en este programa antes, Android puede mostrar un diálogo de confirmación adicional, pidiéndole que permita el envío de mensajes. Debe seleccionar la casilla de verificación \"permitir siempre\" y confirmar si desea que esta acción funcione en segundo plano. Se recomienda ejecutar esta regla manualmente una vez para provocar este diálogo de confirmación.</string>
<string name="deviceOrientationExplanation">Cuando mueva su dispositivo, los siguientes números se actualizarán. Lo que puede ver allí, es la orientación actual de su dispositivo medida en grados. Si está en la orientación deseada, haga clic en el botón Aplicar para copiar los valores actuales en los campos deseados. Debido a que alcanzar esta orientación exacta nunca más es muy poco probable, también deba ingresar a una tolerancia. Esta es la cantidad de grados a los que la orientación puede desviarse en cualquier dirección. 15° resultará en un ángulo total de 30°, 15° en todas las direcciones. Si solo le importa un eje específico, especifique una tolerancia de 180° para los otros dos.</string>
</resources> </resources>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2">
<string name="ConfigurationExportError">C\'è stato un errore durante l\'esportazione della configurazione.</string> <string name="ConfigurationExportError">C\'è stato un errore durante l\'esportazione della configurazione.</string>
<string name="accelerometer">Accelerometro</string> <string name="accelerometer">Accelerometro</string>
@ -14,7 +14,7 @@
<string name="actionSetDataConnectionOff">disattiva la connessione mobile</string> <string name="actionSetDataConnectionOff">disattiva la connessione mobile</string>
<string name="actionSetDataConnectionOn">attiva la connessione mobile</string> <string name="actionSetDataConnectionOn">attiva la connessione mobile</string>
<string name="actionSetDisplayRotation">Rotazione dello schermo</string> <string name="actionSetDisplayRotation">Rotazione dello schermo</string>
<string name="actionSetUsbTethering">Tethering USB</string> <string name="actionSetUsbTethering">USB Tethering</string>
<string name="actionSetWifi">Wifi</string> <string name="actionSetWifi">Wifi</string>
<string name="actionSetWifiTethering">Wifi Tethering</string> <string name="actionSetWifiTethering">Wifi Tethering</string>
<string name="actionSpeakText">Pronuncia testo</string> <string name="actionSpeakText">Pronuncia testo</string>
@ -230,7 +230,7 @@
<string name="helpTextRules">Una regola sarà eseguita quando tutti i suoi eventi risultano veri. Basta che solo un evento non sia eseguito e la regola non si attiverà. Per eseguire una regola in base a diversi eventi individuali, è sufficiente creare regole specifiche per ogni set di eventi.</string> <string name="helpTextRules">Una regola sarà eseguita quando tutti i suoi eventi risultano veri. Basta che solo un evento non sia eseguito e la regola non si attiverà. Per eseguire una regola in base a diversi eventi individuali, è sufficiente creare regole specifiche per ogni set di eventi.</string>
<string name="helpTextSound">Nello schermo principale puoi bloccare temporaneamente i cambi ai suoni per evitare l\'esecuzione di regole che facciano cambi alle attività sonore. Per esempio, potresti essere in una situatione o in un luogo dove normalmente ascoltare il suono di una suoneria è ok, ma in questa occasione bisognerebbe evitarlo. Questa funzione si disattiverà automaticamente non appena sia trascorso il tempo selezionato. Fai Click sul bottone + per raggiungere la quantità di tempo desiderata. Una volta attiva, questa si può disattivare nuovamente usando il pulsante di attivazione (e in questo modo, si riattiveranno le regole basate su cambi sonori).</string> <string name="helpTextSound">Nello schermo principale puoi bloccare temporaneamente i cambi ai suoni per evitare l\'esecuzione di regole che facciano cambi alle attività sonore. Per esempio, potresti essere in una situatione o in un luogo dove normalmente ascoltare il suono di una suoneria è ok, ma in questa occasione bisognerebbe evitarlo. Questa funzione si disattiverà automaticamente non appena sia trascorso il tempo selezionato. Fai Click sul bottone + per raggiungere la quantità di tempo desiderata. Una volta attiva, questa si può disattivare nuovamente usando il pulsante di attivazione (e in questo modo, si riattiveranno le regole basate su cambi sonori).</string>
<string name="helpTextTimeFrame">Se si specifica una regola con un intervallo temporale si hanno due scelte. È possibile scegliere se si desidera attivare la regola all\'interno o all\'esterno dell\'intervallo di tempo. In entrambi i casi l\'azione verrà eseguita una sola volta. Quindi, se si crea una regola che imposta il profilo su vibrazione nell\'intervallo temporale xyz, il telefono, passato allo stato vibrazione, rimarrà definitivamente in tale stato anche dopo lo scadere dell\'intervallo di tempo. Se si desidera che ciò avvenga è necessario specificare un\'altra regola con un altro periodo di tempo.</string> <string name="helpTextTimeFrame">Se si specifica una regola con un intervallo temporale si hanno due scelte. È possibile scegliere se si desidera attivare la regola all\'interno o all\'esterno dell\'intervallo di tempo. In entrambi i casi l\'azione verrà eseguita una sola volta. Quindi, se si crea una regola che imposta il profilo su vibrazione nell\'intervallo temporale xyz, il telefono, passato allo stato vibrazione, rimarrà definitivamente in tale stato anche dopo lo scadere dell\'intervallo di tempo. Se si desidera che ciò avvenga è necessario specificare un\'altra regola con un altro periodo di tempo.</string>
<string name="helpTextToggable">Le regole hanno un segno di spunta chiamato "Reversibile". Ciò significa che, se una regola viene eseguita al verificarsi di un evento e poi quest\'ultimo si verifica una seconda volta, il comando della regola verrà eseguito una ulteriore volta in modalità inversa, se possibile. Attualmente questo avverrà solo in combinazione con i tag NFC. Se li si tocca due volte la regola associata invertirà la situazione attuale. Per esempio una regola “Reversibile” può disattivare il WiFi se attivo e viceversa attivarlo se non attivo.</string> <string name="helpTextToggable">Le regole hanno un segno di spunta chiamato "Reversibile". Ciò significa che, se una regola viene eseguita al verificarsi di un evento e poi quest\'ultimo si verifica una seconda volta, il comando della regola verrà eseguito una ulteriore volta in modalità inversa, se possibile. Attualmente questo avverrà solo in combinazione con etichette NFC. Se le si tocca due volte la regola associata invertirà la situazione attuale. Per esempio una regola “Reversibile” può disattivare il WiFi se attivo e viceversa attivarlo se non attivo.</string>
<string name="helpTitleEnergySaving">Risparmio energetico</string> <string name="helpTitleEnergySaving">Risparmio energetico</string>
<string name="hint">Suggerimento</string> <string name="hint">Suggerimento</string>
<string name="httpAcceptAllCertificatesSummary">Salta il controllo dei certificati SSL (si consiglia di non attivarlo)</string> <string name="httpAcceptAllCertificatesSummary">Salta il controllo dei certificati SSL (si consiglia di non attivarlo)</string>
@ -293,24 +293,24 @@
<string name="newNfcId">Scrivi un nuovo ID NFC</string> <string name="newNfcId">Scrivi un nuovo ID NFC</string>
<string name="newThreadRules">Nuova discussione</string> <string name="newThreadRules">Nuova discussione</string>
<string name="newsOptIn">Vuoi ricevere delle notizie su questa app (solo quelle importanti) nella schermata principale? Queste vengono scaricate dal sito web dello sviluppatore. Non ci sarà nessuna notifica intrusiva, solo un testo nella schermata principale quando apri l\'app.</string> <string name="newsOptIn">Vuoi ricevere delle notizie su questa app (solo quelle importanti) nella schermata principale? Queste vengono scaricate dal sito web dello sviluppatore. Non ci sarà nessuna notifica intrusiva, solo un testo nella schermata principale quando apri l\'app.</string>
<string name="nfcApplyTagToRule">Applicazione del tag alla regola</string> <string name="nfcApplyTagToRule">Applicazione della etichetta alla regola</string>
<string name="nfcBringTagIntoRange">Portare un tag NFC nel campo d\'azione.</string> <string name="nfcBringTagIntoRange">Portare una etichetta NFC nel campo d\'azione.</string>
<string name="nfcBringTagIntoRangeToRead">Avvicina il TAG da leggere.</string> <string name="nfcBringTagIntoRangeToRead">Avvicina la etichetta da leggere.</string>
<string name="nfcEnterValidIdentifier">Inserire un nome valido per il tag (come "Porta d\'ingresso di casa").</string> <string name="nfcEnterValidIdentifier">Inserire un nome valido per l\'etichetta (come "Porta d\'ingresso di casa").</string>
<string name="nfcNoNdefIntentBut">Nessun intento NFC NDEF, ma</string> <string name="nfcNoNdefIntentBut">Nessun intento NFC NDEF, ma</string>
<string name="nfcNoTag">Nessun tag rilevato.</string> <string name="nfcNoTag">Nessuna etichetta rilevata.</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC non ancora supportato in questa versione di Android.</string> <string name="nfcNotSupportedInThisAndroidVersionYet">NFC non ancora supportato in questa versione di Android.</string>
<string name="nfcReadTag">Lettura ID dal tag</string> <string name="nfcReadTag">Lettura ID dall\'etichetta</string>
<string name="nfcTag">Tag NFC</string> <string name="nfcTag">Etichetta NFC</string>
<string name="nfcTagDataNotUsable">Dati del tag non leggibili, si prega di riscriverli.</string> <string name="nfcTagDataNotUsable">Dati dell\'etichetta non leggibili, si prega di riscriverli.</string>
<string name="nfcTagDiscovered">Tag rilevato</string> <string name="nfcTagDiscovered">Etichetta rilevata</string>
<string name="nfcTagFoundWithText">Trovato Tag con testo:</string> <string name="nfcTagFoundWithText">Trovata etichetta con testo:</string>
<string name="nfcTagReadSuccessfully">Tag letto con successo.</string> <string name="nfcTagReadSuccessfully">Etichetta letta con successo.</string>
<string name="nfcTagWriteError">Errore di scrittura sul tag. È sufficientemente vicino?</string> <string name="nfcTagWriteError">Errore di scrittura dell\'etichetta. È sufficientemente vicina?</string>
<string name="nfcTagWrittenSuccessfully">Scrittura Tag eseguita con successo.</string> <string name="nfcTagWrittenSuccessfully">Scrittura dell\'etichetta eseguita con successo.</string>
<string name="nfcUnsupportedEncoding">Codifica non supportata:</string> <string name="nfcUnsupportedEncoding">Codifica non supportata:</string>
<string name="nfcValueNotSuitable">Valore memorizzato non adatto.</string> <string name="nfcValueNotSuitable">Valore memorizzato non adatto.</string>
<string name="nfcWriteTag">Scrittura tag</string> <string name="nfcWriteTag">Scrittura etichetta</string>
<string name="no">No</string> <string name="no">No</string>
<string name="noApplicableFilesFoundInDirectory">Nessun file adatto è stato trovato in quella directory.</string> <string name="noApplicableFilesFoundInDirectory">Nessun file adatto è stato trovato in quella directory.</string>
<string name="noChangeSelectedProfileDoesntMakeSense">Nessun cambiamento selezionato. Questo profilo non ha senso.</string> <string name="noChangeSelectedProfileDoesntMakeSense">Nessun cambiamento selezionato. Questo profilo non ha senso.</string>
@ -500,7 +500,7 @@
<string name="textMessageAnnotations">Puoi inserire direttamente un numero di telefono. In alternativa usa l\'opzione contatti per sceglierne uno. Ma tieni presente che il numero verrà memorizzato qui, non nel contatto. Se cambi il numero di telefono di un contatto, dovrai aggiornarlo nella questa regola. Non si aggiorna da solo.</string> <string name="textMessageAnnotations">Puoi inserire direttamente un numero di telefono. In alternativa usa l\'opzione contatti per sceglierne uno. Ma tieni presente che il numero verrà memorizzato qui, non nel contatto. Se cambi il numero di telefono di un contatto, dovrai aggiornarlo nella questa regola. Non si aggiorna da solo.</string>
<string name="textToSend">Testo da inviare</string> <string name="textToSend">Testo da inviare</string>
<string name="textToSpeak">Testo da leggere</string> <string name="textToSpeak">Testo da leggere</string>
<string name="textTooShort">Il testo deve avere almeno 10 caratteri.</string> <string name="enterPhoneNumberAndText">Inserisci un numero di telefono e un testo.</string>
<string name="theFollowingPermissionsHaveBeenDenied">Sono state negate le seguenti autorizzazioni:</string> <string name="theFollowingPermissionsHaveBeenDenied">Sono state negate le seguenti autorizzazioni:</string>
<string name="theseAreThePermissionsRequired">Queste sono le autorizzazioni necessarie:</string> <string name="theseAreThePermissionsRequired">Queste sono le autorizzazioni necessarie:</string>
<string name="thursday">Giovedì</string> <string name="thursday">Giovedì</string>
@ -517,7 +517,7 @@
<string name="to">a</string> <string name="to">a</string>
<string name="toggableRules">Regole \"Reversibili\"</string> <string name="toggableRules">Regole \"Reversibili\"</string>
<string name="toggle">reversibile</string> <string name="toggle">reversibile</string>
<string name="toggleNotAllowed">La reversibilità al momento è disponibile solo per le regole che hanno come evento un tag NFC. Consulta l\'aiuto per i dettagli.</string> <string name="toggleNotAllowed">La reversibilità al momento è disponibile solo per le regole che hanno come evento una etichetta NFC. Consulta l\'aiuto per i dettagli.</string>
<string name="toggleRule">Regola Reversibile</string> <string name="toggleRule">Regola Reversibile</string>
<string name="toggling">Attivando</string> <string name="toggling">Attivando</string>
<string name="triggerCharging">Batteria sotto carica</string> <string name="triggerCharging">Batteria sotto carica</string>
@ -538,7 +538,7 @@
<string name="urlTooShort">L\'url deve avere almeno 10 caratteri.</string> <string name="urlTooShort">L\'url deve avere almeno 10 caratteri.</string>
<string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funzionerà dato che sei su una versione superiore ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola.</string> <string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funzionerà dato che sei su una versione superiore ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola.</string>
<string name="useAuthentication">Usa l\'autenticazione</string> <string name="useAuthentication">Usa l\'autenticazione</string>
<string name="useExistingTag">Utilizzo di un tag NFC esistente</string> <string name="useExistingTag">Utilizzo di una etichetta NFC esistente</string>
<string name="useTextToSpeechOnNormalSummary">Usa TextToSpeech nel modo normale</string> <string name="useTextToSpeechOnNormalSummary">Usa TextToSpeech nel modo normale</string>
<string name="useTextToSpeechOnNormalTitle">TTS in modo normale</string> <string name="useTextToSpeechOnNormalTitle">TTS in modo normale</string>
<string name="useTextToSpeechOnSilentSummary">Usa TextToSpeech nel modo silenzioso</string> <string name="useTextToSpeechOnSilentSummary">Usa TextToSpeech nel modo silenzioso</string>
@ -552,8 +552,8 @@
<string name="volumeAlarms">Allarmi sonori</string> <string name="volumeAlarms">Allarmi sonori</string>
<string name="volumeMusicVideoGameMedia">Multimedia (musica, video …)</string> <string name="volumeMusicVideoGameMedia">Multimedia (musica, video …)</string>
<string name="volumeRingtoneNotifications">Toni e notifiche</string> <string name="volumeRingtoneNotifications">Toni e notifiche</string>
<string name="volumeTest">Taratura audio</string> <string name="volumeTest">Calibratura audio</string>
<string name="volumeTesterExplanation">Per calcolare il valore del rumore di fondo in dB è necessario specificare un valore di riferimento fisico (si prega di leggere Wikipedia per ulteriori informazioni). Questo valore è probabilmente diverso per ogni telefono. Trascinare il cursore per modificare il valore di riferimento fisico definito. Più alto è il valore di riferimento e più basso sarà il valore misurato in dB. Misurazioni costanti saranno effettuate ogni %1$s secondi ed i risultati visualizzati sotto. Premere indietro quando hai trovato un valore adeguato.</string> <string name="volumeCalibrationExplanation">Per calcolare il valore del rumore di fondo in dB è necessario specificare un valore di riferimento fisico (si prega di leggere Wikipedia per ulteriori informazioni). Questo valore è probabilmente diverso per ogni telefono. Trascinare il cursore per modificare il valore di riferimento fisico definito. Più alto è il valore di riferimento e più basso sarà il valore misurato in dB. Misurazioni costanti saranno effettuate ogni %1$s secondi ed i risultati visualizzati sotto. Premere indietro quando hai trovato un valore adeguato.</string>
<string name="volumes">Volumi</string> <string name="volumes">Volumi</string>
<string name="waitBeforeNextAction">Attesa prima della azione successiva</string> <string name="waitBeforeNextAction">Attesa prima della azione successiva</string>
<string name="waitBeforeNextActionEnterValue">Inserisci il valore della pausa tra tra un\'azione e la successiva (millisecondi).</string> <string name="waitBeforeNextActionEnterValue">Inserisci il valore della pausa tra tra un\'azione e la successiva (millisecondi).</string>
@ -587,4 +587,57 @@
<string name="noLocationCouldBeFound">Nessuna posizione è stata trovata dopo un tempo di attesa di %1$s seconds.</string> <string name="noLocationCouldBeFound">Nessuna posizione è stata trovata dopo un tempo di attesa di %1$s seconds.</string>
<string name="pleaseGiveBgLocation">Nella schermata successiva vai su permessi, poi posizione. Lì seleziona \"Consenti sempre\" per permettere ad Automation di determinare la tua posizione in secondo piano.</string> <string name="pleaseGiveBgLocation">Nella schermata successiva vai su permessi, poi posizione. Lì seleziona \"Consenti sempre\" per permettere ad Automation di determinare la tua posizione in secondo piano.</string>
<string name="tones">Suonerias</string> <string name="tones">Suonerias</string>
<string name="dnd">Non disturbare</string>
<string name="deviceOrientation">Orientamento</string>
<string name="tolerance">Tolleranza</string>
<string name="orientationAzimuth">Azimut:</string>
<string name="actionSetBluetoothTethering">Bluetooth Tethering</string>
<string name="actionTurnBluetoothTetheringOn">accendere Bluetooth Tethering</string>
<string name="actionTurnBluetoothTetheringOff">spegnere Bluetooth Tethering</string>
<string name="vibrate">Vibrare</string>
<string name="test">Provare</string>
<string name="VibrateExplanation">Inserisci una durata per la vibrazione, seguita da una virgola e poi la durata di una pausa. Si possono concatenare tutte le vibrazioni che si vogliono. Per esempio, lo schema 100,500,500,1000,100 farà vibrare il dispositivo per 100ms, aspetterà 500ms, vibrerà 500ms, aspetterà 1000ms e vibrerà 100ms. Se pensi che una vibrazione non venga eseguita, prova ad aumentare la pausa precedente.</string>
<string name="pleaseEnterValidVibrationPattern">Si prega di inserire uno schema di vibrazione valido.</string>
<string name="top">Superiore</string>
<string name="bottom">Inferiore</string>
<string name="tabsPlacement">Posizione della barra delle schede</string>
<string name="tabsPlacementSummary">Scegli dove posizionare la barra delle schede.</string>
<string name="wifiApi30">Dato che Google ha rovinato un\'altra parte ancora di Android, a partire con le API 30, solo le reti wifi attualmente visibili possono essere visualizzate, non tutte quelle a cui il tuo dispositivo si è collegato.</string>
<string name="smsDialogNotice">Se non hai mai usato una azione \"invia-sms\" prima, Android potrebbe visualizzare una finestra di conferma addizionale, chiedendo di permettere l\'invio di messaggi. Dovrai mettere il segno di spunta su \"permetti sempre"\ e confermare se vuoi che questa attività funzioni in secondo piano. Si raccomanda l\'esecuzione manuale la prima volta solo per far apparire questa finestra.</string>
<string name="silentTriggersDnd">ATTENZIONE: La modalità silenziosa spesso attiva quella \"non disturbare\" sui dispositivi più nuovi. Se questo avviene sul tuo, ti raccomando di usare la modalità normale invece di abbassare tutti i volumi a zero.</string>
<string name="miscellaneous">Altro</string>
<string name="dndOff">Spegni \"Non disturbare\"</string>
<string name="dndPriority">Permetti notifiche prioritarie</string>
<string name="dndAlarms">Permetti allarmi</string>
<string name="dndNothing">Non permettere nulla</string>
<string name="dndRemarks">La configurazione dettagliata (come il permesso di fare chiamate, scegliere numeri specifici, etc.) può solo essere effettuata dalle impostazioni di sistema.</string>
<string name="permissionsRequiredNotAvailable">Le tue regole hanno bisogno di permessi che non possono essere richiesti da questa versione di Automation.</string>
<string name="automationNotificationsIgnored">Se non scegli una applicazione specifica, ma scegli \"Qualsiasi applicazione\", le notifiche provenienti da Automation saranno ignorate per evitare che vada in ripetizione.</string>
<string name="repeatEveryXseconds">Ripeti ogni x secondi</string>
<string name="repeatEveryXsecondsWithVariable">ripeti ogni %1$s secondi</string>
<string name="enterRepetitionTime">Devi inserire un valore positivo e non decimale per il tempo di ripetizione.</string>
<string name="elementSkipped">Un elemento del file di configurazione non può essere letto. Il file potrebbe essere stato create da una versione più recente del programma.</string>
<string name="donate">Donazioni</string>
<string name="btTetheringNotice">È stato confermato che questa caratteristica funziona fino ad Android 8.0. Da qualche versione superiore ha cessato di funzionare, ma dato che non ho sufficienti dispositivi fisici, non posso identificare quale sia. Su Android 11 sicuramente non funziona più. Se hai una versione intermedia, per favore fammi sapere se funziona per il tuo dispositivo, o no. </string>
<string name="notice">Avviso</string>
<string name="orientationPitch">Inclinazione:</string>
<string name="orientationRoll">Rotazione:</string>
<string name="enterValidNumbersIntoAllFields">Inserire un numero valido in tutti i campi.</string>
<string name="deviceOrientationExplanation">When you move your device the below numbers will update. What you can see there, is the current orientation of your device measured in degrees. If it is in the desired orientation, click the apply button to copy the current values to the desired fields.\nBecause reaching this exact orientation ever again is highly unlikely you must also enter a tolerance. The is amount of degrees to which the orientation can deviate in either direction. 15° will result in a total angle of 30°, 15° in every direction.\nIf you only care about one specific axis, specify a tolerance of 180° for the two other ones.</string>
<string name="wouldCurrentlyApply">Si applica attualmente?</string>
<string name="deviceIsInCertainOrientation">il dispositivo si trova in una certa orientazione</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">Una tolleranza di 180 è permessa solo per 2 campi di tolleranza, non tutti e tre. Altrimenti l\'attività si applicherebbe SEMPRE.</string>
<string name="unknown">sconosciuto</string>
<string name="orientation">Orientazione</string>
<string name="triggerWrong">C\'è qualcosa di errato con questo evento. Non può essere caricato correttamente.</string>
<string name="turnScreenOnOrOff">Accendi/Spegni lo schermo</string>
<string name="turnScreenOn">accendi lo schermo</string>
<string name="turnScreenOff">spegni lo schermo</string>
<string name="mustApply">Si deve applicare</string>
<string name="explanationDeviceOrientationDirection">Se la casella di controllo è spuntata, significa che il dispositivo deve essere nell\'orientamento specificato. Se non è spuntata, qualsiasi orientamento che NON corrisponde ai tuoi criteri andrà bene. </string>
<string name="deviceOrientationTimeAcceptIntervalTitle">Frequenza del segnale</string>
<string name="deviceOrientationTimeAcceptIntervalSummary">Accetta nuovi segnali di movimento ogni x millisecondi </string>
<string name="deviceOrientationSettings">Impostazioni di orientamento del dispositivo</string>
<string name="android.permission.BIND_DEVICE_ADMIN">Amministrazione dispositivo</string>
<string name="deviceAdminNote">I permessi di amministratore del dispositivo sono necessari per almeno 1 delle regole che hai creato.</string>
</resources> </resources>

View File

@ -0,0 +1,641 @@
<resources>
<string name="ruleActivate">Activering regel %1$s</string>
<string name="profileActivate">Activeren profiel %1$s</string>
<string name="ruleActivateToggle">Activeren regel %1$s in Togglemode</string>
<string name="addPoi">Locatie toevoegen</string>
<string name="addRule">Regel toevoegen</string>
<string name="poiList">Lijst locaties:</string>
<string name="ruleList">Lijst Regels:</string>
<string name="pleaseEnterValidName">Voer a.u.b. een geldige naam in.</string>
<string name="pleaseSpecifiyTrigger">Gelieve minstens één trigger op te geven.</string>
<string name="pleaseSpecifiyAction">Gelieve minstens één actie te specificeren</string>
<string name="serviceWontStart">Geen regels gedefinieerd. Dienst start niet.</string>
<string name="serviceStarted">Automations Service gestart.</string>
<string name="version">Versie %1$s.</string>
<string name="distanceBetween">Afstand tussen GPS locatie en netwerklocatie is %1$d meter. Deze +1m moet de absolute minimum radius zijn.</string>
<string name="positioningWindowNotice">Als u zich in een gebouw bevindt, wordt u sterk aangeraden om uw apparaat naast een raam te plaatsen totdat een positie is gevonden. Anders kan het erg lang duren als het al in staat is om er een te vinden.</string>
<string name="gettingPosition">Positie aan het zoeken. Even geduld aub...</string>
<string name="yes">Ja</string>
<string name="no">Nee</string>
<string name="pleaseEnterValidLatitude">Voer a.u.b. een geldige breedtegraad in.</string>
<string name="pleaseEnterValidLongitude">Voer a.u.b. een geldige lengtegraad in.</string>
<string name="pleaseEnterValidRadius">Voer a.u.b. een geldige positieve radius in.</string>
<string name="selectOneDay">Selecteer ten minste één dag.</string>
<string name="whatToDoWithRule">Wat wil je met de regel doen?</string>
<string name="whatToDoWithPoi">Wat wil je met de locatie doen?</string>
<string name="whatToDoWithProfile">Wat wil je met profiel doen?</string>
<string name="delete">Verwijderen</string>
<string name="deleteCapital">Verwijderen</string>
<string name="serviceStopped">Automation: dienst gestopt.</string>
<string name="logServiceStopping">Service stoppen.</string>
<string name="stillGettingPosition">Nog steeds positie aan het verkrijgen.</string>
<string name="lastRule">Laatste regel:</string>
<string name="at">Bij</string>
<string name="service">Service:</string>
<string name="getCurrentPosition">Huidige locatie ophalen</string>
<string name="savePoi">Sla locatie op</string>
<string name="deletePoi">Locatie verwijderen</string>
<string name="latitude">Latitude</string>
<string name="longitude">Longitude</string>
<string name="ruleName">Naam regel</string>
<string name="triggers">Trigger(s)</string>
<string name="triggersComment">EN-verbonden (alle triggers moeten tegelijk van toepassing zijn)</string>
<string name="addTrigger">Trigger toevoegen</string>
<string name="actions">Action(s)</string>
<string name="actionsComment">(worden in die volgorde uitgevoerd)</string>
<string name="addAction">Actie toevoegen</string>
<string name="saveRule">Regel opslaan</string>
<string name="monday">Maandag</string>
<string name="tuesday">Dinsdag</string>
<string name="wednesday">Woensdag</string>
<string name="thursday">Donderdag</string>
<string name="friday">Vrijdag</string>
<string name="saturday">Saturday</string>
<string name="sunday">Zondag</string>
<string name="start">Start</string>
<string name="end">Einde</string>
<string name="save">Opslaan</string>
<string name="urlToTrigger">URL om te activeren:</string>
<string name="urlLegend">Variabelen:U kunt de volgende variabelen gebruiken. Bij het triggeren zullen ze worden vervangen door de corresponderende waarde op je apparaat. Zet de haakjes in uw tekst. \n[uniqueid] - Het unieke id van uw apparaat[serienummer] - Het serienummer van uw apparaat[latitude] - De breedtegraad van uw apparaat[longitude] - De lengtegraad van uw apparaat[phonenr] - Nummer van het laatste inkomende of uitgaande gesprek[d] - Dag van de maand, 2 cijfers met voorloopnullen[m] - Numerieke weergave van een maand, met voorloopnullen[Y] - een volledige numerieke weergave van een jaar, 4 cijfers[h] - 12-uurs indeling van een uur, met voorloopnullen[H] - 24-uurs indeling van een uur, met voorloopnullen[i] - minuten, met voorloopnullen[s] - seconden, met voorloopnullen[ms] - milliseconden[notificationTitle] - titel van de laatste melding[notificationText] - tekst van de laatste melding</string>
<string name="wifi">wifi</string>
<string name="activating">Activeren</string>
<string name="deactivating">Deactiveren</string>
<string name="bluetoothFailed">Niet gelukt om Bluetooth te activeren. Heeft dit apparaat Bluetooth?</string>
<string name="urlTooShort">De url moet uit minstens 10 tekens bestaan.</string>
<string name="selectTypeOfTrigger">Selecteer type trigger</string>
<string name="entering">inkomend</string>
<string name="leaving">uitgaand</string>
<string name="noPoisSpecified">Je hebt nog geen locaties opgegeven. Doe dat eerst.</string>
<string name="started">gestart</string>
<string name="stopped">gestopt</string>
<string name="connected">verbonden</string>
<string name="disconnected">verbinding verbroken</string>
<string name="selectPoi">Selecteer locatie</string>
<string name="selectTypeOfAction">Selecteer type actie</string>
<string name="selectSoundProfile">Selecteer geluidsprofiel</string>
<string name="whatToDoWithTrigger">Wat te doen met trigger?</string>
<string name="whatToDoWithAction">Wat te doen met actie?</string>
<string name="radiusHasToBePositive">Straal moet een positief getal zijn.</string>
<string name="poiStillReferenced">Er zijn nog steeds regels die verwijzen naar deze locatie (%1$s). Ik kan het nog niet verwijderen.</string>
<string name="generalSettings">Algemene instellingen</string>
<string name="startAtSystemBoot">Start bij opstarten systeem</string>
<string name="onOff">Aan/Uit</string>
<string name="writeLogFile">Logbestand schrijven</string>
<string name="useTextToSpeechOnNormalSummary">Gebruik TextToSpeech op normaal</string>
<string name="useTextToSpeechOnVibrateSummary">Gebruik TextToSpeech op trillen</string>
<string name="useTextToSpeechOnSilentSummary">Gebruik TextToSpeech op stil</string>
<string name="useTextToSpeechOnNormalTitle">TTS op normaal gebruiken</string>
<string name="useTextToSpeechOnVibrateTitle">TTS op trillen</string>
<string name="useTextToSpeechOnSilentTitle">TTS op stil</string>
<string name="positioningSettings">Positie instellingen</string>
<string name="listenToWifiState">Luisteren naar wifi-statuswijzigingen waar mogelijk</string>
<string name="wifiState">Wifi-toestand</string>
<string name="listenToAccelerometerState">Observeer bewegingssensor waar wifi niet beschikbaar is</string>
<string name="accelerometer">Accelerometer</string>
<string name="accelerometerTimer">Accelerometer gebruiken na x minuten zonder verandering van torenmast</string>
<string name="cellMastIdleTime">Inactieve tijd zendmast</string>
<string name="accelerometerThresholdDescription">Drempel voor accelerometerbewegingen</string>
<string name="accelerometerThreshold">Accelerometerdrempel</string>
<string name="positioningThresholds">Drempels voor positionering</string>
<string name="minimumDistanceChangeForGpsLocationUpdates">Minimale afstandsverandering voor gps locatie-updates</string>
<string name="distanceForGpsUpdate">Afstand voor gps update [m]</string>
<string name="minimumDistanceChangeForNetworkLocationUpdates">Minimale afstandswijziging voor netwerklocatie-updates</string>
<string name="distanceForNetworkUpdate">Afstand voor netwerkupdate [m]</string>
<string name="satisfactoryAccuracyGps">Bevredigende nauwkeurigheid bij het verkrijgen van locatie via gps in meters</string>
<string name="gpsAccuracy">GPS nauwkeurigheid [m]</string>
<string name="satisfactoryAccuracyNetwork">Bevredigende nauwkeurigheid bij het verkrijgen van locatie via celtorens in meters</string>
<string name="networkAccuracy">Netwerk nauwkeurigheid [m]</string>
<string name="minimumTimeForLocationUpdates">Minimale tijdsverandering in milliseconden voor locatie-updates</string>
<string name="timeForUpdate">Tijd voor update [milliseconden]</string>
<string name="soundSettings">Geluidsinstellingen</string>
<string name="showHelp">Toon help</string>
<string name="rules">Regels</string>
<string name="helpTextRules">Alle triggers in een regel zijn EN-verbonden (AND). De regel zal alleen worden toegepast als aan alle triggers is voldaan. Als je OR wilt, maak dan een andere regel.</string>
<string name="timeframes">Tijdsbestek</string>
<string name="helpTextTimeFrame">Als je een regel opgeeft met een tijdsbestek heb je twee keuzes. Je kunt kiezen tussen het binnengaan OF het verlaten van een tijdframe. In beide gevallen wordt een regel slechts eenmaal getriggerd. Dus als je een regel maakt met als trigger "ingaan tijdvak xyz" en je laat je geluidsprofiel veranderen in trillen dan betekent dat niet dat de telefoon automatisch gaat rinkelen als het tijdvak voorbij is. Als je dat wilt moet je een andere regel specificeren met een ander tijdsbestek.</string>
<string name="helpTextSound">Op het hoofdscherm kunt u vergrendelingsgeluiden gebruiken om op regels gebaseerde geluidsveranderingen tijdelijk te vermijden. U kunt bijvoorbeeld in een situatie of plaats zijn waar ringtones normaal gesproken ok zijn, maar deze ene keer zou het storend zijn. De functie zal automatisch worden uitgeschakeld zodra de ingestelde tijd is verstreken. Klik op de + knop om de ingestelde tijd toe te voegen. Zodra het actief is kunt u het weer deactiveren met de toggle knop (en op die manier op regels gebaseerde geluidsveranderingen weer inschakelen).</string>
<string name="toggableRules">Schakelbare regels</string>
<string name="helpTextToggable">Regels hebben een vlag genaamd "Toggable". Dit betekent dat als een regel wordt uitgevoerd en daarna dezelfde triggers opnieuw van toepassing zijn, de regel zal worden uitgevoerd in een tegenovergestelde modus indien van toepassing. Momenteel gebeurt dit alleen in combinatie met NFC tags. Als je er twee keer op tikt en er is een toggable regel aan verbonden, zal het het tegenovergestelde doen van de huidige situatie, bv. wifi uitschakelen als het momenteel geactiveerd is.</string>
<string name="helpTextProcessMonitoring">Als je een regel opgeeft met een procesmonitor, zal de applicatie elke x seconden controleren of er een proces is (je kunt dat in de instellingen wijzigen). Ik weet dat dit traag kan zijn, maar continu monitoren zou de batterij te snel leegmaken. En er is geen uitzending van het OS voor die gebeurtenis.</string>
<string name="helpTitleEnergySaving">Energiebesparing</string>
<string name="helpTextEnergySaving">Veel fabrikanten van Android-toestellen proberen energie te besparen door de achtergrondactiviteit van draaiende apps te beperken. Helaas leidt dat er vaak toe dat die apps niet goed werken, Automation is daar één van. Zie dit om uit te vinden hoe je Automation kunt uitsluiten van deze maatregelen.</string>
<string name="speedMaximumTimeBetweenLocations">Maximale tijd tussen 2 locaties voor snelheidsbepaling.</string>
<string name="speedMaximumTime">Tijd in minuten</string>
<string name="exceeds">overschrijdt</string>
<string name="dropsBelow">daalt onder</string>
<string name="settingsCategoryNoiseLevelMeasurements">Geluidsniveau meting</string>
<string name="timeBetweenNoiseLevelMeasurementsSummary">Seconden tussen metingen geluidsniveau</string>
<string name="timeBetweenNoiseLevelMeasurementsTitle">Seconden tussen metingen geluidsniveau</string>
<string name="lengthOfNoiseLevelMeasurementsSummary">Lengte in seconden voor elke meting van het geluidsniveau</string>
<string name="lengthOfNoiseLevelMeasurementsTitle">Lengte van elke meting van het geluidsniveau</string>
<string name="referenceValueForNoiseLevelMeasurementsSummary">Fysieke referentiewaarde voor geluidsniveaumeting</string>
<string name="referenceValueForNoiseLevelMeasurementsTitle">Referentie voor geluidsmeting</string>
<string name="logLevelSummary">Logboek niveau (1=minimum, 5=maximum)</string>
<string name="logLevelTitle">Logboek niveau</string>
<string name="ruleActive">Regel actief</string>
<string name="triggerPointOfInterest">Locatie</string>
<string name="triggerTimeFrame">Timeframe</string>
<string name="triggerCharging">Batterij wordt opgeladen</string>
<string name="triggerUsb_host_connection">USB-verbinding met een computer</string>
<string name="triggerSpeed">Snelheid</string>
<string name="triggerNoiseLevel">Achtergrond geluidsniveau</string>
<string name="actionSetWifi">Wifi</string>
<string name="actionSetBluetooth">Bluetooth</string>
<string name="actionSetUsbTethering">USB Tethering</string>
<string name="actionSetWifiTethering">Wifi Tethering</string>
<string name="actionSetDisplayRotation">Beeldschermrotatie</string>
<string name="actionTurnWifiOn">Wifi inschakelen</string>
<string name="actionTurnWifiOff">Wifi uitzetten</string>
<string name="actionTurnBluetoothOn">zet Bluetooth aan</string>
<string name="actionTurnBluetoothOff">zet Bluetooth uit</string>
<string name="actionTriggerUrl">Trigger een URL</string>
<string name="actionChangeSoundProfile">Wijzig geluidsprofiel</string>
<string name="actionTurnUsbTetheringOn">Schakel USB-tethering in</string>
<string name="actionTurnUsbTetheringOff">USB-tethering uitschakelen</string>
<string name="actionTurnWifiTetheringOn">zet Wifi Tethering aan</string>
<string name="actionTurnWifiTetheringOff">zet Wifi Tethering uit</string>
<string name="actionTurnAirplaneModeOn">zet vliegtuigmodus aan</string>
<string name="actionTurnAirplaneModeOff">zet vliegtuigmodus uit</string>
<string name="actionEnableScreenRotation">schermrotatie inschakelen</string>
<string name="actionDisableScreenRotation">schermrotatie uitschakelen</string>
<string name="screenRotationEnabled">Schermrotatie ingeschakeld</string>
<string name="screenRotationDisabled">Schermrotatie uitgeschakeld.</string>
<string name="screenRotationAlreadyEnabled">Schermrotatie was al ingeschakeld.</string>
<string name="screenRotationAlreadyDisabled">Schermrotatie was al uitgeschakeld.</string>
<string name="noPoisDefinedShort">Geen locaties gedefinieerd.</string>
<string name="activePoi">Actieve locatie:</string>
<string name="closestPoi">Dichtstbijzijnde locatie:</string>
<string name="overview">Overzicht</string>
<string name="poi">Locatie</string>
<string name="pois">Locaties</string>
<string name="helpTextPoi">Een locatie is opgebouwd uit GPS-coördinaten en een radius. Aangezien plaatsbepaling via zendmasten nogal onnauwkeurig is (maar snel en goedkoop) moet je de straal niet te klein opgeven. De applicatie zal u een minimale straal voorstellen wanneer u een nieuwe locatie aanmaakt.</string>
<string name="serviceNotRunning">Service is niet actief.</string>
<string name="general">General</string>
<string name="generalText">Om dit programma te gebruiken moet je regels instellen. Die bevatten triggers, bijvoorbeeld als je een bepaald gebied bereikt of als je een bepaalde tijd binnengaat. Als dat gedaan is klik je op de aan/uit knop op het hoofdscherm.</string>
<string name="failedToTriggerBluetooth">Mislukt om Bluetooth te activeren. Heeft dit apparaat Bluetooth?</string>
<string name="startServiceAfterAppUpdate">Start service automatisch na app update als deze al eerder heeft gedraaid.</string>
<string name="startServiceAfterAppUpdateShort">Start service na update</string>
<string name="wifiConnection">Wifi-verbinding</string>
<string name="wifiName">Wifi-naam</string>
<string name="enterWifiName">Voer een wifi-naam in. Laat leeg voor elke wifi.</string>
<string name="cancel">Annuleren</string>
<string name="starting">bezig met starten</string>
<string name="stopping">bezig met stoppen</string>
<string name="connecting">aan het verbinden</string>
<string name="disconnecting">verbinding aan het verbreken</string>
<string name="exceeding">te hoog</string>
<string name="droppingBelow">lager dan</string>
<string name="connectedToWifi">verbonden met wifi %1$s</string>
<string name="disconnectedFromWifi">losgekoppeld van wifi "%1$s"</string>
<string name="anyWifi">enige wifi</string>
<string name="cantStopIt">Kan het niet stoppen.</string>
<string name="settingsCategoryHttp">HTTP(s) Verzoeken</string>
<string name="httpAcceptAllCertificatesTitle">Accepteer alle certificaten</string>
<string name="httpAcceptAllCertificatesSummary">Geldigheidscontrole van SSL certificaten overslaan (aanbevolen om dit niet te activeren)</string>
<string name="httpAttemptsSummary">Aantal pogingen indien HTTP-verzoeken om connectiviteitsredenen mislukken</string>
<string name="httpAttemptsTitle">Aantal HTTP-pogingen</string>
<string name="httpAttemptsTimeoutSummary">Time-out voor HTTP-verzoeken [seconden]</string>
<string name="httpAttemptsTimeoutTitle">Timeout [sec]</string>
<string name="httpAttemptGapSummary">Pauze voor een volgende poging [seconden]</string>
<string name="httpAttemptGapTitle">Pauze [sec]</string>
<string name="runManually">Handmatig uitvoeren</string>
<string name="serviceHasToRunForThat">De service moet daarvoor actief zijn.</string>
<string name="gpsComparison">GPS-vergelijking</string>
<string name="timeoutForGpsComparisonsTitle">GPS timeout [sec]</string>
<string name="timeoutForGpsComparisonsSummary">Maximale tijd in seconden om te proberen een GPS-locatie te krijgen voor vergelijking. Indien meer dan laatst bekende locatie zal worden toegepast.</string>
<string name="rememberLastActivePoiSummary">Als u op een locatie bent, uw apparaat of de applicatie opnieuw opstart en de locatie verlaat, zal de applicatie bij de volgende start regels uitvoeren die zijn gekoppeld aan het verlaten van de locatie.</string>
<string name="rememberLastActivePoiTitle">Onthoud laatste actieve locatie</string>
<string name="muteTextToSpeechDuringCallsTitle">Dempen tijdens oproepen</string>
<string name="muteTextToSpeechDuringCallsSummary">Mute TextToSpeech tijdens gesprekken</string>
<string name="anotherPoiByThatName">Er is al een andere locatie met die naam.</string>
<string name="anotherRuleByThatName">Er is al een andere regel met die naam.</string>
<string name="startOtherActivity">Start een ander programma</string>
<string name="selectApplication">Selecteer app</string>
<string name="selectPackageOfApplication">Selecteer pakket van toepassing</string>
<string name="selectActivityToBeStarted">Selecteer activiteit van gekozen pakket</string>
<string name="errorStartingOtherActivity">Fout bij starten andere activiteit</string>
<string name="anotherAppIsRunning">Een andere app is gestart/gestopt</string>
<string name="settingsCategoryProcessMonitoring">Process monitoring</string>
<string name="timeBetweenProcessMonitoringsTitle">Seconden tussen procesbewakingen</string>
<string name="timeBetweenProcessMonitoringsSummary">Hoe lager, hoe hoger het batterijverbruik</string>
<string name="processes">Processes</string>
<string name="processMonitoring">Process monitoring</string>
<string name="settings">Settings</string>
<string name="settingsErased">Instellingen gewist.</string>
<string name="settingsSetToDefault">Instellingen op standaard gezet.</string>
<string name="batteryLevel">Batterijniveau</string>
<string name="selectSpeed">Selecteer snelheid</string>
<string name="selectBattery">Selecteer batterijniveau</string>
<string name="privacy">Privacybeleid</string>
<string name="privacyConfirmationText">Een browser wordt nu geopend op uw apparaat en laadt het privacybeleid van de website van de ontwikkelaar.</string>
<string name="waitBeforeNextAction">Wachten voor volgende actie</string>
<string name="wakeupDevice">Apparaat wekken</string>
<string name="waitBeforeNextActionEnterValue">Voer een waarde in milliseconden in hoe lang er gewacht moet worden voor de volgende actie.</string>
<string name="wakeupDeviceValue">Voer een waarde in milliseconden in hoe lang het apparaat tenminste wakker moet blijven. 0 voor standaardwaarden.</string>
<string name="enterAPositiveValidNonDecimalNumber">Voer een positief geldig niet-decimaal getal in.</string>
<string name="moveUp">Ga omhoog</string>
<string name="moveDown">Ga naar beneden</string>
<string name="cantMoveUp">Kan item niet naar boven verplaatsen. Het staat al bovenaan.</string>
<string name="cantMoveDown">Kan item niet naar beneden verplaatsen. Het staat al onderaan.</string>
<string name="airplaneMode">Vliegtuigmodus</string>
<string name="activate">Activate</string>
<string name="deactivate">Deactivate</string>
<string name="airplaneModeSdk17Warning">Beginnend vanaf Android versie 4.2 werkt deze functie alleen als uw toestel is geroot.</string>
<string name="addIntentValue">Intentiepaar toevoegen</string>
<string name="parameterName">Parameter naam</string>
<string name="parameterValue">Parameter waarde</string>
<string name="parameterType">Parameter type</string>
<string name="selectTypeOfIntentPair">Selecteer een type voor het intentiepaar.</string>
<string name="enterNameForIntentPair">Voer een naam in voor het intentiepaar.</string>
<string name="enterValueForIntentPair">Voer een waarde in voor het intentiepaar.</string>
<string name="whatToDoWithIntentPair">Wat te doen met paar?</string>
<string name="gettingListOfInstalledApplications">Lijst van geïnstalleerde applicaties ophalen...</string>
<string name="timeFrameWhichDays">Op welke dagen?</string>
<string name="insideOrOutsideTimeFrames">Binnen of buiten die tijdsbestekken?</string>
<string name="selectToggleDirection">Aan- of uitzetten?</string>
<string name="name">Naam</string>
<string name="radiusWithUnit">Straal [m]</string>
<string name="status">Status</string>
<string name="actionDataConnection">Gegevensverbinding</string>
<string name="actionSetDataConnectionOn">Mobiele data aanzetten</string>
<string name="actionSetDataConnectionOff">mobiele data uitzetten</string>
<string name="roaming">Roaming</string>
<string name="activated">ingeschakeld</string>
<string name="deactivated">uitgeschakeld</string>
<string name="until">tot</string>
<string name="application">Application</string>
<string name="is">is</string>
<string name="phoneCall">Telefoongesprek</string>
<string name="with">met</string>
<string name="phoneNumber">Telefoonnummer</string>
<string name="enterPhoneNumber">Voer telefoonnummer in. Laat leeg voor een willekeurig nummer.</string>
<string name="phoneDirection">Selecteer gespreksrichting</string>
<string name="any">een willekeurig</string>
<string name="incoming">binnenkomend</string>
<string name="outgoing">uitgaand</string>
<string name="incomingAdjective">binnenkomend</string>
<string name="outgoingAdjective">uitgaand</string>
<string name="anyNumber">elk nummer</string>
<string name="number">nummer</string>
<string name="nfcTag">NFC tag</string>
<string name="closeTo">dicht bij</string>
<string name="withLabel">met label</string>
<string name="deviceDoesNotHaveNfc">Het lijkt erop dat dit apparaat geen NFC heeft.</string>
<string name="nfcReadTag">Lees ID van tag</string>
<string name="nfcWriteTag">Tag schrijven</string>
<string name="nfcEnterValidIdentifier">Voer een geldige identificatiecode in voor de tag (zoals "Huisdeur").</string>
<string name="nfcTagWrittenSuccessfully">Tag succesvol geschreven.</string>
<string name="nfcTagWriteError">Fout bij schrijven tag. Is het binnen bereik?</string>
<string name="nfcTagDiscovered">Tag ontdekt.</string>
<string name="nfcBringTagIntoRange">Breng een NFC tag binnen bereik.</string>
<string name="nfcTagFoundWithText">Tag gevonden met tekst:</string>
<string name="nfcUnsupportedEncoding">Niet ondersteunde codering:</string>
<string name="nfcNoNdefIntentBut">Geen NFC NDEF bedoeling, maar</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC nog niet ondersteund in deze Android versie.</string>
<string name="cantRunRule">Kan regels niet uitvoeren.</string>
<string name="nfcApplyTagToRule">Pas Tag toe op regel</string>
<string name="nfcTagReadSuccessfully">Tag succesvol gelezen.</string>
<string name="nfcValueNotSuitable">Opgeslagen waarde niet geschikt.</string>
<string name="nfcNoTag">Geen tag aanwezig.</string>
<string name="newNfcId">Schrijf nieuwe NFC ID</string>
<string name="useExistingTag">Gebruik bestaande NFC-tag</string>
<string name="newId">Nieuwe ID:</string>
<string name="currentId">Huidige ID:</string>
<string name="nfcTagDataNotUsable">Tag gegevens niet bruikbaar, opnieuw schrijven.</string>
<string name="nfcBringTagIntoRangeToRead">Breng een tag binnen bereik om te lezen.</string>
<string name="toggleRule">Verwissel regel</string>
<string name="toggling">Toggling</string>
<string name="toggle">Toggle</string>
<string name="overlapBetweenPois">Overlap gedetecteerd tot locatie %1$s van %2$s meter. Verminder de straal met ten minste dat.</string>
<string name="none">geen</string>
<string name="anyLocation">elke locatie</string>
<string name="invalidPoiName">Ongeldige naam voor locatie.</string>
<string name="eraseSettings">Instellingen wissen</string>
<string name="defaultSettings">Standaardinstellingen</string>
<string name="areYouSure">Weet je het zeker?</string>
<string name="activityDetection">Activity detection</string>
<string name="android.permission.ACTIVITY_RECOGNITION">Activity detection</string>
<string name="detectedActivity">Detected activity:</string>
<string name="detectedActivityInVehicle">In voertuig (auto/bus)</string>
<string name="detectedActivityOnBicycle">Op fiets</string>
<string name="detectedActivityOnFoot">Te voet</string>
<string name="detectedActivityStill">Nog steeds</string>
<string name="detectedActivityUnknown">Onbekend</string>
<string name="detectedActivityTilting">Kantelend</string>
<string name="detectedActivityWalking">Lopend</string>
<string name="detectedActivityRunning">Rennend</string>
<string name="detectedActivityInvalidStatus">Ongeldige activiteit</string>
<string name="selectTypeOfActivity">Selecteer type activiteit</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Deze trigger is alleen beschikbaar als Google Play Services is geïnstalleerd.</string>
<string name="activityDetectionFrequencyTitle">Activiteitsdetectiefrequentie [sec]</string>
<string name="activityDetectionFrequencySummary">Seconden tussen pogingen om activiteit te detecteren.</string>
<string name="activityDetectionRequiredProbabilityTitle">Waarschijnlijkheid activiteitdetectie.</string>
<string name="activityDetectionRequiredProbabilitySummary">Zekerheid vanaf wanneer activiteiten als feit worden geaccepteerd.</string>
<string name="incomingCallFrom">Inkomend telefoongesprek van %1$s.</string>
<string name="outgoingCallTo">Uitgaand telefoongesprek naar %1$s.</string>
<string name="actionSpeakText">Spreek tekst in</string>
<string name="textToSpeak">Tekst uitspreken</string>
<string name="toggleNotAllowed">Schakelen is momenteel alleen toegestaan voor regels die NFC-tags als trigger hebben. Zie help voor meer informatie.</string>
<string name="errorReadingPoisAndRulesFromFile">Fout bij het lezen van locaties en regels uit bestand.</string>
<string name="noDataChangedReadingAnyway">Het lijkt erop dat er geen gegevenswijziging is opgeslagen. Er kunnen echter wijzigingen in het geheugen zijn geweest die moeten worden teruggedraaid. Herlezen van bestand.</string>
<string name="bluetoothConnection">Bluetooth connection</string>
<string name="bluetoothConnectionTo">Bluetooth-verbinding met %1$s</string>
<string name="bluetoothDisconnectFrom">Bluetooth-verbinding met %1$s verbroken</string>
<string name="bluetoothDeviceInRange">Bluetooth-apparaat %1$s binnen bereik.</string>
<string name="bluetoothDeviceOutOfRange">Bluetooth-apparaat %1$s buiten bereik.</string>
<string name="anyDevice">elk apparaat</string>
<string name="noDevice">geen apparaat</string>
<string name="selectDeviceFromList">één uit lijst</string>
<string name="connectionToDevice">verbinding met apparaat</string>
<string name="disconnectionFromDevice">verbinding met apparaat verbroken</string>
<string name="deviceInRange">apparaat in bereik</string>
<string name="deviceOutOfRange">apparaat buiten bereik</string>
<string name="selectDeviceOption">Selecteer een apparaatoptie.</string>
<string name="selectConnectionOption">Selecteer een verbindingsoptie.</string>
<string name="triggerHeadsetPlugged">Headset connection</string>
<string name="actionPlayMusic">Muziekspeler openen</string>
<string name="headsetConnected">Headset (type: %1$s) aangesloten</string>
<string name="headsetDisconnected">Headset (type: %1$s) ontkoppeld</string>
<string name="headphoneSimple">Headphone</string>
<string name="headphoneMicrophone">Microphone</string>
<string name="headphoneAny">willekeurige</string>
<string name="headphoneSelectType">Selecteer type hoofdtelefoon</string>
<string name="whatsThis">Wat is dit?</string>
<string name="privacyLocationingTitle">Alleen privé lokalisatie</string>
<string name="privacyLocationingSummary">Vermijd locatiemethoden die uw locatie naar een provider kunnen sturen, bijv. Google. Dit zal alleen GPS gebruiken en kan daarom traag zijn of niet betrouwbaar werken.</string>
<string name="noiseDetectionHint">Als u denkt dat de ruisdetectie niet goed werkt (afhankelijk van de waarde die u opgeeft), houd er dan rekening mee dat elke telefoon anders is. U kunt daarom "Referentie voor ruismeting" in de instellingen wijzigen. Zie http://en.wikipedia.org/wiki/Decibel voor meer informatie. U kunt de volumetester in het hoofdscherm gebruiken om uw toestel te kalibreren.</string>
<string name="hint">Hint</string>
<string name="selectNoiseLevel">Selecteer geluidsniveau</string>
<string name="showOnMap">Toon op kaart</string>
<string name="noMapsApplicationFound">Geen kaarttoepassing gevonden op uw apparaat.</string>
<string name="locationEngineNotActive">Locatiemotor niet actief.</string>
<string name="addProfile">Profiel toevoegen</string>
<string name="profile">Profile</string>
<string name="soundMode">Geluidsmodus</string>
<string name="volumes">Volumes</string>
<string name="incomingCallsRingtone">Toon voor inkomende gesprekken</string>
<string name="notificationRingtone">Toon voor meldingen</string>
<string name="hapticFeedback">Haptische feedback (trillen bij aanraken scherm)</string>
<string name="volumeMusicVideoGameMedia">Muziek, video, spel en andere media</string>
<string name="volumeRingtoneNotifications">Ringtone en meldingen</string>
<string name="volumeAlarms">Alarmen</string>
<string name="change">Wijzigen</string>
<string name="audibleSelection">Hoorbare selectie (geluid bij schermselectie)</string>
<string name="screenLockUnlockSound">Geluid bij schermvergrendeling/ontgrendeling</string>
<string name="vibrateWhenRinging">Trillen bij overgaan</string>
<string name="profiles">Profiles</string>
<string name="soundModeNormal">Normaal</string>
<string name="soundModeVibrate">Trillen</string>
<string name="soundModeSilent">Stil</string>
<string name="enterAname">Voer een naam in.</string>
<string name="noChangeSelectedProfileDoesntMakeSense">Geen wijziging geselecteerd. Profiel heeft geen zin.</string>
<string name="noProfilesCreateOneFirst">Er zijn geen profielen in uw configuratie. Maak er eerst een aan.</string>
<string name="errorActivatingProfile">Fout bij activeren profiel:</string>
<string name="anotherProfileByThatName">Er is al een ander profiel met die naam.</string>
<string name="invalidProfileName">Ongeldige naam voor profiel.</string>
<string name="errorWritingFile">Fout bij schrijven instellingenbestand.</string>
<string name="unknownError">Onbekende fout.</string>
<string name="noWritableFolderFound">Geen beschrijfbare map gevonden om configuratiebestand op te slaan.</string>
<string name="usbTetheringFailForAboveGingerbread">Dit zal waarschijnlijk niet werken omdat je boven Android 2.3 zit. Je zou in plaats daarvan wifi tethering kunnen gebruiken.</string>
<string name="usingNewThreadForRuleExecution">Nieuw process gebruiken voor activatie regel.</string>
<string name="startNewThreadForRuleExecution">Start nieuw process voor activatie regel.</string>
<string name="newThreadRules">Nieuw process</string>
<string name="showIcon">Pictogram tonen</string>
<string name="showIconWhenServiceIsRunning">Pictogram tonen als de service draait (verbergen werkt alleen onder Android 7)</string>
<string name="ruleHistory">Regelgeschiedenis (meest recente eerst):</string>
<string name="someOptionsNotAvailableYet">Sommige opties zijn uitgeschakeld omdat ze nog niet gebruikt kunnen worden. Ze zullen in een latere programmaversie worden geïntroduceerd.</string>
<string name="lockSoundChanges">Geluidswijzigingen vergrendelen</string>
<string name="noProfileChangeSoundLocked">Profiel zal niet worden geactiveerd. Laatst geactiveerde profiel is vergrendeld.</string>
<string name="currentVolume">Huidig volume</string>
<string name="enterValidReferenceValue">Voer een geldige referentiewaarde in.</string>
<string name="volumeTest">Volume test</string>
<string name="volumeCalibrationExplanation">Om een dB-waarde voor geluidsbewaking te berekenen, moet je een zogenaamde fysische referentiewaarde opgeven. Lees Wikipedia voor meer informatie. Deze waarde is waarschijnlijk voor elke telefoon anders. Sleep de zoekbalk om de gedefinieerde fysieke referentiewaarde te wijzigen. Hoe hoger de referentiewaarde, hoe lager de dB-waarde zal zijn. Constante metingen zullen worden uitgevoerd om de %1$s seconden en de resultaten zullen hieronder worden weergegeven. Druk op terug wanneer u een geschikte waarde hebt gevonden.</string>
<string name="settingsWillTakeTime">Sommige instellingen zullen niet worden toegepast voordat bepaalde omgevingsinstellingen worden gewijzigd of de service opnieuw wordt opgestart.</string>
<string name="rootExplanation">U moet uw telefoon rooten om deze functie te laten werken. Daarna moet je de regel handmatig uitvoeren om de superuser-toestemmingsvraag te laten verschijnen. Als de superuser popup verschijnt moet je de applicatie altijd toestemming geven om dat te doen. Anders kan de regel niet werken als de telefoon onbeheerd is.</string>
<string name="errorWritingConfig">Fout bij het schrijven van de config. Heeft u een beschrijfbaar geheugen?</string>
<string name="phoneNrReplacementError">Ik kon het laatste telefoonnummer niet in de variabele plaatsen. Ik heb het niet.</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="useAuthentication">Gebruik authenticatie</string>
<string name="permissionsTitle">Vereiste permissies</string>
<string name="permissionsExplanation">Verklaring van vereiste permissies</string>
<string name="ok">Ok</string>
<string name="disabledFeatures">Uitgeschakelde functies</string>
<string name="theFollowingPermissionsHaveBeenDenied">De volgende permissies zijn geweigerd:</string>
<string name="permissionsExplanationGeneric">De app draait momenteel in beperkte modus en heeft sommige functies gedeactiveerd. Om volledig te functioneren heeft het rechten nodig. Als je alle functionaliteit wilt gebruiken moet je de permissies toekennen in de volgende rechten dialogen. Als je dat niet doet, kunnen bepaalde regels niet worden uitgevoerd. In het volgende venster krijgt u uitleg over de gevraagde rechten. Klik op "doorgaan", als u klaar bent om verder te gaan.</string>
<string name="permissionsExplanationSmall">Om de functie die u zojuist probeerde te gebruiken in te schakelen, zijn meer machtigingen nodig. Klik op doorgaan om ze aan te vragen.</string>
<string name="continueText">continue</string>
<string name="rule">Regel</string>
<string name="storeSettings">Instellingen lezen en opslaan</string>
<string name="featuresDisabled">WAARSCHUWING: Functies zijn uitgeschakeld, Automation draait in beperkte modus. Klik hier voor meer informatie.</string>
<string name="ruleLegend">Groen = ingeschakeld, rood = uitgeschakeld, geel = niet genoeg rechten</string>
<string name="systemSettingsNote1">De toestemming om sommige OS instellingen te wijzigen is vereist (zelfs eenvoudige dingen zoals bluetooth of wifi aanzetten). Nadat je op "continue" hebt geklikt zal er een venster verschijnen waar je dit moet inschakelen voor Automation. Druk daarna op de "back" toets.</string>
<string name="systemSettingsNote2">Verdere permissies zullen worden gevraagd in een tweede dialoogvenster daarna.</string>
<string name="appRequiresPermissiontoAccessExternalStorage">Automation heeft toegang nodig tot externe opslag om zijn instellingen en regels te kunnen lezen.</string>
<string name="mainScreenPermissionNote">Automation vereist meer permissies om volledig te kunnen functioneren. Klik op deze tekst om meer te weten te komen en ze aan te vragen.</string>
<string name="invalidDevice">Ongeldig apparaat</string>
<string name="logFileMaxSizeSummary">Maximale grootte logbestand in Megabyte. Zal geroteerd worden indien groter.</string>
<string name="logFileMaxSizeTitle">Maximale grootte logbestand [Mb]</string>
<string name="android.permission.READ_CALL_LOG">Telefoon log lezen</string>
<string name="android.permission.READ_CALENDAR">Lees agenda-items</string>
<string name="android.permission.ACCESS_FINE_LOCATION">Exacte locatie lezen</string>
<string name="android.permission.ACCESS_COARSE_LOCATION">Lees grove locatie</string>
<string name="readLocation">Lees locatie</string>
<string name="android.permission.INTERNET">Verzend gegevens via een netwerkverbinding</string>
<string name="android.permission.ACCESS_NETWORK_STATE">Netwerkstatus van apparaat lezen</string>
<string name="android.permission.ACCESS_WIFI_STATE">Lees de wifi status van apparaat</string>
<string name="android.permission.BLUETOOTH">Bluetooth instellingen wijzigen</string>
<string name="android.permission.BLUETOOTH_ADMIN">Bluetooth-instellingen wijzigen</string>
<string name="android.permission.NFC">Gebruik NFC-module</string>
<string name="android.permission.VIBRATE">Laat telefoon trillen</string>
<string name="android.permission.WAKE_LOCK">Telefoon aan laten staan</string>
<string name="android.permission.MODIFY_AUDIO_SETTINGS">Audio-instellingen wijzigen</string>
<string name="android.permission.RECORD_AUDIO">Audio opnemen</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Detecteer uitgaande gesprekken</string>
<string name="android.permission.MODIFY_PHONE_STATE">Apparaatinstellingen wijzigen</string>
<string name="android.permission.READ_PHONE_STATE">Detecteer telefoontoestand</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Opslag lezen</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Opslagruimte schrijven</string>
<string name="android.permission.GET_TASKS">Detecteer lopende processen</string>
<string name="android.permission.WRITE_SETTINGS">Apparaatinstellingen wijzigen</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Detecteer apparaat herstart</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Apparaatinstellingen wijzigen</string>
<string name="android.permission.BATTERY_STATS">Batterijstatus lezen</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Wijzig dataverbinding</string>
<string name="android.permission.SEND_SMS">Tekstberichten verzenden</string>
<string name="android.permission.READ_CONTACTS">Lees contactgegevens</string>
<string name="android.permission.ACCESS_NOTIFICATION_POLICY">Niet storen beleid opheffen</string>
<string name="theseAreThePermissionsRequired">Dit zijn de vereiste machtigingen:</string>
<string name="ruleXrequiresThis">Regel %1$s vereist dit.</string>
<string name="helpTextActivityDetection">Deze functie kan detecteren of je op dit moment onderweg bent en of dat te voet is of in welk type voertuig (tot op zekere hoogte). De functie is niet volledig ingebouwd in Automation, maar wordt geleverd door Google Play Services. Technisch gezien geeft het geen ja/nee resultaat, maar geeft een percentage terug tot welk niveau het zeker is dat het je status heeft gedetecteerd. U kunt de percentage waarde instellen vanaf welke Automation een resultaat zal accepteren. Twee opmerkingen: 1) Meer dan 1 status kan zich op hetzelfde moment voordoen. U kunt bijvoorbeeld WANDELEN in een rijdende bus. 2) Deze sensor is relatief duur in termen van batterijverbruik. Als het mogelijk is, zou je kunnen overwegen alternatieven te gebruiken, b.v. eisen dat het handsfree apparaat van je auto verbonden is om te detecteren dat je rijdt.</string>
<string name="sendTextMessage">Tekstbericht verzenden</string>
<string name="textToSend">Te verzenden tekst</string>
<string name="textMessageAnnotations">U kunt direct een telefoonnummer invoeren. Of gebruik de contacten optie om er een te kiezen. Maar houd in gedachten: Het nummer zal hier worden opgeslagen, niet het contact. Als je het telefoonnummer van een geselecteerde contactpersoon wijzigt, moet je deze regel bijwerken. Het doet dat niet uit zichzelf.</string>
<string name="importNumberFromContacts">Importeer nummer uit contacten</string>
<string name="android9RecordAudioNotice">Als u de ruisniveaumeter gebruikt: Helaas heeft Google vanaf Android 9 (Pie) besloten om achtergrond applicaties niet meer toe te staan de microfoon te gebruiken. Dus deze trigger heeft geen effect meer en zal niets meer triggeren.</string>
<string name="android10WifiToggleNotice">Helaas heeft Google besloten om deze functie te verwijderen in Android 10. Reguliere apps mogen wifi niet meer aan of uit zetten. Alleen als je toestel geworteld is zou het moeten blijven werken. Zo niet, dan vrees ik dat dit geen effect meer heeft.</string>
<string name="messageNotShownAgain">Deze melding zal niet meer getoond worden.</string>
<string name="chooseActivityHint">In deze laatste selectie popup moet je een specifieke activiteit selecteren. Vereenvoudigd is dit als een venster van de gewenste toepassing. Als je niet weet welke, is het meestal een goed idee om er een te kiezen met "main" of "launcher" in de naam.</string>
<string name="edit">Bewerken</string>
<string name="clickAndHoldForOptions">Klik en houd een item vast voor opties.</string>
<string name="positioningEngine">Positioning engine</string>
<string name="googleSarcasm">Dankzij de oneindige wijsheid van Google en het constante streven om ieders privacy te beschermen, zijn alle regels die gebruikt kunnen worden om sms\'jes te versturen of de telefoonstatus te lezen, ontdaan van alle triggers en acties die Google als riskant beschouwt.</string>
<string name="startAutomationAsService">Start Automation als een service</string>
<string name="setScreenBrightness">Schermhelderheid instellen</string>
<string name="setScreenBrightnessEnterValue">Voer de gewenste helderheid in (van 0 tot 100).</string>
<string name="autoBrightness">Automatische helderheid inschakelen</string>
<string name="apply">Toepassen</string>
<string name="brightnessAuto">automatische helderheid</string>
<string name="brightnessManual">handmatige helderheid</string>
<string name="autoBrightnessNotice">Als u automatische helderheid gebruikt, zal de helderheidswaarde die u hieronder gebruikt waarschijnlijk niet lang gebruikt worden.</string>
<string name="screenLockSoundNotice">Schermvergrendelingsgeluiden kunnen niet meer automatisch worden gewijzigd op apparaten met Android versie 6.0 of hoger. Wat je hier ook instelt, het zal in beide richtingen niet werken.</string>
<string name="startScreen">Startscherm</string>
<string name="startScreenSummary">Selecteer het scherm waarmee de applicaties openen bij start.</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Voer regels/profielen uit met één klik.</string>
<string name="googleLocationChicanery">Deze app verzamelt locatiegegevens om locatiegebaseerde regels en snelheidsdetectie mogelijk te maken, zelfs als de app gesloten of niet in gebruik is.</string>
<string name="googleLocationChicaneryOld">Deze app verzamelt locatiegegevens om te bepalen of u zich momenteel op een van de locaties bevindt die u hebt gemaakt. Verder wordt het gebruikt om uw huidige snelheid te bepalen als u die trigger in regels gebruikt. Dat gebeurt zelfs als de app gesloten of niet in gebruik is (maar alleen als de dienst geactiveerd is).</string>
<string name="android.permission.ACCESS_BACKGROUND_LOCATION">Lees locatie op achtergrond.</string>
<string name="deviceDoesNotHaveBluetooth">Dit apparaat lijkt geen bluetooth te hebben. U kunt nog steeds doorgaan met het configureren hiervan, maar het zal hoogstwaarschijnlijk geen effect hebben.</string>
<string name="manageLocations">Locaties maken of bewerken</string>
<string name="error">Fout</string>
<string name="featureNotInFdroidVersion">Deze functie is gebaseerd op niet-vrije software. Daarom is is niet beschikbaar in de F-Droid versie.</string>
<string name="settingsReferringToRestrictedFeatures">Uw instellingen en of regels verwijzen momenteel naar niet-vrije functies die niet kunnen worden geleverd in de F-Droid versie. Dat omvat het detecteren van uw huidige fysieke activiteit.</string>
<string name="publishedOn">gepubliceerd op</string>
<string name="displayNewsOnMainScreen">Toepassingsnieuws weergeven op hoofdscherm</string>
<string name="displayNewsOnMainScreenDescription">Aankondigingen over deze app alleen, we hebben het waarschijnlijk over 1-2 per jaar, niet meer.</string>
<string name="filesHaveBeenMovedTo">Automation gebruikt nu een ander pad om uw bestanden op te slaan. Al uw Automation-bestanden zijn hierheen verplaatst: "%s". De externe opslag permissie is niet meer nodig; u kunt het intrekken. Het zal worden verwijderd in een toekomstige versie.</string>
<string name="locationDisabled">Location disabled</string>
<string name="locationEngineDisabledShort">Locatie kan niet meer op de achtergrond worden bepaald. Klik hier om uit te vinden waarom.</string>
<string name="locationEngineDisabledLong">Helaas kan uw locatie niet meer worden bepaald. Ik ben Google dank verschuldigd voor haar oneindige wijsheid en vriendelijkheid. Laat me dit verder uitleggen. Vanaf Android 10 werd een nieuwe toestemming geïntroduceerd die nodig is om uw locatie op de achtergrond te bepalen (wat natuurlijk nodig is voor een app als deze). Hoewel ik dat in het algemeen een goed idee vind, is het gezever en ellende die het met zich meebrengt voor ontwikkelaars dat niet. Als je een app ontwikkelt, kun je proberen in aanmerking te komen voor deze toestemming door je te houden aan een catalogus van vereisten. Helaas zijn nieuwe versies van mijn app over een periode van drie maanden afgewezen. Ik voldeed aan al die eisen, de schijtlollige ontwikkelingsondersteuning van Google beweerde van niet. Nadat ik ze bewijs had gegeven dat ik dat toch had gedaan - kreeg ik een antwoord in de trant van "Ik kan u niet meer helpen". Uiteindelijk gaf ik het op. Als gevolg daarvan kan de Google Play versie uw locatie NIET meer als trigger gebruiken. Mijn enige andere optie zou zijn geweest om deze applicatie helemaal uit de winkel te laten verwijderen.Het spijt me zeer, maar ik heb mijn best gedaan om ruzie te maken met een "support" die herhaaldelijk de Turing test niet heeft doorstaan.Het goede nieuws: U kunt het allemaal nog hebben! Automation is nu open source en kan worden gevonden in F-Droid. Dat is een app winkel die echt geeft om uw privacy - in plaats van alleen maar zo te doen. Maak gewoon een back-up van uw configuratiebestand, verwijder deze app, installeer hem opnieuw vanuit F-Droid, herstel uw configuratiebestand - klaar.Klik hier voor meer informatie:</string>
<string name="filesStoredAt">Config en log bestanden worden opgeslagen in map %1$s. Klik op deze tekst om een bestandsverkenner te openen. Helaas zal dit alleen werken op een geroot apparaat. VOOR ALLE ANDERE APPARATEN: Gebruik gewoon de export knop om een backup te maken.</string>
<string name="notification">Notification</string>
<string name="title">Titel</string>
<string name="text">Tekst</string>
<string name="directionStringEquals">Gelijk aan</string>
<string name="directionStringContains">bevat</string>
<string name="directionStringStartsWith">begint met</string>
<string name="directionStringEndsWith">eindigt met</string>
<string name="directionStringNotEquals">is niet gelijk aan</string>
<string name="anyApp">Elke app</string>
<string name="notificationTriggerExplanation">Deze trigger zal reageren op andere applicaties die meldingen openen in het meldingsgebied (of die worden gesloten). Je kunt een andere applicatie specificeren waar de melding vandaan moet komen. Als je dat niet doet, tellen de meldingen van een andere toepassing mee. U kunt ook tekenreeksen opgeven die wel of niet in de titel of de body van de melding moeten voorkomen. De vergelijking gebeurt hoofdletter-IN-sensitief.</string>
<string name="postsNotification">%1$s berichten notificatie</string>
<string name="removedNotification">kennisgeving van %1$s verwijderd</string>
<string name="notificationAppears">Kennisgeving verschijnt</string>
<string name="notificationDisappears">Kennisgeving verdwijnt</string>
<string name="direction">Direction</string>
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Systeemmeldingen lezen</string>
<string name="playSound">Geluid afspelen</string>
<string name="alwaysPlay">Speel altijd af</string>
<string name="alwaysPlayExplanation">Als deze instelling actief is zal het geluid altijd worden afgespeeld. Als het gedeactiveerd is zal het alleen spelen als je telefoon niet op mute of trillen staat. Maar als het actief is, heeft het geen effect op het volume. Dus als uw telefoon op ring mode staat zal het niet het media volume verhogen bijvoorbeeld. Dus als het media volume op mute staat zal je ook niets horen.</string>
<string name="selectSoundFile">Selecteer geluidsbestand</string>
<string name="fileDoesNotExist">Bestand bestaat niet.</string>
<string name="noFileManageInstalled">Geen bestandsmanager geïnstalleerd.</string>
<string name="shareConfigAndLogFilesWithDev">Deel config en log bestanden met ontwikkelaar (via email).</string>
<string name="shareConfigAndLogExplanation">Dit zal een nieuwe email starten met uw configuratie en log bestanden als zip bestand bijgevoegd. Het zal niet automatisch verzonden worden, je moet nog steeds op "verzenden" drukken. U kunt ook de ontvanger veranderen in bijvoorbeeld uzelf.</string>
<string name="startAppChoiceNote">Hier heeft u 2 algemene opties:. Je kunt een programma starten door een activiteit te selecteren. Stel je dit voor als het voorselecteren van een specifiek scherm/venster van een applicatie. Onthoud dat dit niet altijd zal werken. Dit komt omdat de vensters van een toepassing met elkaar kunnen interageren, bv. parameters doorgeven. Bij het botweg starten van een specifiek scherm heeft die interactie niet plaatsgevonden en kan het venster direct sluiten (waardoor het nooit echt getoond wordt). Probeer het desondanks! Je kunt een activiteitspad handmatig invoeren, maar het is aan te bevelen om de knop "Kiezen" te gebruiken. Als u besluit het pad handmatig in te voeren, voer dan in het bovenste veld de pakketnaam van de toepassing in en in het onderste veld het volledige pad van de activiteit.. Selectie door actie In tegenstelling tot het selecteren van een specifiek venster kunt u een programma ook door een actie starten. Dit is hetzelfde als roepen "Ik zou graag xyz willen" en als er een programma is geïnstalleerd dat u daarbij kan helpen, wordt het gestart. Een goed voorbeeld zou kunnen zijn start browser - je kunt er zelfs meerdere geïnstalleerd hebben (een is meestal de standaard). U moet dit handmatig invoeren, PackageName is hier optioneel. Houd in gedachten dat er geen variabelen zullen worden opgelost. Als je bijvoorbeeld de camera wilt starten met "MediaStore.ACTION_IMAGE_CAPTURE" zal dat niet werken. U moet een kijkje nemen in de Android documentatie en in plaats daarvan de werkelijke waarde van deze variabele gebruiken, die in dit voorbeeld zou zijn: "android.media.action.IMAGE_CAPTURE"</string>
<string name="errorRunningRule">Er is een fout opgetreden bij het uitvoeren van een regel.</string>
<string name="cantFindSoundFile">Kan geluidsbestand %1$s niet vinden en daarom niet afspelen.</string>
<string name="addParameters">Parameters toevoegen</string>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controle tunnels van de wireguard app</string>
<string name="startAppSelectionType">Methode om toepassing te selecteren</string>
<string name="startAppByActivity">op activiteit</string>
<string name="startAppByAction">op actie</string>
<string name="enterValidAction">Voer een geldige actie in</string>
<string name="enterPackageName">Voer een geldige pakketnaam in.</string>
<string name="state">Staat</string>
<string name="phoneNumberExplanation">U kunt een specifiek telefoonnummer opgeven, maar dat hoeft niet. Als u er een wilt opgeven, kunt u er een uit uw adresboek kiezen of het handmatig invoeren. Daarnaast kun je reguliere expressies gebruiken. Om een reguliere expressie te testen is deze pagina behulpzaam:</string>
<string name="importConfiguration">Import configuration</string>
<string name="exportConfiguration">Export configuration</string>
<string name="moreSettings">Meer instellingen</string>
<string name="configurationExportedSuccessfully">Configuratie succesvol geëxporteerd.</string>
<string name="ConfigurationExportError">Er is een fout opgetreden tijdens het exporteren van de configuratie.</string>
<string name="rulesImportedSuccessfully">Regels en locaties zijn succesvol geïmporteerd.</string>
<string name="rulesImportError">Er is een fout opgetreden bij het importeren van regels en locaties.</string>
<string name="configurationImportedSuccessfully">Configuratie succesvol geïmporteerd.</string>
<string name="prefsImportError">Er is een fout opgetreden bij het importeren van de voorkeuren.</string>
<string name="noApplicableFilesFoundInDirectory">Er konden geen toepasbare bestanden gevonden worden in die directory.</string>
<string name="noFilesImported">Er kon geen bestand geïmporteerd worden.</string>
<string name="notAllFilesImported">Niet alle toepasbare bestanden konden geïmporteerd worden.</string>
<string name="importExportExplanation">Wanneer u klikt op importeren of exporteren selecteert u de map van waaruit bestanden worden geïmporteerd of geëxporteerd. Bij het exporteren kunnen bestaande bestanden overschreven worden.</string>
<string name="intentDataComment">Als je parameter van het type Uri is EN je specificeert "IntentData" als naam (kleine/hoofdletter is niet belangrijk), dan zal de parameter niet als een normale parameter worden toegevoegd met putExtra(), maar zal in plaats daarvan worden toegevoegd aan de intent met setData().</string>
<string name="stringNotAllowed">String %1$s is niet toegestaan.</string>
<string name="startAppStartType">Selecteer start type</string>
<string name="startAppByStartActivity">by startActivity()</string>
<string name="startAppBySendBroadcast">by sendBroadcast()</string>
<string name="openExamplesPage">Open webpagina met voorbeelden</string>
<string name="packageName">Naam pakket</string>
<string name="activityOrActionName">Activity/action name</string>
<string name="warning">Warning</string>
<string name="ringing">ringing</string>
<string name="from">van</string>
<string name="to">naar</string>
<string name="matching">matching</string>
<string name="loadWifiList">Laad wifi lijst</string>
<string name="needLocationPermForWifiList">De lijst met wifi\'s waarmee je apparaat verbonden is geweest, kan worden gebruikt om te bepalen op welke plaatsen je bent geweest. Daarom is de locatietoestemming nodig om de lijst met wifi\'s te laden. Als je er een uit de lijst wilt kunnen kiezen, moet je die toestemming geven. Als u dat niet wilt, kunt u nog steeds uw wifi-naam handmatig invoeren.</string>
<string name="noKnownWifis">Er zijn geen bekende wifis op uw apparaat.</string>
<string name="urlToTriggerExplanation">Deze functie opent GEEN browser, maar triggert een URL op de achtergrond. U kunt dit bijvoorbeeld gebruiken om commando\'s naar uw homeAutomation te sturen.</string>
<string name="automaticUpdateCheck">Controleer op updates</string>
<string name="automaticUpdateCheckSummary">Geldt alleen voor APK versie.</string>
<string name="updateAvailable">Er is een nieuwe update beschikbaar. Wilt u de browser openen om deze te downloaden?</string>
<string name="locationFound">Locatie gevonden. De voorgestelde minimum radius voor locaties is %1$d m.</string>
<string name="locationFoundInaccurate">Alleen een locatie met een beperkte nauwkeurigheid kon worden gevonden. Het werkt misschien niet betrouwbaar. De voorgestelde minimale straal voor locaties is %1$d.</string>
<string name="clone">kloon</string>
<string name="noLocationCouldBeFound">Er kon geen positie worden gevonden na een time-out van %1$s seconden.</string>
<string name="pleaseGiveBgLocation">Ga in het volgende scherm naar machtigingen, dan naar locatie. Selecteer daar "Sta alle tijden toe" om Automation toe te staan uw locatie op de achtergrond te bepalen.</string>
<string name="vibrate">Tril</string>
<string name="test">Test</string>
<string name="VibrateExplanation">Voer een trilduur in, gevolgd door een komma, en vervolgens een pauze duur. U kunt zoveel trillingen aaneenkoppelen als u wilt. Scheid ze weer door komma\'s. Bijv. het patroon 100,500,500,1000,100 zal 100 trillen, 500 wachten, 500 trillen, 1000 wachten, 100 ms trillen. Als je denkt dat een trilling wegvalt, probeer dan de pauze ervoor te vergroten.</string>
<string name="pleaseEnterValidVibrationPattern">Voer a.u.b. een geldig trilpatroon in.</string>
<string name="newsOptIn">Wilt u (alleen belangrijk) nieuws over deze app op het hoofdscherm ontvangen? Deze worden gedownload van de website van de ontwikkelaar. Er komt geen opdringerige melding, alleen een tekst op het hoofdscherm als u de app opent.</string>
<string name="top">boven</string>
<string name="bottom">onder</string>
<string name="tabsPlacement">Positie van tabbalk</string>
<string name="tabsPlacementSummary">Kies waar de tabbladenbalk geplaatst moet worden.</string>
<string name="wifiApi30">Omdat Google weer een ander deel van Android verpest heeft, kunnen vanaf API 30 alleen de op dat moment zichtbare Wifi netwerken worden weergegeven. Niet alle Wifi netwerken die uw apparaat kent.</string>
<string name="smsDialogNotice">Als u niet eerder een verzend-sms actie in dit programma hebt gebruikt, kan Android een extra bevestigingsdialoog tonen, waarin u wordt gevraagd om het verzenden van berichten toe te staan. U moet het vakje "altijd toestaan" aanvinken en bevestigen als u wilt dat deze actie op de achtergrond werkt. Het wordt aangeraden om deze regel eenmaal handmatig uit te voeren.</string>
<string name="silentTriggersDnd">OPMERKING: De stille modus triggert vaak Do-Not-Disturb op nieuwere apparaten. Als dat op jouw apparaat gebeurt, raad ik aan om in plaats daarvan de normale modus te gebruiken en alle volumes naar nul te verlagen.</string>
<string name="tones">Tonen</string>
<string name="miscellaneous">Varia</string>
<string name="dnd">Niet-storen</string>
<string name="dndOff">Niet-storen uit</string>
<string name="dndPriority">Laat meldingen met prioriteit door</string>
<string name="dndAlarms">Laat Alarmen door</string>
<string name="dndNothing">Niets doorlaten</string>
<string name="dndRemarks">Fijnafstelling (zoals telefoongesprekken toestaan, specifieke nummers kiezen, etc.) kan alleen via de instellingen van het systeem.</string>
<string name="permissionsRequiredNotAvailable">Uw regels vereisten permissies die niet kunnen worden opgevraagd vanuit deze geïnstalleerde smaak van Automation.</string>
<string name="automationNotificationsIgnored">Als u niet kiest voor een specifieke app, maar kiest voor "Elke app" zullen meldingen van Automation genegeerd worden om lussen te voorkomen.</string>
<string name="repeatEveryXseconds">Herhaal elke x seconden</string>
<string name="repeatEveryXsecondsWithVariable">Herhaal elke %1$s seconden</string>
<string name="enterRepetitionTime">Je moet een positieve niet-decimale waarde invoeren voor de herhalingstijd.</string>
<string name="elementSkipped">Een element van het configuratiebestand kon niet worden gelezen. Mogelijk is het bestand gemaakt in een nieuwere programmaversie.</string>
<string name="donate">Doneren</string>
<string name="unknown">onbekend</string>
<string name="orientation">Oriëntatie</string>
<string name="turnScreenOnOrOff">Scherm in- of uitschakelen</string>
<string name="turnScreenOn">scherm inschakelen</string>
<string name="turnScreenOff">scherm uitschakelen</string>
<string name="mustApply">Moet van toepassing zijn</string>
<string name="deviceOrientationTimeAcceptIntervalTitle">Signaalfrequentie</string>
<string name="deviceOrientationSettings">Instellingen voor apparaatstand</string>
<string name="android.permission.BIND_DEVICE_ADMIN">Apparaatbeheerder</string>
<string name="deviceAdminNote">Apparaatbeheerdersmachtigingen vereist voor ten minste 1 regel die u hebt gemaakt.</string>
<string name="deviceOrientationTimeAcceptIntervalSummary">Accepteer elke x milliseconden nieuwe bewegingssignalen</string>
<string name="explanationDeviceOrientationDirection">Als het selectievakje is aangevinkt, betekent dit dat het apparaat zich in de door u opgegeven richting moet bevinden. Als het niet is gecontroleerd, is elke oriëntatie die NIET aan uw criteria voldoet voldoende.</string>
<string name="triggerWrong">Er is iets mis met deze trigger. Het kan niet correct worden geladen.</string>
<string name="orientationAzimuth">Azimut:</string>
<string name="orientationPitch">Pitch:</string>
<string name="orientationRoll">Rollen:</string>
<string name="enterValidNumbersIntoAllFields">Voer geldige nummers in alle velden in.</string>
<string name="deviceOrientation">Apparaat oriëntatie</string>
<string name="notice">Bemerken</string>
<string name="tolerance">Tolerantie (0-180)</string>
<string name="actionSetBluetoothTethering">Bluetooth Tethering</string>
<string name="enterPhoneNumberAndText">Voer een telefoonnummer en een sms in.</string>
<string name="actionTurnBluetoothTetheringOn">Schakel Bluetooth Tethering in</string>
<string name="actionTurnBluetoothTetheringOff">Schakel Bluetooth Tethering uit</string>
<string name="deviceIsInCertainOrientation">het apparaat zich in een bepaalde richting bevindt</string>
<string name="wouldCurrentlyApply">Zou momenteel van toepassing zijn?</string>
<string name="btTetheringNotice">Deze functie werkt naar verluidt tot Android 8.0. Vanaf een hogere versie werkt het niet meer, maar door een gebrek aan fysieke apparaten kan ik niet zeggen welke dat is. Op Android 11 werkt het absoluut niet meer. Als je een versie tussendoor hebt, laat het me dan weten of het werkt of niet.</string>
<string name="deviceOrientationExplanation">Wanneer u uw apparaat verplaatst, worden de onderstaande nummers bijgewerkt. Wat je daar kunt zien, is de huidige oriëntatie van je apparaat gemeten in graden. Als het zich in de gewenste richting bevindt, klikt u op de knop Toepassen om de huidige waarden naar de gewenste velden te kopiëren.\nOmdat het zeer onwaarschijnlijk is dat u deze exacte oriëntatie ooit nog bereikt, moet u ook een tolerantie invoeren. Dit is het aantal graden waarin de oriëntatie in beide richtingen kan afwijken. 15° resulteert in een totale hoek van 30°, 15° in elke richting.\nAls u slechts om één specifieke as geeft, geef dan een tolerantie van 180° op voor de twee andere.</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">Een tolerantie van 180 is alleen toegestaan voor 2 tolerantievelden, niet alle 3. Anders zou de trigger ALTIJD van toepassing zijn.</string>
</resources>

View File

@ -12,7 +12,6 @@
<color name="black">#000000</color> <color name="black">#000000</color>
<color name="brightScreenBackgroundColor">#F3F3F3</color> <color name="brightScreenBackgroundColor">#F3F3F3</color>
<color name="brightScreenTextColor">#FFFFFF</color> <color name="brightScreenTextColor">#FFFFFF</color>
<color name="darkScreenBackgroundColor">#FFFFFF</color> <color name="darkScreenBackgroundColor">#444444</color>
<color name="darkScreenTextColor">#F3F3F3</color> <color name="darkScreenTextColor">#eeeeee</color>
</resources>
</resources>

View File

@ -76,7 +76,7 @@
<string name="deactivating">Deactivating</string> <string name="deactivating">Deactivating</string>
<string name="bluetoothFailed">Failed to trigger Bluetooth. Does this device have Bluetooth?</string> <string name="bluetoothFailed">Failed to trigger Bluetooth. Does this device have Bluetooth?</string>
<string name="urlTooShort">The url has to have least 10 characters.</string> <string name="urlTooShort">The url has to have least 10 characters.</string>
<string name="textTooShort">The text has to have least 10 characters.</string> <string name="enterPhoneNumberAndText">Enter a phone number and a text.</string>
<string name="selectTypeOfTrigger">Select type of trigger</string> <string name="selectTypeOfTrigger">Select type of trigger</string>
<string name="entering">entering</string> <string name="entering">entering</string>
<string name="leaving">leaving</string> <string name="leaving">leaving</string>
@ -158,6 +158,7 @@
<string name="actionSetBluetooth">Bluetooth</string> <string name="actionSetBluetooth">Bluetooth</string>
<string name="actionSetUsbTethering">USB Tethering</string> <string name="actionSetUsbTethering">USB Tethering</string>
<string name="actionSetWifiTethering">Wifi Tethering</string> <string name="actionSetWifiTethering">Wifi Tethering</string>
<string name="actionSetBluetoothTethering">Bluetooth Tethering</string>
<string name="actionSetDisplayRotation">Display rotation</string> <string name="actionSetDisplayRotation">Display rotation</string>
<string name="actionTurnWifiOn">turn Wifi on</string> <string name="actionTurnWifiOn">turn Wifi on</string>
<string name="actionTurnWifiOff">turn Wifi off</string> <string name="actionTurnWifiOff">turn Wifi off</string>
@ -169,6 +170,8 @@
<string name="actionTurnUsbTetheringOff">turn USB Tethering off</string> <string name="actionTurnUsbTetheringOff">turn USB Tethering off</string>
<string name="actionTurnWifiTetheringOn">turn Wifi Tethering on</string> <string name="actionTurnWifiTetheringOn">turn Wifi Tethering on</string>
<string name="actionTurnWifiTetheringOff">turn Wifi Tethering off</string> <string name="actionTurnWifiTetheringOff">turn Wifi Tethering off</string>
<string name="actionTurnBluetoothTetheringOn">turn Bluetooth Tethering on</string>
<string name="actionTurnBluetoothTetheringOff">turn Bluetooth Tethering off</string>
<string name="actionTurnAirplaneModeOn">turn airplane mode on</string> <string name="actionTurnAirplaneModeOn">turn airplane mode on</string>
<string name="actionTurnAirplaneModeOff">turn airplane mode off</string> <string name="actionTurnAirplaneModeOff">turn airplane mode off</string>
<string name="actionEnableScreenRotation">enable screen rotation</string> <string name="actionEnableScreenRotation">enable screen rotation</string>
@ -209,15 +212,15 @@
<string name="wifiName">Wifi name</string> <string name="wifiName">Wifi name</string>
<string name="enterWifiName">Enter a wifi name. Leave empty for any wifi.</string> <string name="enterWifiName">Enter a wifi name. Leave empty for any wifi.</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="ruleDoesntApplyWeAreSlowerThan" translatable="false">Rule doesn\'t apply. We are slower than</string> <string name="ruleDoesntApplyWeAreSlowerThan" translatable="false">Rule %1$s doesn\'t apply. We are slower than</string>
<string name="ruleDoesntApplyWeAreFasterThan" translatable="false">Rule doesn\'t apply. We are faster than</string> <string name="ruleDoesntApplyWeAreFasterThan" translatable="false">Rule %1$s doesn\'t apply. We are faster than</string>
<string name="ruleDoesntApplyItsQuieterThan" translatable="false">Rule doesn\'t apply. It\'s quieter than</string> <string name="ruleDoesntApplyItsQuieterThan" translatable="false">Rule %1$s doesn\'t apply. It\'s quieter than</string>
<string name="ruleDoesntApplyItsLouderThan" translatable="false">Rule doesn\'t apply. It\'s louder than</string> <string name="ruleDoesntApplyItsLouderThan" translatable="false">Rule %1$s doesn\'t apply. It\'s louder than</string>
<string name="ruleDoesntApplyBatteryLowerThan" translatable="false">Rule doesn\'t apply. Battery level is lower than</string> <string name="ruleDoesntApplyBatteryLowerThan" translatable="false">Rule %1$s doesn\'t apply. Battery level is lower than</string>
<string name="ruleDoesntApplyBatteryHigherThan" translatable="false">Rule doesn\'t apply. Battery level is higher than</string> <string name="ruleDoesntApplyBatteryHigherThan" translatable="false">Rule %1$s doesn\'t apply. Battery level is higher than</string>
<string name="ruleDoesntApplyNotTheCorrectSsid" translatable="false">Rule doesn\'t apply. Not the correct SSID (demanded: \"%1$s\", given: \"%2$s\").</string> <string name="ruleDoesntApplyNotTheCorrectSsid" translatable="false">Rule %1$s doesn\'t apply. Not the correct SSID (demanded: \"%2$s\", given: \"%3$s\").</string>
<string name="ruleDoesntApplyNoTagLabel" translatable="false">Rule doesn\'t apply. There is no tag label or not tag at all.</string> <string name="ruleDoesntApplyNoTagLabel" translatable="false">Rule %1$s doesn\'t apply. There is no tag label or not tag at all.</string>
<string name="ruleDoesntApplyWrongTagLabel" translatable="false">Rule doesn\'t apply. Wrong tag label.</string> <string name="ruleDoesntApplyWrongTagLabel" translatable="false">Rule %1$s doesn\'t apply. Wrong tag label.</string>
<string name="ruleIsDeactivatedCantApply" translatable="false">Rule %1$s is deactivated, can\'t apply.</string> <string name="ruleIsDeactivatedCantApply" translatable="false">Rule %1$s is deactivated, can\'t apply.</string>
<string name="starting">starting</string> <string name="starting">starting</string>
<string name="stopping">stopping</string> <string name="stopping">stopping</string>
@ -401,8 +404,8 @@
<string name="detectedActivityWalking">Walking</string> <string name="detectedActivityWalking">Walking</string>
<string name="detectedActivityRunning">Running</string> <string name="detectedActivityRunning">Running</string>
<string name="detectedActivityInvalidStatus">Invalid activity</string> <string name="detectedActivityInvalidStatus">Invalid activity</string>
<string name="ruleDoesntApplyActivityGivenButTooLowProbability" translatable="false">Rule doesn\'t apply. Detected activity %1$s given, but too low probability (%2$s %%), required %3$s %%.</string> <string name="ruleDoesntApplyActivityGivenButTooLowProbability" translatable="false">Rule %1$s doesn\'t apply. Detected activity %2$s given, but too low probability (%3$s %%), required %4$s %%.</string>
<string name="ruleDoesntApplyActivityNotPresent" translatable="false">Rule doesn\'t apply. Required activity %1$s not present.</string> <string name="ruleDoesntApplyActivityNotPresent" translatable="false">Rule %1$s doesn\'t apply. Required activity %2$s not present.</string>
<string name="selectTypeOfActivity">Select type of activity</string> <string name="selectTypeOfActivity">Select type of activity</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">This trigger is only available if Google Play Services is installed.</string> <string name="triggerOnlyAvailableIfPlayServicesInstalled">This trigger is only available if Google Play Services is installed.</string>
<string name="activityDetectionFrequencyTitle">Activity detection frequency [sec]</string> <string name="activityDetectionFrequencyTitle">Activity detection frequency [sec]</string>
@ -422,8 +425,8 @@
<string name="bluetoothDeviceInRange">Bluetooth device %1$s in range.</string> <string name="bluetoothDeviceInRange">Bluetooth device %1$s in range.</string>
<string name="bluetoothDeviceOutOfRange">Bluetooth device %1$s out of range.</string> <string name="bluetoothDeviceOutOfRange">Bluetooth device %1$s out of range.</string>
<string name="anyDevice">any device</string> <string name="anyDevice">any device</string>
<string name="ruleDoesntApplyNotTheCorrectDeviceName" translatable="false">Rule doesn\'t apply. Not the correct bluetooth device name.</string> <string name="ruleDoesntApplyNotTheCorrectDeviceName" translatable="false">Rule %1$s doesn\'t apply. Not the correct bluetooth device name.</string>
<string name="ruleDoesntApplyNotTheCorrectDeviceAddress" translatable="false">Rule doesn\'t apply. Not the correct bluetooth device address.</string> <string name="ruleDoesntApplyNotTheCorrectDeviceAddress" translatable="false">Rule %1$s doesn\'t apply. Not the correct bluetooth device address.</string>
<string name="noDevice">no device</string> <string name="noDevice">no device</string>
<string name="selectDeviceFromList">one from list</string> <string name="selectDeviceFromList">one from list</string>
<string name="connectionToDevice">connection to device</string> <string name="connectionToDevice">connection to device</string>
@ -432,8 +435,8 @@
<string name="deviceOutOfRange">device out of range</string> <string name="deviceOutOfRange">device out of range</string>
<string name="selectDeviceOption">Select a device option.</string> <string name="selectDeviceOption">Select a device option.</string>
<string name="selectConnectionOption">Select a connection option.</string> <string name="selectConnectionOption">Select a connection option.</string>
<string name="ruleDoesntApplyDeviceInRangeButShouldNotBe" translatable="false">Rule doesn\'t apply. Device is in range, but should not be.</string> <string name="ruleDoesntApplyDeviceInRangeButShouldNotBe" translatable="false">Rule %1$s doesn\'t apply. Device is in range, but should not be.</string>
<string name="ruleDoesntApplyStateNotCorrect" translatable="false">Rule doesn\'t apply. Wrong state.</string> <string name="ruleDoesntApplyStateNotCorrect" translatable="false">Rule %1$s doesn\'t apply. Wrong state.</string>
<string name="triggerHeadsetPlugged">Headset connection</string> <string name="triggerHeadsetPlugged">Headset connection</string>
<string name="actionPlayMusic">Open music player</string> <string name="actionPlayMusic">Open music player</string>
<string name="headsetConnected">Headset (type: %1$s) connected</string> <string name="headsetConnected">Headset (type: %1$s) connected</string>
@ -442,7 +445,7 @@
<string name="headphoneMicrophone">Microphone</string> <string name="headphoneMicrophone">Microphone</string>
<string name="headphoneAny">Either</string> <string name="headphoneAny">Either</string>
<string name="headphoneSelectType">Select type of headphone</string> <string name="headphoneSelectType">Select type of headphone</string>
<string name="ruleDoesntApplyWrongHeadphoneType" translatable="false">Rule doesn\'t apply. Wrong headphone type.</string> <string name="ruleDoesntApplyWrongHeadphoneType" translatable="false">Rule %1$s doesn\'t apply. Wrong headphone type.</string>
<string name="ignoringActivityDetectionUpdateTooSoon" translatable="false">Ignoring activity detection update. Came in sooner that %1$s seconds.</string> <string name="ignoringActivityDetectionUpdateTooSoon" translatable="false">Ignoring activity detection update. Came in sooner that %1$s seconds.</string>
<string name="whatsThis">What\'s this?</string> <string name="whatsThis">What\'s this?</string>
<string name="atLeastRuleXisUsingY" translatable="false">At least rule \"%1$s\" is using a trigger of type \"%2$s\".</string> <string name="atLeastRuleXisUsingY" translatable="false">At least rule \"%1$s\" is using a trigger of type \"%2$s\".</string>
@ -453,7 +456,7 @@
<string name="gpsMeasurement" translatable="false">GPS measurement</string> <string name="gpsMeasurement" translatable="false">GPS measurement</string>
<string name="gpsMeasurementTimeout" translatable="false">GPS measurement stopped due to timeout.</string> <string name="gpsMeasurementTimeout" translatable="false">GPS measurement stopped due to timeout.</string>
<string name="cellMastChanged" translatable="false">Cell tower changed: %1$s</string> <string name="cellMastChanged" translatable="false">Cell tower changed: %1$s</string>
<string name="noiseDetectionHint">If you think the noise detection isn\'t working correctly (depending on the value you specify) please keep in mind that every phone is different. You can therefore change \"Reference for noise measurement\" in settings. See http://en.wikipedia.org/wiki/Decibel for more information. You can use the volume tester from the main screen to calibrate your device.</string> <string name="noiseDetectionHint">If you think the noise detection isn\'t working correctly (depending on the value you specify) please keep in mind that every phone is different. You can therefore change \"Reference for noise measurement\" in settings. See http://en.wikipedia.org/wiki/Decibel for more information. You can use the volume calibrator from the main screen to calibrate your device.</string>
<string name="hint">Hint</string> <string name="hint">Hint</string>
<string name="selectNoiseLevel">Select noise level</string> <string name="selectNoiseLevel">Select noise level</string>
<string name="poiHasWifiStoppingCellLocationListener" translatable="false">Location has wifi. Stopping CellLocationChangedReceiver.</string> <string name="poiHasWifiStoppingCellLocationListener" translatable="false">Location has wifi. Stopping CellLocationChangedReceiver.</string>
@ -500,8 +503,8 @@
<string name="noProfileChangeSoundLocked">Profile will not be activated. Last activated profile has been locked.</string> <string name="noProfileChangeSoundLocked">Profile will not be activated. Last activated profile has been locked.</string>
<string name="currentVolume">Current volume</string> <string name="currentVolume">Current volume</string>
<string name="enterValidReferenceValue">Enter a valid reference value.</string> <string name="enterValidReferenceValue">Enter a valid reference value.</string>
<string name="volumeTest">Volume test</string> <string name="volumeTest">Volume calibration</string>
<string name="volumeTesterExplanation">To calculate a dB value for noise monitoring you need to specify a so called physical reference value. Please read Wikipedia for further information. This value is most likely different for every phone. Drag the seekbar to change the defined physical reference value. The higher the reference value the lower the dB value will be. Constant measurings will be performed every %1$s seconds and the results displayed below. Press back when you have found a suitable value.</string> <string name="volumeCalibrationExplanation">To calculate a dB value for noise monitoring you need to specify a so called physical reference value. Please read Wikipedia for further information. This value is most likely different for every phone. Drag the seekbar to change the defined physical reference value. The higher the reference value the lower the dB value will be. Constant measurings will be performed every %1$s seconds and the results displayed below. Press back when you have found a suitable value.</string>
<string name="settingsWillTakeTime">Some settings will not be applied before certain environment settings change or service is restarted.</string> <string name="settingsWillTakeTime">Some settings will not be applied before certain environment settings change or service is restarted.</string>
<string name="phoneIsRooted" translatable="false">Phone is rooted.</string> <string name="phoneIsRooted" translatable="false">Phone is rooted.</string>
<string name="phoneIsNotRooted" translatable="false">Phone is not rooted.</string> <string name="phoneIsNotRooted" translatable="false">Phone is not rooted.</string>
@ -690,8 +693,7 @@
<string name="bottom">Bottom</string> <string name="bottom">Bottom</string>
<string name="tabsPlacement">Position of tab bar</string> <string name="tabsPlacement">Position of tab bar</string>
<string name="tabsPlacementSummary">Choose where the tabs bar should be placed.</string> <string name="tabsPlacementSummary">Choose where the tabs bar should be placed.</string>
<string name="wifiApi30">Because Google screwd up yet another part of Android, starting with API 30 only the currently visible wifis can be displayed. Not all the ones your device knows.</string> <string name="wifiApi30">Because Google screwed up yet another part of Android, starting with API 30 only the currently visible wifis can be displayed, not all the ones your device has connected to anymore.</string>
<string name="smsDialogNotice">If you have not used a send-sms action in this program before, Android may show an additional confirmation dialog, asking you to allow sending messages. You need to select the \"always allow\" checkbox and confirm if you want this action to work in the background. It\'s advised to run this rule manually once.</string>
<string name="silentTriggersDnd">REMARK: The silent mode often triggers Do-Not-Disturb on newer devices. If that happens on your device, I recommend using the normal mode instead and lowering all volumes to zero.</string> <string name="silentTriggersDnd">REMARK: The silent mode often triggers Do-Not-Disturb on newer devices. If that happens on your device, I recommend using the normal mode instead and lowering all volumes to zero.</string>
<string name="tones">Tones</string> <string name="tones">Tones</string>
<string name="miscellaneous">Miscellaneous</string> <string name="miscellaneous">Miscellaneous</string>
@ -701,5 +703,37 @@
<string name="dndAlarms">Let alarms through</string> <string name="dndAlarms">Let alarms through</string>
<string name="dndNothing">Let nothing through</string> <string name="dndNothing">Let nothing through</string>
<string name="dndRemarks">Fine tuning (like allowing phone calls, picking specific numbers, etc.) can only be done from the system\'s settings.</string> <string name="dndRemarks">Fine tuning (like allowing phone calls, picking specific numbers, etc.) can only be done from the system\'s settings.</string>
<string name="automationNotificationsIgnored">If you do not choose a specific app, but choose \"Any app\", notifications from Automation will be ignored to avoid loops.</string>
<string name="repeatEveryXseconds">Repeat every x seconds</string>
<string name="repeatEveryXsecondsWithVariable">repeat every %1$s seconds</string>
<string name="enterRepetitionTime">You need to enter a positive non-decimal value for repetition time.</string>
<string name="elementSkipped">An element of the configuration file could not be read. The file may have been created by a newer program version.</string>
<string name="donate">Donate</string>
<string name="btTetheringNotice">This feature is confirmed to work up until Android 8.0. From some higher version upwards it ceases to work, but due to a lack of physical devices I cannot tell which one that is. On Android 11 it definitely ain\'t working anymore. If you have a version in between please let me know if it\'s working or not.</string>
<string name="notice">Notice</string>
<string name="deviceOrientation">Device orientation</string>
<string name="tolerance">Tolerance (0-180)</string>
<string name="orientationAzimuth">Azimuth:</string>
<string name="orientationPitch">Pitch:</string>
<string name="orientationRoll">Roll:</string>
<string name="enterValidNumbersIntoAllFields">Enter valid numbers in all fields.</string>
<string name="deviceOrientationExplanation">When you move your device the below numbers will update. What you can see there, is the current orientation of your device measured in degrees. If it is in the desired orientation, click the apply button to copy the current values to the desired fields. Because reaching this exact orientation ever again is highly unlikely you must also enter a tolerance. This is amount of degrees to which the orientation can deviate in either direction. 15° will result in a total angle of 30°, 15° in every direction. If you only care about one specific axis, specify a tolerance of 180° for the two other ones.</string>
<string name="wouldCurrentlyApply">Would currently apply?</string>
<string name="deviceIsInCertainOrientation">the device is in a certain orientation</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">A tolerance of 180 is allowed for 2 tolerance fields only, not all 3. Otherwise the trigger would ALWAYS apply.</string>
<string name="unknown">unknown</string>
<string name="orientation">Orientation</string>
<string name="triggerWrong">There\'s something wrong with this trigger. It could not be loaded correctly.</string>
<string name="turnScreenOnOrOff">Turn screen on or off</string>
<string name="turnScreenOn">turn screen on</string>
<string name="turnScreenOff">turn screen off</string>
<string name="mustApply">Must apply</string>
<string name="deviceOrientationTimeAcceptIntervalTitle">Signal frequency</string>
<string name="deviceOrientationTimeAcceptIntervalSummary">Accept new movement signals every x milliseconds</string>
<string name="deviceOrientationSettings">Device orientation settings</string>
<string name="android.permission.BIND_DEVICE_ADMIN">Device administrator</string>
<string name="deviceAdminNote">Device administrator permissions required for at least 1 rule you created.</string>
<string name="explanationDeviceOrientationDirection">If the checkbox is checked that means the device has to be in the orientation you specify. If it\'s not checked, any orientation that does NOT match your criteria will do.</string>
<string name="permissionsRequiredNotAvailable">Your rules required permissions which cannot be requested from this installed flavor of Automation.</string> <string name="permissionsRequiredNotAvailable">Your rules required permissions which cannot be requested from this installed flavor of Automation.</string>
<string name="smsDialogNotice">If you have not used a send-sms action in this program before, Android may show an additional confirmation dialog, asking you to allow sending messages. You need to select the \"always allow\" checkbox and confirm if you want this action to work in the background. It\'s advised to run this rule manually once to provoke this confirmation dialog.</string>
</resources> </resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<force-lock />
</uses-policies>
</device-admin>

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.3' classpath 'com.android.tools.build:gradle:7.0.4'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@ -19,18 +19,20 @@ Mögliche Auslöser:
* Headset verbunden * Headset verbunden
* Telefongespräch im Gange * Telefongespräch im Gange
* Benachrichtigungen anderer Anwendungen * Benachrichtigungen anderer Anwendungen
* Geräteausrichtung (Gyroskop)
Mögliche Aktionen: Mögliche Aktionen:
* WLAN ein-/ausschalten * WLAN ein-/ausschalten
* Bluetooth ein-/ausschalten * Bluetooth ein-/ausschalten
* USB Router ein-/ausschalten * USB Router ein-/ausschalten
* WLAN Router ein-/ausschalten * WLAN Router ein-/ausschalten
* Bluetooth Router ein-/ausschalten
* Bildschirmdrehung ein-/ausschalten * Bildschirmdrehung ein-/ausschalten
* HTTP Request im Hintergrund auslösen * HTTP Request im Hintergrund auslösen
* Klingelton und Toneinstellungen ändern * Klingelton und Toneinstellungen ändern
* Eine andere Anwendung starten * Eine andere Anwendung starten
* Warten (zwischen anderen Aktionen) * Warten (zwischen anderen Aktionen)
* Den Bildschirm des Geräts einschalten * Bildschirm ein-/ausschalten
* Flugzeugmodus ein-/ausschalten * Flugzeugmodus ein-/ausschalten
* Datenverbindung ein-/ausschalten * Datenverbindung ein-/ausschalten
* Text sprechen (TTS) * Text sprechen (TTS)
@ -42,10 +44,12 @@ Mögliche Aktionen:
Es ist ziemlich schwierig diese Anwendung über die vielen verschiedenen Geräte und Android Versionen am Laufen zu halten. Ich kann vieles im Emulator testen, aber eben nicht alles. Es ist ziemlich schwierig diese Anwendung über die vielen verschiedenen Geräte und Android Versionen am Laufen zu halten. Ich kann vieles im Emulator testen, aber eben nicht alles.
Wenn also eine bestimmte Funktion nicht so tut wie sie sollte - lassen Sie es mich wissen. Über die Jahre habe ich noch alle Fehler behoben, die mir vernünftig gemeldet wurden. Aber dafür bin ich auf Ihre Mithilfe angewiesen. Wenn also eine bestimmte Funktion nicht so tut wie sie sollte - lassen Sie es mich wissen. Über die Jahre habe ich noch alle Fehler behoben, die mir vernünftig gemeldet wurden. Aber dafür bin ich auf Ihre Mithilfe angewiesen.
Wenn Sie ein Problem mit der Anwendung haben und mich dazu kontaktieren möchten, updaten Sie bitte vorher auf die neueste Version und schauen Sie, ob Ihr Problem darin auch besteht. Wenn Sie ein Problem mit der Anwendung haben und mich dazu kontaktieren möchten
- updaten Sie bitte vorher auf die neueste Version und schauen Sie, ob Ihr Problem darin auch besteht.
- prüfen Sie, ob Ihr Problem schon bekannt ist: https://server47.de/automation/index.php#knownProblems
Spenden sind sicher eine gute, aber nicht die einzige Möglichkeit mich zu motivieren :-) Spenden sind sicher eine gute, aber nicht die einzige Möglichkeit mich zu motivieren :-)
* Wer mir etwas Gutes tun will, kann die Anwendung auch im Play Store bewerten. * Wer mir etwas Gutes tun will, kann die Anwendung auch im Play Store bewerten (https://play.google.com/store/apps/details?id=com.jens.automation2).
* Außerdem ist Hilfe bei der Übersetzung willkommen. Englisch, Spanisch und Deutsch kann ich selbst. Aber sonst ist alles gern gesehen. * Außerdem ist Hilfe bei der Übersetzung willkommen. Englisch, Spanisch und Deutsch kann ich selbst. Aber sonst ist alles gern gesehen.
Erklärungen zu den vielen Berechtigungen können hier abgerufen werden: https://server47.de/automation/permissions_de.html Erklärungen zu den vielen Berechtigungen können hier abgerufen werden: https://server47.de/automation/permissions_de.html

View File

@ -19,18 +19,20 @@ Supported triggers:
* Headset connected * Headset connected
* Phone call running * Phone call running
* Notifications of other apps * Notifications of other apps
* Device orientation (gyroscope)
Supported actions: Supported actions:
* Change wifi state * Change wifi state
* Change bluetooth state * Change bluetooth state
* Toggle USB tethering * Toggle USB tethering
* Toggle wifi tethering * Toggle wifi tethering
* Toggle Bluetooth tethering
* Toggle automatic screen rotation * Toggle automatic screen rotation
* Make an HTTP request * Make an HTTP request
* Change ringtone/sound setting * Change ringtone/sound setting
* Start another application * Start another application
* Wait (in between other actions) * Wait (in between other actions)
* Wakeup device's screen * Turn screen on or off
* Toggle airplane mode * Toggle airplane mode
* Toggle mobile data connection * Toggle mobile data connection
* Speak text * Speak text
@ -42,10 +44,12 @@ Supported actions:
It's quite hard to keep this app working across the many different hardwares as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs. It's quite hard to keep this app working across the many different hardwares as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs.
So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reasonably reported to me. But for that I'm dependend on your input. So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reasonably reported to me. But for that I'm dependend on your input.
If you have a problem and think about contacting me please update to the latest version first and see if your problem persists there, too. If you have a problem and think about contacting me please
- update to the latest version first and see if your problem persists there, too.
- check this list of known problems first: https://server47.de/automation/index.php#knownProblems
Donations are certainly a good, but not the only way to motivate me :-) Donations are certainly a good, but not the only way to motivate me :-)
* If you'd like to support me, you can also leave a positive review for the app on Google Play. * If you'd like to support me, you can also leave a positive review for the app on Google Play (https://play.google.com/store/apps/details?id=com.jens.automation2).
* Furthermore I can always use help in translating the app. English, German and some Spanish are among my own skills. But everything else is more than welcome. * Furthermore I can always use help in translating the app. English, German and some Spanish are among my own skills. But everything else is more than welcome.
Explanation of the many permissions can be found here: https://server47.de/automation/permissions_en.html Explanation of the many permissions can be found here: https://server47.de/automation/permissions_en.html

View File

@ -19,18 +19,20 @@ Disparadores:
* Headset conectado * Headset conectado
* Llamado de teléfono activo * Llamado de teléfono activo
* Notificaciónes de otras apps * Notificaciónes de otras apps
* Orientación del dispositivo (giroscopio)
Supported actions: Aciónes:
* Pasar de wifi * Pasar de wifi
* Pasar de bluetooth * Pasar de bluetooth
* Pasar USB rúter * Pasar USB rúter
* Pasar wifi rúter * Pasar wifi rúter
* Pasar Bluetooth rúter
* Pasar rotación automatica del monitor * Pasar rotación automatica del monitor
* Hacer un solicitud HTTP * Hacer un solicitud HTTP
* Cambiar el tono de llamada / ajustes de sonido * Cambiar el tono de llamada / ajustes de sonido
* Encender otra app * Encender otra app
* Esperar (inter otras aciónes) * Esperar (inter otras aciónes)
* Desperatar móvil * Encender o apagar pantalla
* Pasar modo de vuelo * Pasar modo de vuelo
* Pasar datos móviles * Pasar datos móviles
* Leer texto * Leer texto
@ -42,10 +44,12 @@ Supported actions:
Es muy dificil mantener esta applicación functionando en todos los hardwares y versiónes de Android. Puedo probrar mucho en el emulator, pero no puedo enviar todos los errores. Es muy dificil mantener esta applicación functionando en todos los hardwares y versiónes de Android. Puedo probrar mucho en el emulator, pero no puedo enviar todos los errores.
Si una función no funcióna - digame. En muchos años resolvaba la mayoria de los errores que los halladores me informaron bien. Pero dependo en su ayuda. Si una función no funcióna - digame. En muchos años resolvaba la mayoria de los errores que los halladores me informaron bien. Pero dependo en su ayuda.
Si tiene un problema y considera contactarme update a la ultima version al primero y probar si su problam persiste. Si tiene un problema y considera contactarme
- update a la ultima version al primero y probar si su problam persiste.
- al primero compruebe esta lista de problemas conocidos: https://server47.de/automation/index.php#knownProblems
Donaciónes seguramente son una buena, pero no la unica posibilidad de apoyarme :-) Donaciónes seguramente son una buena, pero no la unica posibilidad de apoyarme :-)
* Si quiere apoyarme puedes escribir un buena revisión en Google Play * Si quiere apoyarme puedes escribir un buena revisión en Google Play (https://play.google.com/store/apps/details?id=com.jens.automation2).
* Además siempre necesito ayuda en traduciendo la app. Ingles, Aleman y Español estan en mis habilidades. Per todo lo demás es bienvenido. * Además siempre necesito ayuda en traduciendo la app. Ingles, Aleman y Español estan en mis habilidades. Per todo lo demás es bienvenido.
Puedes leer una explicación de los permisos aqui: https://server47.de/automation/permissions_en.html Puedes leer una explicación de los permisos aqui: https://server47.de/automation/permissions_en.html

View File

@ -0,0 +1,85 @@
Crea regole composte da eventi ed azioni. Un buon esempio sarebbe una regola come "Silenzia il telefono in ufficio".
Ecco la lista di eventi ed azioni supportate:
Eventi supportati:
* Posizione
* Data/Ora
* Stato di carica
* Livello batteria
* Connessione USB con il computer attiva
* Velocità attuale
* Rumore di fondo (solo fino ad Android 7)
* Connessione Wifi
* Altre applicazioni in esecuzione
* Modalità volo
* Stato del roaming
* Etichetta NFC
* Connessione Bluetooth
* Auriculari connessi
* Chiamata in esecuzione
* Notificazione di un altra applicazione
* Orientamento del dispositivo (giroscopio)
Azioni supportate:
* Cambia lo stato del wifi
* Cambia lo stato del bluetooth
* Controlla il tethering USB
* Controlla il tethering wifi
* Controlla il tethering Bluetooth
* Controlla la rotazione automatica dello schermo
* Effettua una richiesta HTTP
* Cambia suoneria/opzioni sonore
* Avvia un'altra applicazione
* Aspetta (fra azioni)
* Attiva o disattiva lo schermo
* Controlla modalità volo
* Controlla la connessione dati
* Pronuncia testo
* Apri il lettore musicale
* Cambia la luminosità dello schermo
* Manda un messaggio di testo
* Esegui un file musicale
È piuttosto difficile mantere questa applicazione funzionante su tutti gli hardware esistenti ed includendo tutti i cambi che Android riceve fra una versione e l'altra. Posso effettuare tests nell'emulatore, ma non sarà possibile trovare tutti gli errori.
Pertanto, se una certa funzione non funziona sul tuo dispositivo - fammelo sapere. Nel corso degli anni ho potuto risolvere tutti gli errori che sono stati riportati in maniera ragionevole. Infatti, per questo, dipendo dalle informazioni condivise.
Se hai un problema e stai pensando di contattarmi, per favore:
- assicurati di aggiornare l'applicazione all'ultima versione e controlla se il problema continua.
- controlla questa lista di problemi conosciuti: https://server47.de/automation/index.php#knownProblems
Donativi sono sicuramente una buona forma di motivarmi, ma non l'unica :-)
* Se vuoi darmi il tuo supporto, puoi anche lasciare una rassegna positiva su Google Play (https://play.google.com/store/apps/details?id=com.jens.automation2).
* Inoltre, ho sempre bisogno di aiuto per tradurre l'applicazione.
Inglese, Tedesco e un po' di Spagnolo son parte delle mie abilità. Ma per tutte le altre, apprezzo molto ogni aiuto.
Una spiegazione di tutti i permessi si trova qui:
https://server47.de/automation/permissions_en.html

View File

@ -0,0 +1 @@
Automatizza attività sul tuo dispositivo tramite la creazione di regole.

View File

@ -0,0 +1,58 @@
Automatiseer je telefoon en maak regels die zijn opgebouwd uit triggers en acties.
Een goed voorbeeld is "ALS ik mijn werk wifi verbind zet DAN mijn geluidsinstelling op stil".
Of : als ik tussen 8.00 en 09:00 de NFC tag op mijn werk scan, stuur dan een http verzoek naar mijn tijdschrijf applicatie.
Hieronder een lijst van ondersteunde triggers en acties:
Ondersteunde triggers:
* Locatie (positie)
* Dag/Tijd
* Oplaadstatus
* Batterijniveau
* USB-verbinding met computer tot stand gebracht
* Uw huidige snelheid (via GPS)
* Achtergrondgeluid (alleen tot Android 7)
* Wifi verbinding
* Andere toepassingen die worden uitgevoerd
* Vliegtuigmodus
* Roaming status
* NFC tags
* Bluetooth-verbinding
* Headset aangesloten
* Lopend telefoongesprek
* Meldingen van andere apps
* Apparaat oriëntatie (gyroscoop)
Ondersteunde acties:
* Wijzig wifi status
* Wijzig Bluetooth-status
* Schakel USB-tethering in
* Schakel Wifi-tethering in
* Schakel Bluetooth-tethering in
* Schakel automatische schermrotatie in
* Doe een HTTP verzoek.
* Wijzig Ringtone/geluidsinstelling
* Start een andere toepassing
* Wachten (tussen andere acties)
* Scherm aan- of uitzetten
* Schakel Vliegtuigmodus in
* Schakel Mobiele dataverbinding in
* Spreek tekst
* Open muziekspeler
* Verander de helderheid van het scherm
* Verstuur tekstbericht
* Geluidsbestand afspelen
Het is lastig om deze App werkend te houden over de vele verschillende hardware en de vele veranderingen die Android ondergaat in de loop der versies.
Ik test het in een emulator, maar dat kan niet alle bugs laten zien.
Dus als een bepaalde functie niet werkt op uw apparaat - laat het me dan weten. In de loop der jaren heb ik bijna alle bugs opgelost die redelijkerwijs aan mij gemeld zijn. Maar daarvoor ben ik afhankelijk van jullie input.
Als je een probleem hebt en erover denkt om contact met me op te nemen
- update eerst naar de laatste versie en kijk of uw probleem zich daar ook voordoet.
- Controleer deze lijst met bekende problemen: https://server47.de/automation/index.php#knownProblems
Donaties zijn zeker een goede, maar niet de enige manier om mij te motiveren :-)
* Als je me wilt steunen, kun je ook een positieve review voor de app achterlaten op Google Play ( https://play.google.com/store/apps/details?id=com.jens.automation2 ).
* Verder kan ik altijd hulp gebruiken bij het vertalen van de app. Engels, Duits en wat Spaans behoren tot mijn eigen vaardigheden. Maar al het andere is meer dan welkom.
Uitleg van de vele permissies vind je hier (Engels) : https://server47.de/automation/permissions_en.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -0,0 +1 @@
AUTOMATION : Automatiseer je taken met triggers en acties: ALS dit DAN dat..