Compare commits

...

52 Commits

Author SHA1 Message Date
6179f0e9ae translated new strings 2022-06-10 17:27:17 +02:00
581cdafb87 improved Italian translation 2022-06-10 17:00:59 +02:00
2361c758c9 store descriptions 2022-06-06 20:06:11 +02:00
f738e02b72 store descriptions 2022-06-06 02:47:51 +02:00
f5a3636222 intent pairs for sendBroadcast 2022-06-04 14:32:20 +02:00
bb1b3b0149 tethering detection 2022-06-04 02:44:26 +02:00
b35208b7aa tethering detection 2022-06-03 19:26:34 +02:00
b3ad72cc50 wifi receiver efficiency 2022-06-02 17:55:02 +02:00
c1809bd23c run executable action 2022-06-02 17:41:41 +02:00
88a3ab8241 Merge remote-tracking branch 'origin/development' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/ActivityManageRule.java
2022-06-01 22:39:46 +02:00
00f296d2d1 wifi action 2022-06-01 22:36:30 +02:00
e84842361c Merge remote-tracking branch 'origin/development-stable' into development 2022-05-29 22:30:16 +02:00
efaf0ed270 wifi toggle dialog reduced 2022-05-29 22:29:58 +02:00
7167f0c03d run executable 2022-05-29 20:14:50 +02:00
a9673e65b9 crash when editing notification trigger 2022-05-29 15:13:30 +02:00
592abe5b0d not contains comparator 2022-05-29 14:17:11 +02:00
dd7c3cb1d6 not contains comparator 2022-05-29 14:15:47 +02:00
38665ccd92 Merge remote-tracking branch 'origin/development-stable' into development 2022-05-29 14:04:44 +02:00
c60347b990 syntax errors in translations fixed 2022-05-29 14:04:32 +02:00
1e7ccf5200 not equals direction 2022-05-29 13:57:47 +02:00
9b84b8dad7 translations 2022-05-29 13:38:57 +02:00
a19c84ea51 send broadcasts action 2022-05-29 02:42:12 +02:00
3a14a56fd0 translations 2022-05-28 19:54:29 +02:00
2dfc538343 screenstate no sec lock screen fixed 2022-05-27 20:21:13 +02:00
67a58077cc time class changed 2022-05-26 18:47:30 +02:00
df68f7ca5c delayed lock screen 2022-05-26 18:26:49 +02:00
ad18313284 delayed lock screen 2022-05-26 15:50:39 +02:00
29a93e0e43 language updates and screen locked trigger 2022-05-24 17:40:11 +02:00
a5d54c18d8 language updates and screen locked trigger 2022-05-24 17:31:25 +02:00
62f5ad0005 operator change 2022-05-23 22:59:00 +02:00
4eb7133d9d operator change 2022-05-23 22:45:54 +02:00
343cbba8f8 broadcast trigger 2022-05-23 20:28:56 +02:00
51caae0794 operator change 2022-05-22 23:07:05 +02:00
e39a2411ba broadcast trigger 2022-05-22 17:31:55 +02:00
98b49036a7 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
2022-05-21 14:08:19 +02:00
a7c4cc0965 app picker removed from play store version 2022-05-21 14:06:09 +02:00
5d67452486 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
2022-05-21 13:37:50 +02:00
7e12a0f3e5 full day time window 2022-05-21 13:34:44 +02:00
5786c1bfd4 full day time window 2022-05-21 02:33:56 +02:00
cf500c740e new release prep 2022-05-15 01:54:56 +02:00
41efa7c11b Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values-nl/strings.xml
#	app/src/main/res/values/strings.xml
#	build.gradle
#	fastlane/metadata/android/en-US/changelogs/119.txt
2022-05-15 01:54:32 +02:00
965bf55811 Merge remote-tracking branch 'origin/development-stable' into development 2022-03-05 20:59:33 +01:00
13fd4c2aae magnetometer 2022-03-05 02:00:16 +01:00
195a60cfe0 magnetometer 2022-03-03 17:32:06 +01:00
76563eb89b Merge remote-tracking branch 'origin/development-stable' into development 2022-02-28 13:46:42 +01:00
7733d57435 gradle 2022-02-26 13:02:07 +01:00
481e4d1896 screen state string 2022-02-23 18:09:21 +01:00
5af59e1754 Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Trigger.java
2022-02-22 22:21:39 +01:00
619f348a28 Merge remote-tracking branch 'origin/development-stable' into development 2022-02-20 18:57:38 +01:00
9bf353ea3a logging 2022-02-12 20:04:19 +01:00
af90b566c8 new triggers: service or device starts 2022-02-07 20:09:45 +01:00
0e51c577d5 new triggers: service or device starts 2022-02-06 20:12:11 +01:00
82 changed files with 3571 additions and 785 deletions

View File

@ -11,8 +11,8 @@ android {
compileSdkVersion 31
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 119
versionName "1.7.5"
versionCode 120
versionName "1.7.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -28,7 +28,6 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions "version"
productFlavors
@ -57,6 +56,7 @@ android {
abortOnError false
checkReleaseBuilds false
}
namespace 'com.jens.automation2'
}
dependencies {

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -159,12 +158,17 @@
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityControlCenter" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerBroadcast" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageActionCreateNotification" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity android:name=".ActivityManageActionControlMedia" />
<activity android:name=".ActivityManageActionSendBroadcast" />
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -12,6 +12,7 @@ import android.widget.Toast;
import com.google.android.gms.location.DetectedActivity;
import com.jens.automation2.receivers.ActivityDetectionReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
@ -348,6 +349,10 @@ public class Rule implements Comparable<Rule>
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -386,7 +391,8 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -157,12 +156,17 @@
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityControlCenter" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerBroadcast" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageActionCreateNotification" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity android:name=".ActivityManageActionControlMedia" />
<activity android:name=".ActivityManageActionSendBroadcast" />
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -10,6 +10,7 @@ import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@ -345,6 +346,10 @@ public class Rule implements Comparable<Rule>
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -383,7 +388,8 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens
android:anyDensity="true"
@ -65,7 +64,6 @@
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<application
android:allowBackup="true"
@ -145,12 +143,17 @@
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityControlCenter" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerBroadcast" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityManageActionCreateNotification" />
<activity android:name=".ActivityManageTriggerDeviceOrientation" />
<activity android:name=".ActivityHelp" />
<activity android:name=".ActivityManageActionVibrate" />
<activity android:name=".ActivityManageActionControlMedia" />
<activity android:name=".ActivityManageActionSendBroadcast" />
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -12,6 +12,7 @@ import android.widget.Toast;
import com.google.android.gms.location.DetectedActivity;
import com.jens.automation2.receivers.ActivityDetectionReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import java.util.ArrayList;
import java.util.Calendar;
@ -348,6 +349,10 @@ public class Rule implements Comparable<Rule>
if(oneTrigger.getTimeFrame().repetition > 0)
return true;
}
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
return oneTrigger.getTriggerParameter() == BroadcastListener.getInstance().hasBroadcastOccurredSince(oneTrigger.getTriggerParameter2(), getLastExecution());
}
}
return false;
@ -386,7 +391,8 @@ public class Rule implements Comparable<Rule>
if (!oneTrigger.applies(null, context))
return false;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format("Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately.", this.getName()), 3);
return true;
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jens.automation2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

View File

@ -6,6 +6,8 @@ import android.os.Build;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
@ -21,108 +23,115 @@ public class Action
public static final String intentPairSeparator = "intPairSplit";
public static final String vibrateSeparator = ",";
public enum Action_Enum {
setWifi,
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl,
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
playMusic,
controlMediaPlayback,
setScreenBrightness,
playSound,
vibrate,
createNotification,
closeNotification,
sendTextMessage;
public String getFullName(Context context)
{
switch(this)
{
case setWifi:
return context.getResources().getString(R.string.actionSetWifi);
case setBluetooth:
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation);
case turnWifiOn:
return context.getResources().getString(R.string.actionTurnWifiOn);
case turnWifiOff:
return context.getResources().getString(R.string.actionTurnWifiOff);
case turnBluetoothOn:
return context.getResources().getString(R.string.actionTurnBluetoothOn);
case turnBluetoothOff:
return context.getResources().getString(R.string.actionTurnBluetoothOff);
case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile:
return context.getResources().getString(R.string.actionChangeSoundProfile);
case turnUsbTetheringOn:
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
case turnWifiTetheringOn:
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
case turnWifiTetheringOff:
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
case enableScreenRotation:
return context.getResources().getString(R.string.actionEnableScreenRotation);
case disableScreenRotation:
return context.getResources().getString(R.string.actionDisableScreenRotation);
case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
return context.getResources().getString(R.string.airplaneMode);
case setDataConnection:
return context.getResources().getString(R.string.actionDataConnection);
case speakText:
return context.getResources().getString(R.string.actionSpeakText);
case playMusic:
return context.getResources().getString(R.string.actionPlayMusic);
case controlMediaPlayback:
return context.getResources().getString(R.string.actionMediaControl);
case playSound:
return context.getResources().getString(R.string.playSound);
case sendTextMessage:
return context.getResources().getString(R.string.sendTextMessage);
case setScreenBrightness:
return context.getResources().getString(R.string.setScreenBrightness);
case createNotification:
return context.getResources().getString(R.string.createNotification);
case closeNotification:
return context.getResources().getString(R.string.closeNotifications);
default:
return "Unknown";
}
}
};
public enum Action_Enum
{
setWifi,
setBluetooth,
setUsbTethering,
setWifiTethering,
setBluetoothTethering,
setDisplayRotation,
turnWifiOn,turnWifiOff,
turnBluetoothOn,turnBluetoothOff,
triggerUrl,
changeSoundProfile,
turnUsbTetheringOn,turnUsbTetheringOff,
turnWifiTetheringOn,turnWifiTetheringOff,
enableScreenRotation,disableScreenRotation,
startOtherActivity,
waitBeforeNextAction,
turnScreenOnOrOff,
setAirplaneMode,
setDataConnection,
speakText,
playMusic,
controlMediaPlayback,
setScreenBrightness,
playSound,
vibrate,
createNotification,
closeNotification,
sendBroadcast,
runExecutable,
sendTextMessage;
public String getFullName(Context context)
{
switch(this)
{
case setWifi:
return context.getResources().getString(R.string.actionSetWifi);
case setBluetooth:
return context.getResources().getString(R.string.actionSetBluetooth);
case setWifiTethering:
return context.getResources().getString(R.string.actionSetWifiTethering);
case setBluetoothTethering:
return context.getResources().getString(R.string.actionSetBluetoothTethering);
case setUsbTethering:
return context.getResources().getString(R.string.actionSetUsbTethering);
case setDisplayRotation:
return context.getResources().getString(R.string.actionSetDisplayRotation);
case turnWifiOn:
return context.getResources().getString(R.string.actionTurnWifiOn);
case turnWifiOff:
return context.getResources().getString(R.string.actionTurnWifiOff);
case turnBluetoothOn:
return context.getResources().getString(R.string.actionTurnBluetoothOn);
case turnBluetoothOff:
return context.getResources().getString(R.string.actionTurnBluetoothOff);
case triggerUrl:
return context.getResources().getString(R.string.actionTriggerUrl);
case changeSoundProfile:
return context.getResources().getString(R.string.actionChangeSoundProfile);
case turnUsbTetheringOn:
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
case turnUsbTetheringOff:
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
case turnWifiTetheringOn:
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
case turnWifiTetheringOff:
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
case enableScreenRotation:
return context.getResources().getString(R.string.actionEnableScreenRotation);
case disableScreenRotation:
return context.getResources().getString(R.string.actionDisableScreenRotation);
case startOtherActivity:
return context.getResources().getString(R.string.startOtherActivity);
case waitBeforeNextAction:
return context.getResources().getString(R.string.waitBeforeNextAction);
case turnScreenOnOrOff:
return context.getResources().getString(R.string.turnScreenOnOrOff);
case vibrate:
return context.getResources().getString(R.string.vibrate);
case setAirplaneMode:
return context.getResources().getString(R.string.airplaneMode);
case setDataConnection:
return context.getResources().getString(R.string.actionDataConnection);
case speakText:
return context.getResources().getString(R.string.actionSpeakText);
case playMusic:
return context.getResources().getString(R.string.actionPlayMusic);
case controlMediaPlayback:
return context.getResources().getString(R.string.actionMediaControl);
case playSound:
return context.getResources().getString(R.string.playSound);
case sendTextMessage:
return context.getResources().getString(R.string.sendTextMessage);
case setScreenBrightness:
return context.getResources().getString(R.string.setScreenBrightness);
case createNotification:
return context.getResources().getString(R.string.createNotification);
case closeNotification:
return context.getResources().getString(R.string.closeNotifications);
case sendBroadcast:
return context.getResources().getString(R.string.sendBroadcast);
case runExecutable:
return context.getResources().getString(R.string.runExecutable);
default:
return "Unknown";
}
}
};
private Action_Enum action;
private boolean parameter1 = false;
@ -258,6 +267,12 @@ public class Action
case closeNotification:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.closeNotifications));
break;
case sendBroadcast:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendBroadcast));
break;
case runExecutable:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.runExecutable));
break;
default:
returnString.append(action.toString());
}
@ -315,7 +330,15 @@ public class Action
if (parts.length > 4 && !StringUtils.isBlank(parts[4]))
returnString.append(", " + Miscellaneous.getAnyContext().getResources().getString(R.string.ifString) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.text) + " " + Trigger.getMatchString(parts[3]) + " " + parts[4]);
}
else if(this.getAction().equals(Action_Enum.setWifi))
{
if(!StringUtils.isEmpty(this.parameter2))
{
boolean useRoot = Boolean.parseBoolean(this.parameter2);
if(useRoot)
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.usingRoot));
}
}
else if(this.getAction().equals(Action_Enum.controlMediaPlayback))
{
@ -430,7 +453,7 @@ public class Action
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
}
public void run(Context context, boolean toggleActionIfPossible)
{
try
@ -533,6 +556,16 @@ public class Action
else
Miscellaneous.logEvent("w", "Close notification", "Close notification was requested, but OS version is too low: " + String.valueOf(Build.VERSION.SDK_INT), 2);
break;
case sendBroadcast:
Actions.sendBroadcast(context, this.getParameter2());
break;
case runExecutable:
String[] execParts = this.getParameter2().split(Action.actionParameter2Split);
if(execParts.length == 1)
Actions.runExecutable(context, this.getParameter1(), execParts[0], null);
else if(execParts.length == 2)
Actions.runExecutable(context, this.getParameter1(), execParts[0], execParts[1]);
break;
default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break;
@ -636,7 +669,7 @@ public class Action
//Do something with result
//Toast.makeText(context, text, duration) result;
Miscellaneous.logEvent("i", "HTTP RESULT", result, 3);
Actions myAction=new Actions();
Actions myAction = new Actions();
myAction.useDownloadedWebpage(result);
}
}

View File

@ -52,7 +52,12 @@ import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@ -62,8 +67,11 @@ import java.net.NetworkInterface;
import java.security.KeyStore;
import java.util.Calendar;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
@ -185,7 +193,24 @@ public class Actions
}
}
public static class WifiStuff
public static void sendBroadcast(Context context, String action)
{
Miscellaneous.logEvent("i", "sendBroadcast", "Sending broadcast with action " + action, 5);
Intent broadcastIntent = new Intent();
if(action.contains(Action.actionParameter2Split))
{
String[] parts = action.split(Action.actionParameter2Split);
broadcastIntent.setAction(parts[0]);
add params
}
else
broadcastIntent.setAction(action);
context.sendBroadcast(broadcastIntent);
}
public static class WifiStuff
{
public static Boolean setWifi(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
@ -1899,4 +1924,187 @@ public class Actions
return android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
public static boolean runExecutable(Context context, boolean runAsRoot, String path, String parameters)
{
if(runAsRoot)
{
if(!StringUtils.isEmpty(parameters))
return executeCommandViaSu(new String[] { path + " " + parameters });
else
return executeCommandViaSu(new String[] { path });
}
else
{
Object[] result;
File executable = new File(path);
File workingDir = new File(executable.getParent());
if(!StringUtils.isEmpty(parameters))
result = runExternalApplication(path, 0, workingDir, parameters);
else
result = runExternalApplication(path, 0, workingDir, null);
boolean execResult = (boolean) result[0];
return execResult;
}
}
/**
*
* @param commandToExecute
* @param timeout
* @param params
* @return Returns an array: 0=exit code, 1=cmdline output
*/
public static Object[] runExternalApplication(String commandToExecute, long timeout, File workingDirectory, String params)
{
/*
* Classes stolen from https://github.com/stleary/JSON-java
*/
String fullCommand;
if(!StringUtils.isEmpty(params))
fullCommand = commandToExecute + " " + params;
else
fullCommand = commandToExecute;
Miscellaneous.logEvent("i", "Running executable", "Running external application " + fullCommand, 4);
Object[] returnObject = new Object[2];
StringBuilder output = new StringBuilder();
String line = null;
OutputStream stdin = null;
InputStream stderr = null;
InputStream stdout = null;
try
{
Process process = null;
if(workingDirectory != null)
process = Runtime.getRuntime().exec(fullCommand, null, workingDirectory);
else
process = Runtime.getRuntime().exec(fullCommand);
stdin = process.getOutputStream ();
stderr = process.getErrorStream ();
stdout = process.getInputStream ();
// "write" the parms into stdin
/*line = "param1" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param2" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param3" + "\n";
stdin.write(line.getBytes() );
stdin.flush();*/
stdin.close();
// clean up if any output in stdout
BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stdout] " + line, 4);
output.append(line);
}
brCleanUp.close();
// clean up if any output in stderr
brCleanUp = new BufferedReader (new InputStreamReader(stderr));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stderr] " + line, 4);
output.append(line);
}
brCleanUp.close();
try
{
// Wait for the process to exit, we want the return code
if(timeout > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
try
{
if(!process.waitFor(timeout, TimeUnit.MILLISECONDS))
{
Miscellaneous.logEvent("i", "Running executable", "Timeout of " + String.valueOf(timeout) + " ms reached. Killing check attempt.", 3);
process.destroyForcibly();
}
}
catch(NoSuchMethodError e)
{
process.waitFor();
}
}
else
process.waitFor();
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("i", "Running executable", "Waiting for process failed: " + Log.getStackTraceString(e), 4);
Miscellaneous.logEvent("i", "Running executable", Log.getStackTraceString(e), 1);
}
if(process.exitValue() == 0)
Miscellaneous.logEvent("i", "Running executable", "ReturnCode: " + String.valueOf(process.exitValue()), 4);
else
Miscellaneous.logEvent("i", "Running executable", "External execution (RC=" + String.valueOf(process.exitValue()) + ") returned error: " + output.toString(), 3);
returnObject[0] = process.exitValue();
returnObject[1] = output.toString();
return returnObject;
}
catch (IOException e)
{
Miscellaneous.logEvent("e", "Running executable", Log.getStackTraceString(e), 1);
}
Miscellaneous.logEvent("i", "Running executable", "Error running external application.", 1);
// if(slotMap != null)
// for(String key : slotMap.keySet())
// System.clearProperty(key);
return null;
}
public static boolean isTetheringActive1(Context context)
{
try
{
for(Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
{
NetworkInterface intf = en.nextElement();
for(Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
{
InetAddress inetAddress = enumIpAddr.nextElement();
if(!intf.isLoopback())
{
if(intf.getName().contains("rndis"))
{
return true;
}
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "isTetheringActive()", Log.getStackTraceString(e), 3);
}
return false;
}
}

View File

@ -353,11 +353,15 @@ public class ActivityControlCenter extends Activity
systemInfoText.append("Device details" + Miscellaneous.lineSeparator);
systemInfoText.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
systemInfoText.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
systemInfoText.append("Target SDK: " + Miscellaneous.getAnyContext().getApplicationInfo().targetSdkVersion + Miscellaneous.lineSeparator);
systemInfoText.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
systemInfoText.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
systemInfoText.append("Product: " + android.os.Build.PRODUCT + Miscellaneous.lineSeparator);
systemInfoText.append("Rooted: " + String.valueOf(Miscellaneous.isPhoneRooted()) + Miscellaneous.lineSeparator);
systemInfoText.append("Country: " + Miscellaneous.getUserCountry(Miscellaneous.getAnyContext()) + Miscellaneous.lineSeparator);
systemInfoText.append("OS language: " + Locale.getDefault().getDisplayName());
systemInfoText.append("OS language: " + Locale.getDefault().getDisplayName() + Miscellaneous.lineSeparator);
systemInfoText.append("Logfile written: " + String.valueOf(Settings.writeLogFile) + Miscellaneous.lineSeparator);
systemInfoText.append("Log level: " + String.valueOf(Settings.logLevel));
/*
I've checked the Locale methods on my Android 4.1.2 device, and the results:

View File

@ -77,10 +77,9 @@ public class ActivityMainScreen extends ActivityGeneric
tvLockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
bDonate = (Button)findViewById(R.id.bDonate);
if(!BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
bDonate.setVisibility(View.VISIBLE);
toggleService.setChecked(AutomationService.isMyServiceRunning(this));

View File

@ -1,7 +1,5 @@
package com.jens.automation2;
import static com.jens.automation2.Trigger.triggerParameter2Split;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@ -18,8 +16,6 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
@ -49,7 +45,6 @@ public class ActivityManageActionCloseNotification extends Activity
TextView tvSelectedApplication;
private static List<PackageInfo> pInfos = null;
public static Trigger resultingTrigger;
private static String[] directions;
@ -271,6 +266,7 @@ public class ActivityManageActionCloseNotification extends Activity
directions = new String[] {
getResources().getString(R.string.directionStringEquals),
getResources().getString(R.string.directionStringContains),
getResources().getString(R.string.directionStringDoesNotContain),
getResources().getString(R.string.directionStringStartsWith),
getResources().getString(R.string.directionStringEndsWith),
getResources().getString(R.string.directionStringNotEquals)

View File

@ -0,0 +1,114 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
public class ActivityManageActionRunExecutable extends Activity
{
final static int PICKFILE_RESULT_CODE = 4711;
CheckBox chkRunExecAsRoot;
EditText etRunExecutablePath, etRunExecutableParameters;
Button bChooseExecutable, bSaveActionRunExec;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_run_executable);
chkRunExecAsRoot = (CheckBox)findViewById(R.id.chkRunExecAsRoot);
etRunExecutablePath = (EditText) findViewById(R.id.etRunExecutablePath);
etRunExecutableParameters = (EditText) findViewById(R.id.etRunExecutableParameters);
bChooseExecutable = (Button) findViewById(R.id.bChooseExecutable);
bSaveActionRunExec = (Button) findViewById(R.id.bSaveActionRunExec);
bChooseExecutable.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
//Need to check for storage permissions
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
chooseFile = Intent.createChooser(chooseFile, getResources().getString(R.string.selectSoundFile));
startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);
}
});
bSaveActionRunExec.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
saveExecSettings();
}
});
}
void saveExecSettings()
{
if(etRunExecutablePath.getText().toString() == null || etRunExecutablePath.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.selectValidExecutable), Toast.LENGTH_LONG).show();
return;
}
else
{
File executableFile = new File(etRunExecutablePath.getText().toString());
if(!executableFile.exists())
{
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.fileDoesNotExist), Toast.LENGTH_LONG).show();
return;
}
else
{
if(!chkRunExecAsRoot.isChecked() && !executableFile.canExecute())
{
Toast.makeText(ActivityManageActionRunExecutable.this, getResources().getString(R.string.fileNotExecutable), Toast.LENGTH_LONG).show();
return;
}
}
}
Intent returnData = new Intent();
returnData.putExtra(ActivityManageRule.intentNameActionParameter1, chkRunExecAsRoot.isChecked());
if(etRunExecutableParameters.getText() != null && !StringUtils.isEmpty(etRunExecutableParameters.getText().toString()))
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, etRunExecutablePath.getText().toString() + Action.actionParameter2Split + etRunExecutableParameters.getText().toString());
else
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, etRunExecutablePath.getText().toString());
setResult(RESULT_OK, returnData);
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
{
if(requestCode == PICKFILE_RESULT_CODE)
{
Uri fileUri = data.getData();
String filePath = CompensateCrappyAndroidPaths.getPath(ActivityManageActionRunExecutable.this, fileUri);
etRunExecutablePath.setText(filePath);
}
}
}
}

View File

@ -0,0 +1,256 @@
package com.jens.automation2;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class ActivityManageActionSendBroadcast extends Activity
{
EditText etBroadcastToSend;
Button bBroadcastSendShowSuggestions, bSaveSendBroadcast, bAddIntentPair;
ListView lvIntentPairs;
EditText etParameterName, etParameterValue;
Spinner spinnerParameterType;
ArrayAdapter<String> intentTypeSpinnerAdapter, intentPairAdapter;
private static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String", "Uri" };
private ArrayList<String> intentPairList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_send_broadcast);
etBroadcastToSend = (EditText)findViewById(R.id.etBroadcastToSend);
bBroadcastSendShowSuggestions = (Button)findViewById(R.id.bBroadcastSendShowSuggestions);
bSaveSendBroadcast = (Button)findViewById(R.id.bSaveSendBroadcast);
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
lvIntentPairs = (ListView) findViewById(R.id.lvIntentPairs);
etParameterName = (EditText) findViewById(R.id.etParameterName);
etParameterValue = (EditText) findViewById(R.id.etParameterValue);
spinnerParameterType = (Spinner) findViewById(R.id.spinnerParameterType);
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionSendBroadcast.supportedIntentTypes);
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
intentTypeSpinnerAdapter.notifyDataSetChanged();
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
bSaveSendBroadcast.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if(checkInput())
{
Intent answer = new Intent();
String param2 = etBroadcastToSend.getText().toString();
if(intentPairList.size() > 0)
{
param2 += Action.actionParameter2Split;
for (String s : intentPairList)
param2 += s + ";";
param2 = param2.substring(0, param2.length() - 1);
}
answer.putExtra(ActivityManageRule.intentNameActionParameter2, param2);
setResult(RESULT_OK, answer);
finish();
}
}
});
bBroadcastSendShowSuggestions.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageActionSendBroadcast.this);
builder.setTitle(getResources().getString(R.string.selectBroadcast));
builder.setItems(ActivityManageTriggerBroadcast.broadcastSuggestions, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int which)
{
etBroadcastToSend.setText(ActivityManageTriggerBroadcast.broadcastSuggestions[which]);
}
});
builder.create().show();
}
});
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
{
String param2 = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
if(!param2.contains(Action.actionParameter2Split))
etBroadcastToSend.setText(input.getStringExtra(ActivityManageRule.intentNameActionParameter2));
else
{
String[] param2Parts = param2.split(Action.actionParameter2Split);
etBroadcastToSend.setText(param2Parts[0]);
String[] params = param2Parts[1].split(";");
intentPairList.clear();
for(int i = 0; i < params.length; i++)
{
if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE);
intentPairList.add(params[i]);
}
updateIntentPairList();
}
}
bAddIntentPair.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// type;name;value
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
return;
}
if(etParameterName.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
if(etParameterValue.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
intentPairList.add(param);
spinnerParameterType.setSelection(0);
etParameterName.setText("");
etParameterValue.setText("");
updateIntentPairList();
if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE);
}
});
lvIntentPairs.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
getIntentPairDialog(arg2).show();
return false;
}
});
spinnerParameterType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
else
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
}
boolean checkInput()
{
String broadcastToSend = etBroadcastToSend.getText().toString();
if(StringUtils.isEmpty(broadcastToSend))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enterBroadcast), Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
private void updateIntentPairList()
{
if(lvIntentPairs.getAdapter() == null)
lvIntentPairs.setAdapter(intentPairAdapter);
intentPairAdapter.notifyDataSetChanged();
}
private AlertDialog getIntentPairDialog(final int itemPosition)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageActionSendBroadcast.this);
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
// Only 1 choice at the moment, no need to check
ActivityManageActionSendBroadcast.this.intentPairList.remove(itemPosition);
updateIntentPairList();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
return alertDialog;
}
}

View File

@ -15,8 +15,6 @@ public class ActivityManageActionSpeakText extends Activity
private Button bSaveSpeakText;
private EditText etSpeakText;
// private String existingUrl = "";
public static boolean edit = false;
public static Action resultingAction = null;
@ -27,7 +25,7 @@ public class ActivityManageActionSpeakText extends Activity
this.setContentView(R.layout.activity_manage_action_speak_text);
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl);
bSaveSpeakText = (Button)findViewById(R.id.bSaveSpeakText);
bSaveSpeakText.setOnClickListener(new OnClickListener()
{
@Override

View File

@ -60,6 +60,202 @@ public class ActivityManageActionStartActivity extends Activity
final static String startByBroadcastString = "1";
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_start_activity);
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
etParameterName = (EditText)findViewById(R.id.etParameterName);
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
bSelectApp = (Button)findViewById(R.id.bSelectApp);
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
etPackageName = (EditText) findViewById(R.id.etPackageName);
etActivityOrActionPath = (EditText) findViewById(R.id.etActivityOrActionPath);
rbStartAppSelectByActivity = (RadioButton)findViewById(R.id.rbStartAppSelectByActivity);
rbStartAppSelectByAction = (RadioButton)findViewById(R.id.rbStartAppSelectByAction);
showStartProgramExamples = (Button)findViewById(R.id.showStartProgramExamples);
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
intentTypeSpinnerAdapter.notifyDataSetChanged();
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
bSelectApp.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
int targetSdkVersion = getApplicationContext().getApplicationInfo().targetSdkVersion;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && targetSdkVersion >= 30 && !ActivityPermissions.havePermission(Manifest.permission.QUERY_ALL_PACKAGES, ActivityManageActionStartActivity.this))// && shouldShowRequestPermissionRationale(Manifest.permission.QUERY_ALL_PACKAGES))
{
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
{
// This ain't possible anymore.
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.featureNotInGooglePlayVersion) + Miscellaneous.lineSeparator + Miscellaneous.lineSeparator + getResources().getString(R.string.startActivityInsertManually), ActivityManageActionStartActivity.this).show();
}
else
requestPermissions(new String[] {Manifest.permission.QUERY_ALL_PACKAGES}, requestCodeForRequestQueryAllPackagesPermission);
}
else
getAppList();
}
});
bAddIntentPair.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// type;name;value
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
return;
}
if(etParameterName.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
if(etParameterValue.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
intentPairList.add(param);
spinnerParameterType.setSelection(0);
etParameterName.setText("");
etParameterValue.setText("");
updateIntentPairList();
if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE);
}
});
showStartProgramExamples.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlShowExamples));
startActivity(browserIntent);
}
});
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
getIntentPairDialog(arg2).show();
return false;
}
});
bSaveActionStartOtherActivity.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if(saveAction())
{
ActivityManageActionStartActivity.this.setResult(RESULT_OK);
finish();
}
}
});
lvIntentPairs.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
spinnerParameterType.setOnItemSelectedListener(new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
else
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
rbStartAppSelectByActivity.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
bSelectApp.setEnabled(isChecked);
}
});
rbStartAppSelectByAction.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
bSelectApp.setEnabled(!isChecked);
}
});
Intent i = getIntent();
if(i.getBooleanExtra("edit", false) == true)
{
edit = true;
loadValuesIntoGui();
}
}
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
{
@ -82,7 +278,6 @@ public class ActivityManageActionStartActivity extends Activity
return name1.compareTo(name2);
}
}
private static List<PackageInfo> pInfos = null;
@ -343,197 +538,6 @@ public class ActivityManageActionStartActivity extends Activity
getActivityListTask.execute();
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_start_activity);
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
etParameterName = (EditText)findViewById(R.id.etParameterName);
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
bSelectApp = (Button)findViewById(R.id.bSelectApp);
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
etPackageName = (EditText) findViewById(R.id.etPackageName);
etActivityOrActionPath = (EditText) findViewById(R.id.etActivityOrActionPath);
rbStartAppSelectByActivity = (RadioButton)findViewById(R.id.rbStartAppSelectByActivity);
rbStartAppSelectByAction = (RadioButton)findViewById(R.id.rbStartAppSelectByAction);
showStartProgramExamples = (Button)findViewById(R.id.showStartProgramExamples);
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
intentTypeSpinnerAdapter.notifyDataSetChanged();
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
bSelectApp.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
int targetSdkVersion = getApplicationContext().getApplicationInfo().targetSdkVersion;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && targetSdkVersion >= 30 && !ActivityPermissions.havePermission(Manifest.permission.QUERY_ALL_PACKAGES, ActivityManageActionStartActivity.this))// && shouldShowRequestPermissionRationale(Manifest.permission.QUERY_ALL_PACKAGES))
{
requestPermissions(new String[] {Manifest.permission.QUERY_ALL_PACKAGES}, requestCodeForRequestQueryAllPackagesPermission);
}
else
getAppList();
}
});
bAddIntentPair.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// type;name;value
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
return;
}
if(etParameterName.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterName.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
if(etParameterValue.getText().toString().length() == 0)
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(Action.intentPairSeparator))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeparator), Toast.LENGTH_LONG).show();
return;
}
else if(etParameterValue.getText().toString().contains(";"))
{
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
return;
}
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
intentPairList.add(param);
spinnerParameterType.setSelection(0);
etParameterName.setText("");
etParameterValue.setText("");
updateIntentPairList();
if(lvIntentPairs.getVisibility() != View.VISIBLE)
lvIntentPairs.setVisibility(View.VISIBLE);
}
});
showStartProgramExamples.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlShowExamples));
startActivity(browserIntent);
}
});
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
getIntentPairDialog(arg2).show();
return false;
}
});
bSaveActionStartOtherActivity.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if(saveAction())
{
ActivityManageActionStartActivity.this.setResult(RESULT_OK);
finish();
}
}
});
lvIntentPairs.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
spinnerParameterType.setOnItemSelectedListener(new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
else
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
rbStartAppSelectByActivity.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
bSelectApp.setEnabled(isChecked);
}
});
rbStartAppSelectByAction.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
bSelectApp.setEnabled(!isChecked);
}
});
Intent i = getIntent();
if(i.getBooleanExtra("edit", false) == true)
{
edit = true;
loadValuesIntoGui();
}
}
private void loadValuesIntoGui()
{

View File

@ -47,7 +47,7 @@ public class ActivityManageActionTriggerUrl extends Activity
chkTriggerUrlUseAuthentication = (CheckBox)findViewById(R.id.chkTriggerUrlUseAuthentication);
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveTriggerUrl);
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveSpeakText);
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
{
@Override

View File

@ -0,0 +1,63 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class ActivityManageActionWifi extends Activity
{
CheckBox chkWifiRunAsRoot;
RadioButton rbActionWifiOn, rbActionWifiOff;
Button bActionWifiSave;
TextView tvWifiExplanation1, tvWifiExplanation2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_wifi);
chkWifiRunAsRoot = (CheckBox)findViewById(R.id.chkWifiRunAsRoot);
rbActionWifiOn = (RadioButton) findViewById(R.id.rbActionWifiOn);
rbActionWifiOff = (RadioButton)findViewById(R.id.rbActionWifiOff);
bActionWifiSave = (Button) findViewById(R.id.bActionWifiSave);
tvWifiExplanation1 = (TextView)findViewById(R.id.tvWifiExplanation1);
tvWifiExplanation2 = (TextView)findViewById(R.id.tvWifiExplanation2);
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameActionParameter1))
rbActionWifiOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
chkWifiRunAsRoot.setChecked(Boolean.parseBoolean(input.getStringExtra(ActivityManageRule.intentNameActionParameter2)));
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
// Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice), ActivityManageActionWifi.this).show();
if(getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
tvWifiExplanation1.setVisibility(View.VISIBLE);
else
tvWifiExplanation1.setVisibility(View.GONE);
bActionWifiSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent response = new Intent();
response.putExtra(ActivityManageRule.intentNameActionParameter1, rbActionWifiOn.isChecked());
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(chkWifiRunAsRoot.isChecked()));
setResult(RESULT_OK, response);
finish();
}
});
}
}

View File

@ -119,7 +119,17 @@ public class ActivityManageRule extends Activity
final static int requestCodeActionCloseNotificationEdit = 806;
final static int requestCodeActionControlMediaAdd = 807;
final static int requestCodeActionControlMediaEdit = 808;
final static int requestCodeTriggerBroadcastReceivedAdd = 809;
final static int requestCodeTriggerBroadcastReceivedEdit = 810;
final static int requestCodeActionSendBroadcastAdd = 811;
final static int requestCodeActionSendBroadcastEdit = 812;
final static int requestCodeActionRunExecutableAdd = 813;
final static int requestCodeActionRunExecutableEdit = 814;
final static int requestCodeActionSetWifiAdd = 815;
final static int requestCodeActionSetWifiEdit = 816;
final static int requestCodeTriggerTetheringAdd = 817;
final static int requestCodeTriggerTetheringEdit = 818;
public static ActivityManageRule getInstance()
{
if(instance == null)
@ -298,6 +308,17 @@ public class ActivityManageRule extends Activity
devicePositionEditor.putExtra(ActivityManageTriggerDeviceOrientation.vectorFieldName, selectedTrigger.getTriggerParameter2());
startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit);
break;
case broadcastReceived:
Intent broadcastEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerBroadcast.class);
broadcastEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
broadcastEditor.putExtra(intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2());
startActivityForResult(broadcastEditor, requestCodeTriggerBroadcastReceivedEdit);
break;
case tethering:
Intent tetheringEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerTethering.class);
tetheringEditor.putExtra(intentNameTriggerParameter1, selectedTrigger.getTriggerParameter());
startActivityForResult(tetheringEditor, requestCodeTriggerTetheringEdit);
break;
default:
break;
}
@ -367,6 +388,23 @@ public class ActivityManageRule extends Activity
activityEditVibrateIntent.putExtra("vibratePattern", a.getParameter2());
startActivityForResult(activityEditVibrateIntent, requestCodeActionVibrateEdit);
break;
case sendBroadcast:
Intent activityEditSendBroadcastIntent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
activityEditSendBroadcastIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSendBroadcastIntent, requestCodeActionSendBroadcastEdit);
break;
case runExecutable:
Intent activityEditRunExecutableIntent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
activityEditRunExecutableIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditRunExecutableIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditRunExecutableIntent, requestCodeActionRunExecutableEdit);
break;
case setWifi:
Intent activityEditSetWifiIntent = new Intent(ActivityManageRule.this, ActivityManageActionWifi.class);
activityEditSetWifiIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditSetWifiIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSetWifiIntent, requestCodeActionSetWifiEdit);
break;
case controlMediaPlayback:
Intent activityEditControlMediaIntent = new Intent(ActivityManageRule.this, ActivityManageActionControlMedia.class);
activityEditControlMediaIntent.putExtra(ActivityManageRule.intentNameActionParameter2, a.getParameter2());
@ -508,6 +546,8 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.plane));
else if(types[i].toString().equals(Trigger_Enum.roaming.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.roaming));
else if(types[i].toString().equals(Trigger_Enum.broadcastReceived.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Trigger_Enum.phoneCall.toString()))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS"))
@ -531,6 +571,12 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
else if(types[i].toString().equals(Trigger_Enum.screenState.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone));
else if(types[i].toString().equals(Trigger_Enum.deviceStarts.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm));
else if(types[i].toString().equals(Trigger_Enum.serviceStarts.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.alarm));
else if(types[i].toString().equals(Trigger_Enum.tethering.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.router));
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@ -595,7 +641,7 @@ public class ActivityManageRule extends Activity
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.usb_host_connection)
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel)
else if(triggerType == Trigger_Enum.speed || triggerType == Trigger_Enum.noiseLevel || triggerType == Trigger_Enum.batteryLevel)
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
else if(triggerType == Trigger_Enum.wifiConnection)
{
@ -698,6 +744,21 @@ public class ActivityManageRule extends Activity
{
newTrigger.setTriggerType(Trigger_Enum.screenState);
getTriggerScreenStateDialog().show();
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.lockedCommentScreenMustBeOff), ActivityManageRule.this).show();
return;
}
else if(triggerType == Trigger_Enum.deviceStarts)
{
newTrigger.setTriggerType(Trigger_Enum.deviceStarts);
ruleToEdit.getTriggerSet().add(newTrigger);
refreshTriggerList();
return;
}
else if(triggerType == Trigger_Enum.serviceStarts)
{
newTrigger.setTriggerType(Trigger_Enum.serviceStarts);
ruleToEdit.getTriggerSet().add(newTrigger);
refreshTriggerList();
return;
}
else if(triggerType == Trigger_Enum.headsetPlugged)
@ -708,6 +769,20 @@ public class ActivityManageRule extends Activity
if (NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
getTriggerParameterDialog(context, booleanChoices).show();
}
else if(triggerType == Trigger_Enum.broadcastReceived)
{
newTrigger.setTriggerType(Trigger_Enum.broadcastReceived);
Intent broadcastTriggerEditor = new Intent(myContext, ActivityManageTriggerBroadcast.class);
startActivityForResult(broadcastTriggerEditor, requestCodeTriggerBroadcastReceivedAdd);
return;
}
else if(triggerType == Trigger_Enum.tethering)
{
newTrigger.setTriggerType(Trigger_Enum.tethering);
Intent tetheringTriggerEditor = new Intent(myContext, ActivityManageTriggerTethering.class);
startActivityForResult(tetheringTriggerEditor, requestCodeTriggerTetheringAdd);
return;
}
else
getTriggerParameterDialog(context, booleanChoices).show();
@ -1044,7 +1119,9 @@ public class ActivityManageRule extends Activity
String[] choices = {
Miscellaneous.getAnyContext().getResources().getString(R.string.off),
Miscellaneous.getAnyContext().getResources().getString(R.string.on),
Miscellaneous.getAnyContext().getResources().getString(R.string.unlocked)
Miscellaneous.getAnyContext().getResources().getString(R.string.unlocked),
Miscellaneous.getAnyContext().getResources().getString(R.string.lockedWithoutSecurity),
Miscellaneous.getAnyContext().getResources().getString(R.string.lockedWithSecurity)
};
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
@ -1052,6 +1129,7 @@ public class ActivityManageRule extends Activity
@Override
public void onClick(DialogInterface dialog, int which)
{
newTrigger.setTriggerParameter(true);
newTrigger.setTriggerParameter2(String.valueOf(which));
ruleToEdit.getTriggerSet().add(newTrigger);
refreshTriggerList();
@ -1330,8 +1408,18 @@ public class ActivityManageRule extends Activity
{
if(resultCode == RESULT_OK)
{
newTrigger = ActivityManageTriggerNotification.resultingTrigger;
newTrigger.setParentRule(ruleToEdit);
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.notification);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageTriggerNotification.intentNameNotificationDirection, false));
editedTrigger.setTriggerParameter2(
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationApp) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTitleDir) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTitle) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationTextDir) + Trigger.triggerParameter2Split +
data.getStringExtra(ActivityManageTriggerNotification.intentNameNotificationText)
);
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
@ -1341,7 +1429,7 @@ public class ActivityManageRule extends Activity
{
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2"));
newTrigger.setTriggerParameter2(data.getStringExtra(intentNameTriggerParameter2));
this.refreshTriggerList();
}
}
@ -1433,6 +1521,27 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSendBroadcastAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionRunExecutableAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionControlMediaAdd)
{
if(resultCode == RESULT_OK)
@ -1443,6 +1552,17 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetWifiAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
newAction.setParameter2(data.getStringExtra(ActivityManageRule.intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionCreateNotificationAdd)
{
if(resultCode == RESULT_OK)
@ -1479,6 +1599,48 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSendBroadcastEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionRunExecutableEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetWifiEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1) && data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionControlMediaEdit)
{
if(resultCode == RESULT_OK)
@ -1612,6 +1774,52 @@ public class ActivityManageRule extends Activity
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerBroadcastReceivedAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerBroadcastReceivedEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.broadcastReceived);
editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerTetheringAdd)
{
if(resultCode == RESULT_OK)
{
newTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
newTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().add(newTrigger);
this.refreshTriggerList();
}
}
else if(requestCode == requestCodeTriggerTetheringEdit)
{
if(resultCode == RESULT_OK)
{
Trigger editedTrigger = new Trigger();
editedTrigger.setTriggerType(Trigger_Enum.tethering);
editedTrigger.setTriggerParameter(data.getBooleanExtra(intentNameTriggerParameter1, true));
editedTrigger.setParentRule(ruleToEdit);
ruleToEdit.getTriggerSet().set(editIndex, editedTrigger);
this.refreshTriggerList();
}
}
}
protected AlertDialog getActionTypeDialog()
@ -1665,6 +1873,10 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Action_Enum.closeNotification.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Action_Enum.sendBroadcast.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Action_Enum.runExecutable.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.script));
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
{
// if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageSpecificRule.this, "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(ActivityManageSpecificRule.this))
@ -1714,10 +1926,8 @@ public class ActivityManageRule extends Activity
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifi.toString()))
{
newAction.setAction(Action_Enum.setWifi);
getActionParameter1Dialog(ActivityManageRule.this).show();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
Miscellaneous.messageBox(context.getResources().getString(R.string.app_name), context.getResources().getString(R.string.android10WifiToggleNotice), context).show();
Intent editSetWifiIntent = new Intent(context, ActivityManageActionWifi.class);
startActivityForResult(editSetWifiIntent, requestCodeActionSetWifiAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setBluetooth.toString()))
{
@ -1827,6 +2037,18 @@ public class ActivityManageRule extends Activity
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
startActivityForResult(intent, requestCodeActionVibrateAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendBroadcast.toString()))
{
newAction.setAction(Action_Enum.sendBroadcast);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionSendBroadcast.class);
startActivityForResult(intent, requestCodeActionSendBroadcastAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.runExecutable.toString()))
{
newAction.setAction(Action_Enum.runExecutable);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
startActivityForResult(intent, requestCodeActionRunExecutableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.controlMediaPlayback.toString()))
{
newAction.setAction(Action_Enum.controlMediaPlayback);

View File

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

View File

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

View File

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

View File

@ -0,0 +1,46 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class ActivityManageTriggerTethering extends Activity
{
RadioButton rbTetheringOn, rTetheringOff;
Button bTriggerTetheringSave;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_trigger_tethering);
rbTetheringOn = (RadioButton) findViewById(R.id.rbTetheringOn);
rTetheringOff = (RadioButton)findViewById(R.id.rTetheringOff);
bTriggerTetheringSave = (Button) findViewById(R.id.bTriggerTetheringSave);
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameTriggerParameter1))
rbTetheringOn.setChecked(input.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true));
bTriggerTetheringSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent response = new Intent();
response.putExtra(ActivityManageRule.intentNameTriggerParameter1, rbTetheringOn.isChecked());
setResult(RESULT_OK, response);
finish();
}
});
}
}

View File

@ -10,13 +10,13 @@ import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@ -27,6 +27,7 @@ public class ActivityManageTriggerTimeFrame extends Activity
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday, chkRepeat;
RadioButton radioTimeFrameEntering, radioTimeFrameLeaving;
EditText etRepeatEvery;
TextView tvDaysHint;
static Trigger editedTimeFrameTrigger = null;
@ -53,17 +54,18 @@ public class ActivityManageTriggerTimeFrame extends Activity
radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving);
chkRepeat = (CheckBox)findViewById(R.id.chkRepeat);
etRepeatEvery = (EditText)findViewById(R.id.etRepeatEvery);
tvDaysHint = (TextView)findViewById(R.id.tvDaysHint);
bSaveTimeFrame.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Time startTime = new Time(0);
TimeObject startTime = new TimeObject();
startTime.setHours(startPicker.getCurrentHour());
startTime.setMinutes(startPicker.getCurrentMinute());
Time stopTime = new Time(0);
TimeObject stopTime = new TimeObject();
stopTime.setHours(stopPicker.getCurrentHour());
stopTime.setMinutes(stopPicker.getCurrentMinute());
@ -181,6 +183,31 @@ public class ActivityManageTriggerTimeFrame extends Activity
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(editedTimeFrameTrigger.getTriggerParameter2()));
loadVariableIntoGui();
}
TimePicker.OnTimeChangedListener pickerListener = new TimePicker.OnTimeChangedListener()
{
@Override
public void onTimeChanged(TimePicker timePicker, int i, int i1)
{
if(
startPicker.getCurrentHour() > stopPicker.getCurrentHour()
||
(
startPicker.getCurrentHour() == stopPicker.getCurrentHour()
&&
startPicker.getCurrentMinute() >= stopPicker.getCurrentMinute()
)
)
tvDaysHint.setText(getResources().getString(R.string.timeFrameDaysHint));
else
tvDaysHint.setText("");
}
};
startPicker.setOnTimeChangedListener(pickerListener);
stopPicker.setOnTimeChangedListener(pickerListener);
// Perform check once
pickerListener.onTimeChanged(null, 0, 0);
}
private void loadVariableIntoGui()

View File

@ -224,7 +224,7 @@ public class ActivityPermissions extends Activity
}
}
protected static void addToArrayListUnique(String value, ArrayList<String> list)
public static void addToArrayListUnique(String value, List<String> list)
{
if (!list.contains(value))
list.add(value);
@ -250,7 +250,7 @@ public class ActivityPermissions extends Activity
}
else if(s.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || s.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
if (!havePermission(s, context))
return true;
}
@ -381,7 +381,7 @@ public class ActivityPermissions extends Activity
}
else if (singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if (!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if (!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
addToArrayListUnique(singlePermission, requiredPermissions);
}
else

View File

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

View File

@ -33,6 +33,7 @@ import com.jens.automation2.receivers.PackageReplacedReceiver;
import com.jens.automation2.receivers.PhoneStatusListener;
import java.util.Calendar;
import java.util.Set;
@SuppressLint("NewApi")
public class AutomationService extends Service implements OnInitListener
@ -42,6 +43,10 @@ public class AutomationService extends Service implements OnInitListener
protected final static int notificationIdRestrictions = 1005;
protected final static int notificationIdLocationRestriction = 1006;
public static final String flavor_name_apk = "apkFlavor";
public static final String flavor_name_fdroid = "fdroidFlavor";
public static final String flavor_name_googleplay = "googlePlayFlavor";
final static String NOTIFICATION_CHANNEL_ID_SERVICE = "com.jens.automation2_service";
final static String NOTIFICATION_CHANNEL_NAME_SERVICE = "Service notification";
@ -193,6 +198,9 @@ public class AutomationService extends Service implements OnInitListener
{
Bundle b = intent.getExtras();
startAtBoot = b.getBoolean("startAtBoot", false);
if(startAtBoot)
Settings.deviceStartDone = false;
}
if (checkStartupRequirements(this, startAtBoot))
@ -212,12 +220,9 @@ public class AutomationService extends Service implements OnInitListener
ActivityMainScreen.updateMainScreen();
this.isRunning = true;
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
// ********** Test area **********
// Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3);
// Actions.setData(true);
// ********** Test area **********
/*
On normal phones the app is supposed to automatically restart in case of any problems.
@ -247,8 +252,6 @@ public class AutomationService extends Service implements OnInitListener
reloadSettings, reloadPointsOfInterest, reloadRules, updateNotification
}
;
public void serviceInterface(serviceCommands command)
{
Miscellaneous.logEvent("i", "Bind", "Ahhhh, customers... How can I help you?", 5);
@ -318,6 +321,8 @@ public class AutomationService extends Service implements OnInitListener
private void startUpRoutine()
{
Settings.serviceStartDone = false;
checkForTtsEngine();
checkForPermissions();
checkForRestrictedFeatures();
@ -336,6 +341,9 @@ public class AutomationService extends Service implements OnInitListener
if(r.getsGreenLight(AutomationService.this))
r.activate(AutomationService.this, false);
}
Settings.serviceStartDone = true;
Settings.deviceStartDone = true;
}
protected void startLocationProvider()
@ -558,11 +566,11 @@ public class AutomationService extends Service implements OnInitListener
if(activePoi == null)
{
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + " " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
}
else
{
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + " " + activePoi.getName() + lastRuleString;
}
}
catch(NullPointerException e)

View File

@ -481,6 +481,8 @@ public class Miscellaneous extends Service
return !haystack.equalsIgnoreCase(needle);
case Trigger.directionContains:
return haystack.toLowerCase().contains(needle.toLowerCase());
case Trigger.directionNotContains:
return !haystack.toLowerCase().contains(needle.toLowerCase());
case Trigger.directionStartsWith:
return haystack.toLowerCase().startsWith(needle.toLowerCase());
case Trigger.directionEndsWith:
@ -490,7 +492,7 @@ public class Miscellaneous extends Service
}
}
public static int compareTimes(Time time1, Time time2)
public static int compareTimes(TimeObject time1, TimeObject time2)
{
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
@ -710,14 +712,6 @@ public class Miscellaneous extends Service
}
});
// alertDialog.setNegativeButton(context.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
// {
// public void onClick(DialogInterface dialog, int whichButton)
// {
// // Canceled.
// }
// });
return alertDialog.create();
}
@ -744,8 +738,8 @@ public class Miscellaneous extends Service
*
* @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
*/
public static boolean isPhoneRooted()
{
public static boolean isPhoneRooted()
{
// if(true)
// return true;
@ -753,30 +747,30 @@ public class Miscellaneous extends Service
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys"))
{
return true;
return true;
}
// check if /system/app/Superuser.apk is present
try
{
File file = new File("/system/app/Superuser.apk");
if (file.exists())
{
return true;
}
}
catch (Exception e1)
{
try
{
File file = new File("/system/app/Superuser.apk");
if (file.exists())
{
return true;
}
}
catch (Exception e1)
{
// ignore
}
}
// try executing commands
return canExecuteCommand("/system/xbin/which su")
return canExecuteCommand("/system/xbin/which su")
||
canExecuteCommand("/system/bin/which su")
||
canExecuteCommand("which su");
}
}
// executes a command on the system
private static boolean canExecuteCommand(String command)
@ -804,9 +798,9 @@ public class Miscellaneous extends Service
* Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
private static void disableSSLCertificateChecking()
{
try
private static void disableSSLCertificateChecking()
{
try
{
SSLSocketFactory ssf = null;
@ -1626,7 +1620,7 @@ public class Miscellaneous extends Service
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
if (BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
{
if(checkExistingRules)
{

View File

@ -5,6 +5,7 @@ import android.util.Log;
import com.jens.automation2.location.CellLocationChangedReceiver;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.AutomationListenerInterface;
import com.jens.automation2.receivers.BatteryReceiver;
@ -17,6 +18,7 @@ import com.jens.automation2.receivers.NoiseListener;
import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ScreenStateReceiver;
import com.jens.automation2.receivers.TetheringReceiver;
import com.jens.automation2.receivers.TimeZoneListener;
import androidx.annotation.RequiresApi;
@ -58,7 +60,8 @@ public class ReceiverCoordinator
ProcessListener.class,
MediaPlayerListener.class,
ScreenStateReceiver.class,
TimeZoneListener.class
TimeZoneListener.class,
TetheringReceiver.class
};
}
catch (ClassNotFoundException e)
@ -67,6 +70,7 @@ public class ReceiverCoordinator
DateTimeListener.class,
BatteryReceiver.class,
BluetoothReceiver.class,
BroadcastListener.class,
ConnectivityReceiver.class,
DeviceOrientationListener.class,
HeadphoneJackListener.class,
@ -75,7 +79,8 @@ public class ReceiverCoordinator
PhoneStatusListener.class,
ProcessListener.class,
ScreenStateReceiver.class,
TimeZoneListener.class
TimeZoneListener.class,
TetheringReceiver.class
};
}
}
@ -163,6 +168,10 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.noiseLevel))
NoiseListener.startNoiseListener(AutomationService.getInstance());
// startBroadcastListener
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.broadcastReceived))
BroadcastListener.getInstance().startListener(AutomationService.getInstance());
// startProcessListener
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
ProcessListener.startProcessListener(AutomationService.getInstance());
@ -170,6 +179,9 @@ public class ReceiverCoordinator
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.deviceOrientation))
DeviceOrientationListener.getInstance().startListener(AutomationService.getInstance());
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.tethering))
TetheringReceiver.getInstance().startListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
@ -206,16 +218,18 @@ public class ReceiverCoordinator
TimeZoneListener.stopTimeZoneListener();
DateTimeListener.stopAlarmListener(AutomationService.getInstance());
NoiseListener.stopNoiseListener();
BroadcastListener.getInstance().stopListener(AutomationService.getInstance());
ProcessListener.stopProcessListener(AutomationService.getInstance());
MediaPlayerListener.getInstance().stopListener(AutomationService.getInstance());
DeviceOrientationListener.getInstance().stopListener(AutomationService.getInstance());
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
try
{
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
}
catch(ClassNotFoundException e)
catch(Exception e)
{
// Nothing to do, just not stopping this one.
}
@ -266,6 +280,17 @@ public class ReceiverCoordinator
NoiseListener.stopNoiseListener();
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.broadcastReceived))
{
Miscellaneous.logEvent("i", "LocationProvider", "Starting BroadcastReceiver because used in a new/changed rule.", 4);
BroadcastListener.getInstance().startListener(AutomationService.getInstance());
}
else
{
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down BroadcastReceiver because not used in any rule.", 4);
BroadcastListener.getInstance().stopListener(AutomationService.getInstance());
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
{
Miscellaneous.logEvent("i", "LocationProvider", "Starting ProcessListener because used in a new/changed rule.", 4);
@ -300,7 +325,7 @@ public class ReceiverCoordinator
MediaPlayerListener.getInstance().stopListener(AutomationService.getInstance());
}
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if(!BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_fdroid))
{
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
{
@ -397,6 +422,24 @@ public class ReceiverCoordinator
}
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.tethering))
{
if(!TetheringReceiver.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "TetheringReceiver", "Starting TetheringReceiver because used in a new/changed rule.", 4);
// if(DevicePositionListener.getInstance().haveAllPermission())
TetheringReceiver.getInstance().startListener(AutomationService.getInstance());
}
}
else
{
if(TetheringReceiver.getInstance().isListenerRunning())
{
Miscellaneous.logEvent("i", "TetheringReceiver", "Shutting down TetheringReceiver because not used in any rule.", 4);
TetheringReceiver.getInstance().stopListener(AutomationService.getInstance());
}
}
AutomationService.updateNotification();
}
}

View File

@ -12,7 +12,7 @@ import java.util.Set;
public class Settings implements SharedPreferences
{
public static final int rulesThatHaveBeenRanHistorySize = 10;
public final static int lockSoundChangesInterval = 15;
public static final int lockSoundChangesInterval = 15;
public static final int newsPollEveryXDays = 3;
public static final int newsDisplayForXDays = 3;
public static final int updateCheckFrequencyDays = 7;
@ -77,7 +77,13 @@ public class Settings implements SharedPreferences
public static ArrayList<String> whatHasBeenDone;
/*
Generic settings valid for all installations and not changable
Not saved permanently.
*/
public static boolean deviceStartDone = true; // by default assume device has not just been started
public static boolean serviceStartDone = false;
/*
Generic settings valid for all installations and not changeable
*/
public static final String dateFormat = "E dd.MM.yyyy HH:mm:ss:ssss";
@ -600,5 +606,4 @@ public class Settings implements SharedPreferences
// TODO Auto-generated method stub
return null;
}
}

View File

@ -6,8 +6,8 @@ import java.util.ArrayList;
public class TimeFrame
{
// Defines a timeframe
protected Time triggerTimeStart;
protected Time triggerTimeStop;
protected TimeObject triggerTimeStart;
protected TimeObject triggerTimeStop;
protected long repetition;
protected final static String separator = "/";
@ -34,20 +34,20 @@ public class TimeFrame
}
}
public Time getTriggerTimeStart()
public TimeObject getTriggerTimeStart()
{
return triggerTimeStart;
}
public void setTriggerTimeStart(Time triggerTimeStart)
public void setTriggerTimeStart(TimeObject triggerTimeStart)
{
this.triggerTimeStart = triggerTimeStart;
}
public Time getTriggerTimeStop()
public TimeObject getTriggerTimeStop()
{
return triggerTimeStop;
}
public void setTriggerTimeStop(Time triggerTimeStop)
public void setTriggerTimeStop(TimeObject triggerTimeStop)
{
this.triggerTimeStop = triggerTimeStop;
}
@ -62,7 +62,7 @@ public class TimeFrame
this.repetition = repetition;
}
public TimeFrame (Time timeStart, Time timeEnd, ArrayList<Integer> dayList2, long repetition)
public TimeFrame (TimeObject timeStart, TimeObject timeEnd, ArrayList<Integer> dayList2, long repetition)
{
this.setTriggerTimeStart(timeStart);
this.setTriggerTimeStop(timeEnd);
@ -73,8 +73,8 @@ public class TimeFrame
public TimeFrame (String fileContent)
{
String[] dateArray = fileContent.split(separator); // example: timestart/timestop/days[int]/repetition
this.setTriggerTimeStart(Time.valueOf(dateArray[0]));
this.setTriggerTimeStop(Time.valueOf(dateArray[1]));
this.setTriggerTimeStart(TimeObject.valueOf(dateArray[0]));
this.setTriggerTimeStop(TimeObject.valueOf(dateArray[1]));
this.setDayListFromString(dateArray[2]);
if(dateArray.length > 3) // may not exist in old config files
this.setRepetition(Long.parseLong(dateArray[3]));

View File

@ -0,0 +1,68 @@
package com.jens.automation2;
import java.sql.Time;
public class TimeObject
{
int hours, minutes, seconds;
public TimeObject()
{
}
public int getHours()
{
return hours;
}
public void setHours(int hours)
{
this.hours = hours;
}
public int getMinutes()
{
return minutes;
}
public void setMinutes(int minutes)
{
this.minutes = minutes;
}
public int getSeconds()
{
return seconds;
}
public void setSeconds(int seconds)
{
this.seconds = seconds;
}
public TimeObject(int hours, int minutes, int seconds)
{
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
public static TimeObject valueOf(String input)
{
TimeObject ro = null;
if(input.contains(":"))
{
String[] parts = input.split(":");
if(parts.length == 2)
ro = new TimeObject(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 0);
else if(parts.length == 3)
ro = new TimeObject(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
else
Miscellaneous.logEvent("w", "TimeObject", "Invalid length for time. Input: " + input, 4);
}
return ro;
}
}

View File

@ -3,7 +3,6 @@ package com.jens.automation2;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.telephony.TelephonyManager;
import android.util.Log;
@ -14,6 +13,7 @@ import com.jens.automation2.location.LocationProvider;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.BatteryReceiver;
import com.jens.automation2.receivers.BluetoothReceiver;
import com.jens.automation2.receivers.BroadcastListener;
import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.DeviceOrientationListener;
import com.jens.automation2.receivers.HeadphoneJackListener;
@ -24,22 +24,43 @@ import com.jens.automation2.receivers.NotificationListener;
import com.jens.automation2.receivers.PhoneStatusListener;
import com.jens.automation2.receivers.ProcessListener;
import com.jens.automation2.receivers.ScreenStateReceiver;
import static com.jens.automation2.Trigger.triggerParameter2Split;
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
import com.jens.automation2.receivers.TetheringReceiver;
import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Trigger
{
public enum Trigger_Enum {
pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, screenState, musicPlaying, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
public enum Trigger_Enum
{
pointOfInterest,
timeFrame,
charging,
batteryLevel,
usb_host_connection,
speed,
noiseLevel,
wifiConnection,
process_started_stopped,
airplaneMode,
roaming,
nfcTag,
activityDetection,
bluetoothConnection,
headsetPlugged,
notification,
deviceOrientation,
profileActive,
screenState,
musicPlaying,
deviceStarts,
serviceStarts,
broadcastReceived,
tethering,
phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
public String getFullName(Context context)
{
@ -87,6 +108,14 @@ public class Trigger
return context.getResources().getString(R.string.musicPlaying);
case screenState:
return context.getResources().getString(R.string.screenState);
case deviceStarts:
return context.getResources().getString(R.string.deviceStarts);
case serviceStarts:
return context.getResources().getString(R.string.serviceStarts);
case broadcastReceived:
return context.getResources().getString(R.string.broadcastReceivedTitle);
case tethering:
return context.getResources().getString(R.string.tetheringState);
default:
return "Unknown";
}
@ -190,6 +219,22 @@ public class Trigger
if(!checkScreenState())
result = false;
break;
case deviceStarts:
if(!checkDeviceStarts())
result = false;
break;
case serviceStarts:
if(!checkServiceStarts())
result = false;
break;
case broadcastReceived:
if(!checkBroadcastReceived())
result = false;
break;
case tethering:
if(!checkTetheringActive())
result = false;
break;
default:
break;
}
@ -206,7 +251,19 @@ public class Trigger
return result;
}
boolean checkNotification()
boolean checkBroadcastReceived()
{
/*
We cannot reasonably check the current state for every broadcast event.
We can only hope that when starting the receiver we get an initial broadcast
for every current state. That collection of states will be saved and checked if
it contains the specific event of this trigger.
*/
return triggerParameter == BroadcastListener.getInstance().hasBroadcastOccurred(triggerParameter2);
}
boolean checkNotification()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
@ -343,6 +400,16 @@ public class Trigger
return triggerParameter == MediaPlayerListener.isAudioPlaying(Miscellaneous.getAnyContext());
}
boolean checkDeviceStarts()
{
return checkServiceStarts() && !Settings.deviceStartDone;
}
boolean checkServiceStarts()
{
return !Settings.serviceStartDone;
}
boolean checkProfileActive()
{
String demandedProfileName = getTriggerParameter2().split(Trigger.triggerParameter2Split)[0];
@ -385,13 +452,15 @@ public class Trigger
try
{
int desiredState = Integer.parseInt(getTriggerParameter2());
int currentState = ScreenStateReceiver.getScreenState();
return desiredState == currentState;
if(desiredState == ScreenStateReceiver.SCREEN_STATE_OFF || desiredState == ScreenStateReceiver.SCREEN_STATE_ON)
return desiredState == ScreenStateReceiver.getScreenPowerState();
else
return desiredState == ScreenStateReceiver.getScreenLockState();
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "Trigger", "Error checking profile trigger.", 4);
Miscellaneous.logEvent("w", "Trigger", "Error checking screen state trigger.", 4);
}
return false;
@ -857,6 +926,11 @@ public class Trigger
return true;
}
boolean checkTetheringActive()
{
return TetheringReceiver.isTetheringActive() == triggerParameter;
}
public boolean checkDateTime(Object triggeringObject, boolean checkifStateChangedSinceLastRuleExecution)
{
/*
@ -872,7 +946,7 @@ public class Trigger
triggeringTime = new Date();
String timeString = String.valueOf(triggeringTime.getHours()) + ":" + String.valueOf(triggeringTime.getMinutes()) + ":" + String.valueOf(triggeringTime.getSeconds());
Time nowTime = Time.valueOf(timeString);
TimeObject nowTime = TimeObject.valueOf(timeString);
Calendar calNow = Calendar.getInstance();
try
@ -884,20 +958,24 @@ public class Trigger
if(
// Regular case, start time is lower than end time
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
&&
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0
)
||
// Other case, start time higher than end time, timeframe goes over midnight
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0
&&
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0)
)
||
// further case: start and end times are identical, meaning a 24h window
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) == 0
)
|
// Other case, start time higher than end time, timeframe goes over midnight
(
Miscellaneous.compareTimes(tf.getTriggerTimeStart(), tf.getTriggerTimeStop()) < 0
&&
(Miscellaneous.compareTimes(tf.getTriggerTimeStart(), nowTime) >= 0
||
Miscellaneous.compareTimes(nowTime, tf.getTriggerTimeStop()) > 0)
)
)
{
// We are in the timeframe
@ -1023,7 +1101,7 @@ public class Trigger
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
Time setTime;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)
@ -1217,9 +1295,9 @@ public class Trigger
return triggerType;
}
public void setTriggerType(Trigger_Enum settriggerType)
public void setTriggerType(Trigger_Enum setTriggerType)
{
this.triggerType = settriggerType;
this.triggerType = setTriggerType;
}
public boolean getTriggerParameter()
@ -1538,16 +1616,43 @@ public class Trigger
state = Miscellaneous.getAnyContext().getString(R.string.off);
break;
case "1":
state = Miscellaneous.getAnyContext().getString(R.string.on);
state = Miscellaneous.getAnyContext().getString(R.string.on);
break;
case "2":
state = Miscellaneous.getAnyContext().getString(R.string.unlocked);
break;
case "3":
state = Miscellaneous.getAnyContext().getString(R.string.lockedWithoutSecurity);
break;
case "4":
state = Miscellaneous.getAnyContext().getString(R.string.lockedWithSecurity);
break;
default:
state = Miscellaneous.getAnyContext().getString(R.string.unknown);
}
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.screenIs), state));
break;
case deviceStarts:
// This type doesn't have an activate/deactivate equivalent
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deviceHasJustStarted));
break;
case serviceStarts:
// This type doesn't have an activate/deactivate equivalent
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.serviceHasJustStarted));
break;
case broadcastReceived:
if(triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.broadcastReceived));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.broadcastNotReceived));
returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.screenIs), state));
returnString.append(": " + triggerParameter2);
break;
case tethering:
if(triggerParameter)
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.tetheringActive));
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.tetheringNotActive));
break;
default:
returnString.append("error");
@ -1559,6 +1664,7 @@ public class Trigger
public static final String directionEquals = "eq";
public static final String directionContains = "ct";
public static final String directionNotContains = "nc";
public static final String directionStartsWith = "sw";
public static final String directionEndsWith = "ew";
public static final String directionNotEquals = "ne";
@ -1571,6 +1677,8 @@ public class Trigger
return Miscellaneous.getAnyContext().getString(R.string.directionStringEquals);
case directionContains:
return Miscellaneous.getAnyContext().getString(R.string.directionStringContains);
case directionNotContains:
return Miscellaneous.getAnyContext().getString(R.string.directionStringDoesNotContain);
case directionStartsWith:
return Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith);
case directionEndsWith:
@ -1588,6 +1696,8 @@ public class Trigger
return directionEquals;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringContains)))
return directionContains;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringDoesNotContain)))
return directionNotContains;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith)))
return directionStartsWith;
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringEndsWith)))
@ -1612,11 +1722,7 @@ public class Trigger
public static String[] getTriggerTypesStringAsArray(Context context)
{
ArrayList<String> triggerTypesList = new ArrayList<String>();
/*for(int i=0; i<Trigger_Enum.values().length; i++)
{
triggerTypesList.add(Trigger_Enum.values()[i].getFullName(context));
}*/
for(Trigger_Enum triggerType : Trigger_Enum.values())
triggerTypesList.add(triggerType.getFullName(context));

View File

@ -26,7 +26,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static Boolean wasConnected = false;
protected static String lastWifiSsid = "";
public static boolean lastConnectedState = false;
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
protected static WifiBroadcastReceiver wifiBrInstance;
protected static IntentFilter wifiListenerIntentFilter;
protected static boolean wifiListenerActive=false;
@ -52,7 +52,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static boolean mayCellLocationReceiverBeActivated()
{
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi;
return mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView;
}
@Override
@ -63,18 +63,12 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
// int state = -1;
NetworkInfo myWifi = null;
// if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) //gefeuert bei Verbindung
// {
// Miscellaneous.logEvent("i", "WifiReceiver", "RSSI_CHANGED_ACTION: " + String.valueOf(intent.getIntExtra(WifiManager.RSSI_CHANGED_ACTION, -1)));
// }
// else
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) //gefeuert bei Trennung
{
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));
myWifi = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
}
WifiManager myWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
// ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
@ -95,8 +89,14 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
if(Settings.useWifiForPositioning && PointOfInterest.reachedPoiWithActivateWifiRule()) // Poi has wifi
{
Miscellaneous.logEvent("i", "WifiReceiver", context.getResources().getString(R.string.poiHasWifiStoppingCellLocationListener), 2);
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = false;
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = false;
CellLocationChangedReceiver.stopCellLocationChangedReceiver();
/*
TODO: Every time the screen is turned on, we receiver a "wifi has been connected"-event.
This is technically wrong and not really any changed to when the screen was off. It has
to be filtered.
*/
}
else
{
@ -110,7 +110,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
wasConnected = true;
Miscellaneous.logEvent("i", "WifiReceiver", "WifiReceiver just activated. Wifi already connected. Stopping CellLocationReceiver", 3);
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = false;
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = false;
CellLocationChangedReceiver.stopCellLocationChangedReceiver();
SensorActivity.stopAccelerometerTimer();
String ssid = myWifiManager.getConnectionInfo().getSSID();
@ -126,7 +126,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
wasConnected = false;
Miscellaneous.logEvent("i", "WifiReceiver", String.format(context.getResources().getString(R.string.disconnectedFromWifi), getLastWifiSsid()) + " Switching to CellLocationChangedReceiver.", 3);
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
CellLocationChangedReceiver.startCellLocationChangedReceiver();
lastConnectedState = false;
findRules(AutomationService.getInstance());

View File

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

View File

@ -0,0 +1,168 @@
package com.jens.automation2.receivers;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class BroadcastListener extends android.content.BroadcastReceiver implements AutomationListenerInterface
{
ArrayList<EventOccurrence> broadcastsCollection = new ArrayList<>();
public static AutomationService automationServiceRef = null;
private static boolean broadcastReceiverActive = false;
private static BroadcastListener broadcastReceiverInstance = null;
private static IntentFilter broadcastIntentFilter = null;
private static Intent broadcastStatus = null;
public static BroadcastListener getInstance()
{
if(broadcastReceiverInstance == null)
broadcastReceiverInstance = new BroadcastListener();
return broadcastReceiverInstance;
}
public static class EventOccurrence
{
Calendar time;
String event;
public EventOccurrence(Calendar time, String event)
{
this.time = time;
this.event = event;
}
}
@Override
public void onReceive(Context context, Intent intent)
{
broadcastsCollection.add(new EventOccurrence(Calendar.getInstance(), intent.getAction()));
for(String key : intent.getExtras().keySet())
{
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
public ArrayList<EventOccurrence> getBroadcastsCollection()
{
return broadcastsCollection;
}
public boolean hasBroadcastOccurred(String event)
{
for(EventOccurrence eo : broadcastsCollection)
{
if(eo.event.equalsIgnoreCase(event))
return true;
}
return false;
}
public boolean hasBroadcastOccurredSince(String event, Calendar timeLimit)
{
for(EventOccurrence eo : broadcastsCollection)
{
if(eo.event.equalsIgnoreCase(event) && (timeLimit == null || eo.time.getTimeInMillis() > timeLimit.getTimeInMillis()))
return true;
}
return false;
}
@Override
public void startListener(AutomationService automationService)
{
if(!broadcastReceiverActive)
{
BroadcastListener.automationServiceRef = automationService;
if(broadcastReceiverInstance == null)
broadcastReceiverInstance = new BroadcastListener();
if(broadcastIntentFilter == null)
{
broadcastIntentFilter = new IntentFilter();
List<String> actionList = new ArrayList<>();
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);
for(int i=0; i<ruleCandidates.size(); i++)
{
for(Trigger t : ruleCandidates.get(i).getTriggerSet())
{
if(t.getTriggerType().equals(Trigger.Trigger_Enum.broadcastReceived))
{
ActivityPermissions.addToArrayListUnique(t.getTriggerParameter2(), actionList);
}
}
}
for(String s : actionList)
broadcastIntentFilter.addAction(s);
}
try
{
broadcastStatus = automationServiceRef.registerReceiver(broadcastReceiverInstance, broadcastIntentFilter);
broadcastReceiverActive = true;
}
catch(Exception e)
{
/*
We might be confronted with permission issues here.
*/
Miscellaneous.logEvent("e", "BroadcastListener", Log.getStackTraceString(e), 1);
broadcastReceiverActive = false;
}
}
}
@Override
public void stopListener(AutomationService automationService)
{
if(broadcastReceiverActive)
{
if(broadcastReceiverInstance != null)
{
automationServiceRef.unregisterReceiver(broadcastReceiverInstance);
broadcastReceiverInstance = null;
}
broadcastReceiverActive = false;
}
}
@Override
public boolean isListenerRunning()
{
return broadcastReceiverActive;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.broadcastReceived };
}
}

View File

@ -14,6 +14,7 @@ import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.TimeFrame;
import com.jens.automation2.TimeObject;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
@ -96,7 +97,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
TimeFrame tf = new TimeFrame(oneTrigger.getTriggerParameter2());
Calendar calSet;
Time setTime;
TimeObject setTime;
if(oneTrigger.getTriggerParameter())
setTime = tf.getTriggerTimeStart();
@ -365,7 +366,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
public static Calendar getNextRepeatedExecutionAfter(Trigger trigger, Calendar now)
{
Calendar calSet;
Time setTime;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0)

View File

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

View File

@ -89,6 +89,11 @@ public class NotificationListener extends NotificationListenerService// implemen
{
lastNotification = convertNotificationToSimpleNotification(created, sbn);
if(created)
Miscellaneous.logEvent("i", "New notification", lastNotification.toString(), 5);
else
Miscellaneous.logEvent("i", "Notification removed", lastNotification.toString(), 5);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
for (int i = 0; i < ruleCandidates.size(); i++)
{

View File

@ -1,14 +1,18 @@
package com.jens.automation2.receivers;
import android.Manifest;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.util.Log;
import android.widget.Toast;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.RequiresApi;
import com.jens.automation2.Actions;
import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
@ -16,10 +20,13 @@ import com.jens.automation2.Rule;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class ScreenStateReceiver extends BroadcastReceiver implements AutomationListenerInterface
{
static int screenState = -1; // initialize with a better value than this
static int screenPowerState = -1; // initialize with a better value than this
static int screenLockState = -1; // initialize with a better value than this
public static AutomationService automationServiceRef = null;
private static boolean screenStateReceiverActive = false;
@ -27,9 +34,18 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
private static Intent screenStatusIntent = null;
private static BroadcastReceiver screenStateReceiverInstance = null;
public final static String broadcastScreenLockedWithoutSecurity = "automation.system.screen_locked_without_security";
public final static String broadcastScreenLockedWithSecurity = "automation.system.screen_locked_with_security";
public final static int SCREEN_STATE_OFF = 0;
public final static int SCREEN_STATE_ON = 1;
public final static int SCREEN_STATE_UNLOCKED = 2;
public final static int SCREEN_STATE_LOCKED_WITHOUT_SECURITY = 3;
public final static int SCREEN_STATE_LOCKED_WITH_SECURITY = 4;
public static BroadcastReceiver getScreenStateReceiverInstance()
{
if(screenStateReceiverInstance == null)
if (screenStateReceiverInstance == null)
screenStateReceiverInstance = new ScreenStateReceiver();
return screenStateReceiverInstance;
@ -37,58 +53,60 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
public static void startScreenStateReceiver(final AutomationService automationServiceRef)
{
if(!screenStateReceiverActive)
if (!screenStateReceiverActive)
{
ScreenStateReceiver.automationServiceRef = automationServiceRef;
if(screenStateReceiverInstance == null)
if (screenStateReceiverInstance == null)
screenStateReceiverInstance = new ScreenStateReceiver();
if(screenStateIntentFilter == null)
if (screenStateIntentFilter == null)
{
screenStateIntentFilter = new IntentFilter();
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
screenStateIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateIntentFilter.addAction(Intent.ACTION_USER_PRESENT);
screenStateIntentFilter.addAction(Intent.ACTION_USER_PRESENT); // also fired when device is unlocked
screenStateIntentFilter.addAction(broadcastScreenLockedWithoutSecurity);
screenStateIntentFilter.addAction(broadcastScreenLockedWithSecurity);
// Intent.ACTION_USER_UNLOCKED
}
screenStatusIntent = automationServiceRef.registerReceiver(screenStateReceiverInstance, screenStateIntentFilter);
screenStateReceiverActive = true;
}
}
public static void stopScreenStateReceiver()
{
if(screenStateReceiverActive)
if (screenStateReceiverActive)
{
if(screenStateReceiverInstance != null)
if (screenStateReceiverInstance != null)
{
automationServiceRef.unregisterReceiver(screenStateReceiverInstance);
screenStateReceiverInstance = null;
}
screenStateReceiverActive = false;
}
}
public static boolean isScreenStateReceiverActive()
{
return screenStateReceiverActive;
}
public static int getScreenState()
public static int getScreenPowerState()
{
return screenState;
return screenPowerState;
}
private static int currentChargingState = 0; //0=unknown, 1=no, 2=yes
public static int getCurrentChargingState()
public static int getScreenLockState()
{
return currentChargingState;
return screenLockState;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
@Override
public void onReceive(Context context, Intent intent)
{
@ -101,32 +119,65 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
try
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
ScreenStateReceiver.screenState = 0;
ScreenStateReceiver.screenPowerState = SCREEN_STATE_OFF;
KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "Method 2: " + String.valueOf(pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked()), 4);
// if (pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked())
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "pm.isInteractive(): " + String.valueOf(pm.isInteractive()), 4);
// Miscellaneous.logEvent("i", "ScreenStateReceiver", "pm.isScreenOn(): " + String.valueOf(pm.isScreenOn()), 4);
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isKeyguardLocked(): " + String.valueOf(keyguardManager.isKeyguardLocked()), 4);
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isDeviceLocked(): " + String.valueOf(keyguardManager.isDeviceLocked()), 4);
if(keyguardManager.isKeyguardLocked() && !keyguardManager.isDeviceLocked())
{
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithoutSecurity);
}
else if(keyguardManager.isDeviceLocked())
{
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithSecurity);
}
else
{
// Lock may be activated delayed, not at power button press
ScreenLockMonitor mon = new ScreenLockMonitor();
mon.startMonitor();
}
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
ScreenStateReceiver.screenState = 1;
ScreenStateReceiver.screenPowerState = SCREEN_STATE_ON;
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT))
else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT))
{
ScreenStateReceiver.screenState = 2;
ScreenStateReceiver.screenLockState = SCREEN_STATE_UNLOCKED;
}
else if (intent.getAction().equals(broadcastScreenLockedWithoutSecurity))
{
ScreenStateReceiver.screenLockState = SCREEN_STATE_LOCKED_WITHOUT_SECURITY;
}
else if (intent.getAction().equals(broadcastScreenLockedWithSecurity))
{
ScreenStateReceiver.screenLockState = SCREEN_STATE_LOCKED_WITH_SECURITY;
}
else
{
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Unknown state received: " + intent.getAction(), 3);
}
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "ScreenStateReceiver", "Error receiving screen state: " + e.getMessage(), 3);
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.screenState);
for(int i=0; i<ruleCandidates.size(); i++)
for (int i = 0; i < ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).getsGreenLight(context))
if (ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@ -136,6 +187,7 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
{
ScreenStateReceiver.startScreenStateReceiver(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
@ -145,7 +197,7 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
public static boolean haveAllPermission()
{
return ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext()) &&
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
ActivityPermissions.havePermission(Manifest.permission.BATTERY_STATS, Miscellaneous.getAnyContext());
}
@Override
@ -157,6 +209,66 @@ public class ScreenStateReceiver extends BroadcastReceiver implements Automation
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.screenState };
return new Trigger_Enum[]{Trigger_Enum.screenState};
}
class ScreenLockMonitor
{
long runs = 0;
final long maxRuns = 20;
final long interval = 1000;
Timer timer = new Timer();
TimerTask task = new TimerTask()
{
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
@Override
public void run()
{
KeyguardManager keyguardManager = (KeyguardManager) Miscellaneous.getAnyContext().getSystemService(Context.KEYGUARD_SERVICE);
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isKeyguardLocked(): " + String.valueOf(keyguardManager.isKeyguardLocked()), 4);
Miscellaneous.logEvent("i", "ScreenStateReceiver", "keyguardManager.isDeviceLocked(): " + String.valueOf(keyguardManager.isDeviceLocked()), 4);
if(keyguardManager.isKeyguardLocked() && !keyguardManager.isDeviceLocked())
{
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithoutSecurity);
timer.purge();
timer.cancel();
}
else if(keyguardManager.isDeviceLocked())
{
Actions.sendBroadcast(Miscellaneous.getAnyContext(), broadcastScreenLockedWithSecurity);
timer.purge();
timer.cancel();
}
else
{
if (runs++ > maxRuns)
{
Miscellaneous.logEvent("w", "ScreenStateReceiver->ScreenLockMonitor", "Lock never came.", 4);
timer.purge();
timer.cancel();
}
}
}
};
public void startMonitor()
{
ContentResolver mResolver = Miscellaneous.getAnyContext().getContentResolver();
long lockscreen_timeout = 0;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1)
lockscreen_timeout = Settings.System.getInt(mResolver, "lock_screen_lock_after_timeout", 0);
else
lockscreen_timeout = Settings.Secure.getInt(mResolver, "lock_screen_lock_after_timeout", 0);
if(lockscreen_timeout > 0)
timer.schedule(task, lockscreen_timeout);
else
timer.scheduleAtFixedRate(task, 0, interval);
}
}
}

View File

@ -0,0 +1,130 @@
package com.jens.automation2.receivers;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import java.util.ArrayList;
public class TetheringReceiver extends android.content.BroadcastReceiver implements AutomationListenerInterface
{
public static AutomationService automationServiceRef = null;
private static boolean receiverActive = false;
private static TetheringReceiver receiverInstance = null;
private static IntentFilter intentFilter = null;
private static boolean tetheringActive = false;
public static TetheringReceiver getInstance()
{
if(receiverInstance == null)
receiverInstance = new TetheringReceiver();
return receiverInstance;
}
public static boolean isTetheringActive()
{
return tetheringActive;
}
@Override
public void onReceive(Context context, Intent intent)
{
for(String key : intent.getExtras().keySet())
{
// Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
Object ob = intent.getExtras().get(key);
String target = null;
if(Build.VERSION.SDK_INT >= 26)
target = "tetherArray";
else
target = "activeArray";
if(key.equals(target) && ob instanceof ArrayList)
{
if(((ArrayList<String>)ob).size() > 0)
tetheringActive = true;
else
tetheringActive = false;
}
// Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.tethering);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).getsGreenLight(context))
ruleCandidates.get(i).activate(automationServiceRef, false);
}
}
@Override
public void startListener(AutomationService automationService)
{
if(!receiverActive)
{
TetheringReceiver.automationServiceRef = automationService;
if(receiverInstance == null)
receiverInstance = new TetheringReceiver();
if(intentFilter == null)
{
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.TETHER_STATE_CHANGED");
}
try
{
automationServiceRef.registerReceiver(receiverInstance, intentFilter);
receiverActive = true;
}
catch(Exception e)
{
/*
We might be confronted with permission issues here.
*/
Miscellaneous.logEvent("e", "TetheringReceiver", Log.getStackTraceString(e), 1);
receiverActive = false;
}
}
}
@Override
public void stopListener(AutomationService automationService)
{
if(receiverActive)
{
if(receiverInstance != null)
{
automationServiceRef.unregisterReceiver(receiverInstance);
receiverInstance = null;
}
receiverActive = false;
}
}
@Override
public boolean isListenerRunning()
{
return receiverActive;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[] { Trigger.Trigger_Enum.tethering};
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:textSize="25dp"
android:textStyle="bold"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/tetheringState"/>
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/state" />
<RadioGroup
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbTetheringOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/on" />
<RadioButton
android:id="@+id/rTetheringOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/off" />
</RadioGroup>
</TableRow>
</TableLayout>
<Button
android:id="@+id/bTriggerTetheringSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

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

View File

@ -413,7 +413,7 @@
<string name="volumeTest">Lautstärkekalibrierung</string>
<string name="volumeCalibrationExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
<string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie die Regel manuell ausführen, um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken "immer erlauben" setzen. Ansonsten wird die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen.</string>
<string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string>
<string name="phoneNrReplacementError">Die letzte Telefonnummer konnte nicht in die Variable integriert werden. Sie liegt mir nicht vor.</string>
<string name="username">Benutzername</string>
@ -557,7 +557,7 @@
<string name="noFilesImported">Keine Dateien konnten importiert werden.</string>
<string name="notAllFilesImported">Nicht alle passenden Dateien konnten importiert werden.</string>
<string name="openExamplesPage">Webseite mit Beispielen öffnen</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben, aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben (des Anrufpartners), aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
<string name="prefsImportError">Fehler beim Importieren der Einstellungen.</string>
<string name="rulesImportedSuccessfully">Regeln und Orte wurden erfolgreich importiert.</string>
<string name="rulesImportError">Fehler beim Importieren der Regeln.</string>
@ -701,4 +701,40 @@
<string name="profileXrequiresThis">Profil \"%1$s\" benötigt dies.</string>
<string name="lastProfile">Letztes Profil:</string>
<string name="queryAllPackages">Liste von installierten Anwendungen auslesen</string>
<string name="timeFrameDaysHint">Wenn Sie ein Zeitfenster verwenden, das sich über Mitternacht erstreckt, müssen Sie auch den Folgetag auswählen, wenn der Auslöser auch nach Mitternacht noch auslösen soll.</string>
<string name="featureNotInGooglePlayVersion">Diese Funktion ist in der Google Play-Version nicht mehr verfügbar.\n\nHin und wieder schikaniert Google Entwickler. Wenn Sie bestimmte Funktionen weiterhin verwenden möchten, müssen Sie Unterlagen einreichen. Leider besteht eine 99% ige Chance, dass der Papierkram abgelehnt wird. Es ist so ziemlich wie im Asterix-Comic/Film.\n\nIch habe in der Vergangenheit Wochen damit verbracht, mit ihnen über solche Fälle zu streiten, aber ich bekam immer wieder Ablehnungen - entweder von Bots oder von Leuten, die ungefähr so intelligent sind wie Bots. Ich kann mich dann nur entscheiden, ob die App vollständig aus dem Play Store fliegen soll oder die Funktion aus der Play Store Version entfernen.\n\nBitte erwägen Sie, die APK-Version von meiner Website oder die von F-Droid zu verwenden, wenn Sie diese Funktionen benötigen.</string>
<string name="startActivityInsertManually">Diese Einschränkung betrifft nur die Auswahl einer App, nicht den eigentlichen Start. So können Sie den Namen einer Anwendung immer noch manuell eingeben, falls Sie ihn kennen.</string>
<string name="serviceStarts">Dienst startet</string>
<string name="deviceStarts">Gerät startet</string>
<string name="deviceHasJustStarted">Gerät ist gerade gestartet</string>
<string name="serviceHasJustStarted">Dienst ist gerade gestartet</string>
<string name="broadcastReceived">Broadcast empfangen</string>
<string name="broadcastNotReceived">Broadcast nicht empfangen</string>
<string name="broadcastReceivedTitle">Broadcast empfangen</string>
<string name="broadcastsShowSuggestions">Vorschläge anzeigen</string>
<string name="selectBroadcast">Broadcast auswählen</string>
<string name="lockedWithoutSecurity">gesperrt (nur wischen, keine PIN, etc.)</string>
<string name="lockedWithSecurity">gesperrt (mit PIN, etc.)</string>
<string name="lockedCommentScreenMustBeOff">Jeglicher Sperrzustand wird nur erkannt werden, wenn gleichzeitig der Bildschirm aus ist.</string>
<string name="emailPretext">Wenn Sie ein Problem, einen Vorschlag oder eine Frage haben, schreiben Sie bitte auch etwas in die Email. Senden Sie mir nicht einfach die Dateien mit dem Standard-Mailtext. Ich werde solche Nachrichten ignorieren, sollten wir nicht bereits in einer Konversation sein.</string>
<string name="sendBroadcast">Broadcast verschicken</string>
<string name="enterBroadcast">Geben Sie eine Aktion für den Broadcast ein.</string>
<string name="broadcastExplanation">Diese Aktion erlaubt es, einen Broadcast über das Nachrichtensystem von Android zu verschicken. Das ist für den Benutzer nicht sichtbar, aber Anwendungen, die sich für bestimmte Broadcasts registriert haben, können darauf reagieren.</string>
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
<string name="logsExplanation">Um eine unnötige Abnutzung Ihres Speichers zu vermeiden, werden Protokolle standardmäßig nicht gespeichert. Wenn Sie also ein Problem haben, aktivieren Sie bitte zuerst die Anmeldeeinstellungen und setzen Sie den Protokollpegel auf 5. Reproduzieren Sie dann das Problem. Erst dann können Protokolle angehängt werden.</string>
<string name="directionStringDoesNotContain">enthält nicht</string>
<string name="path">Pfad</string>
<string name="runExecutable">Programm/Script ausführen</string>
<string name="parameters">Parameter</string>
<string name="chooseExecutable">Datei auswählen</string>
<string name="runAsRoot">Als root ausführen</string>
<string name="selectValidExecutable">Wählen Sie eine gültige ausführbare Datei aus.</string>
<string name="fileNotExecutable">Diese Datei ist nicht ausführbar.</string>
<string name="usingRoot">als root</string>
<string name="tetheringActive">Tethering ist aktiv</string>
<string name="tetheringNotActive">Tethering ist nicht aktiv</string>
<string name="tetheringState">Tethering Status</string>
<string name="wifiExplanation2">Während der Flugmodus aktiv ist, kann WLAN nur von Anwendungen ein- oder ausgeschaltet werden, wenn root-Rechte dafür verwendet werden.</string>
<string name="wifiExplanation1">Anwendungen, die auf Android Q oder höher ausgerichtet sind, können WLAN nicht mehr ein- oder ausschalten. Daran ist Google schuld, nicht ich.\n\nSie können diese Einschränkung umgehen, indem Sie Ihr Gerät rooten und die Checkbox unten aktivieren. Alternativ laden Sie sich diese Anwendung von F-Droid oder meiner Webseite herunter. In diesen Versionen bin ich nicht gezwungen, die Anwendungen auf die neuesten API Level zu unterstützen.</string>
<string name="runExecutableExplanation">Sie können ein Script oder eine andere ausführbare Datei auswählen, die dann als Aktion ausgeführt wird.\n\nAllerdings gibt es ein paar Voraussetzungen, um die Sie sich selbst kümmern müssen. Google hat es sehr schwer gemacht, irgendetwas außer normalen Android Anwendungen auszuführen.\n\n1.\nDie Datei muß im Dateisystem als ausführbar markiert sein. Auf einem normalen Android-System (ohne Root) ist das in der Tat der schwierigste Teil.\n\n2.\nDas bedeutet auch, daß auch Automation in der Lage sein muß, die Datei auszuführen, nicht nur der Besitzer oder die Gruppe.\n\n3.\nWenn es ein Script ist, muß eine gültige Shell im Header des Scripts definiert sein.</string>
</resources>

View File

@ -127,10 +127,10 @@
<string name="actionTurnWifiTetheringOff">desactivar enrutador wifi</string>
<string name="actionTurnAirplaneModeOn">encender modo de vuelo</string>
<string name="actionTurnAirplaneModeOff">desactivar modo de vuelo</string>
<string name="activePoi">sitio activo</string>
<string name="activePoi">Sitio activo:</string>
<string name="closestPoi">sitio mas cerca</string>
<string name="poi">Posición</string>
<string name="pois">posiciónes</string>
<string name="pois">Posiciones</string>
<string name="serviceNotRunning">Servicio no está activo</string>
<string name="general">General</string>
<string name="startServiceAfterAppUpdate">Encender servicio después de un update si estuvo activado.</string>
@ -294,7 +294,7 @@
<string name="parameterValue">Valor del parámetro</string>
<string name="addIntentValue">Añadir pareja intento</string>
<string name="parameterType">Tipo del parámetro</string>
<string name="phoneNumberExplanation">Puedes introducir un número, pero es opciónal. Si quieres usar uno puedes elegir uno de su directorio o introducir uno manualmente. Adiciónalmente puedes usar expresiónes regulares. Para probar esos me gusta la pagina:</string>
<string name="phoneNumberExplanation">Puedes introducir un número remoto, pero es opciónal. Si quieres usar uno puedes elegir uno de su directorio o introducir uno manualmente. Adiciónalmente puedes usar expresiónes regulares. Para probar esos me gusta la pagina:</string>
<string name="screenRotationEnabled">Rotación del monitor activado.</string>
<string name="screenRotationDisabled">Rotación del monitor desactivado.</string>
<string name="noPoisDefinedShort">No hay sitios.</string>
@ -700,4 +700,26 @@
<string name="profileXrequiresThis">El perfil \"%1$s\" requiere esto.</string>
<string name="lastProfile">Último perfil:</string>
<string name="queryAllPackages">Obtener una lista de las aplicaciones instaladas</string>
<string name="timeFrameDaysHint">Si utiliza un marco de tiempo que se extiende más allá de la medianoche, también debe seleccionar el día siguiente si desea que la condición se aplique después de la medianoche.</string>
<string name="featureNotInGooglePlayVersion">Esta función ya no está disponible en la versión de Google Play.\n\nTodo de vez en cuando Google intimida a los desarrolladores. Si desea seguir utilizando ciertas funciones, debe presentar documentos. Desafortunadamente, hay un 99% de posibilidades de que el papeleo sea rechazado. Es más o menos como en el cómic/la película de Astérix.\n\nHe pasado semanas discutiendo con ellos sobre casos como ese en el pasado, pero seguí recibiendo rechazos, ya sea por bots o personas que son tan inteligentes como los bots. En el puedo decidir entre que la aplicación se elimine de Play Store por completo o eliminar la función.\n\nPor favor, considere usar la versión APK de mi sitio web o la de F-Droid si necesita esas características.</string>
<string name="startActivityInsertManually">Esta limitación se refiere solo a la selección de una aplicación, no al inicio real. Por lo tanto, aún puede ingresar el nombre de una aplicación manualmente si lo conoce.</string>
<string name="deviceStarts">Dispositivo esta enciendo</string>
<string name="serviceStarts">Servicio esta enciendo</string>
<string name="deviceHasJustStarted">el dispositivo justamente ha encendido</string>
<string name="serviceHasJustStarted">el servicio justamente ha encendido</string>
<string name="emailPretext">Si tiene un problema, sugerencia o pregunta, escriba algo en el correo electrónico. No solo envíeme los archivos con el cuerpo de correo predeterminado. Ignoraré todo eso a menos que ya estemos en una conversación.</string>
<string name="lockedCommentScreenMustBeOff">Cualquier estado de bloqueo solo se detectará si la pantalla está apagada.</string>
<string name="lockedWithSecurity">bloqueado (con PIN, etc.)</string>
<string name="lockedWithoutSecurity">bloqueado (solo deslizar, sin PIN)</string>
<string name="selectBroadcast">Seleccionar broadcast</string>
<string name="broadcastsShowSuggestions">Mostrar sugerencias</string>
<string name="broadcastReceivedTitle">Broadcast recibido</string>
<string name="broadcastReceived">broadcast recibido</string>
<string name="broadcastNotReceived">broadcast no recibido</string>
<string name="broadcastExplanation">Esta acción permite enviar una transmisión a través del sistema de mensajes de Android. Esto no es visible para el usuario, pero las aplicaciones que se han registrado para ciertas transmisiones pueden responder a ello.</string>
<string name="sendBroadcast">Enviar broadcast</string>
<string name="enterBroadcast">Introduzca una acción de broadcast.</string>
<string name="explanationBroadcastTrigger">La mayoría de los eventos en su teléfono se \"publicado\" transmitiéndolos a través del sistema operativo.\nPor ejemplo, activar / desactivar el modo avión activará dicha transmisión. Esas transmisiones no son automáticamente visibles / audibles, pero si una aplicación (como Automatización) está interesada, puede conectarse a ellas. Cuando ocurran, se le notificará y podrá reaccionar.\n\nPuede definir aquí un evento de difusión para el que la aplicación esperará. Puede ingresarlo manualmente, copiarlo y pegarlo desde algún lugar o elegir uno de la lista de sugerencias. Como este desencadenante está destinado a ser y seguir siendo muy flexible, no puedo proporcionarle explicaciones para los elementos.\n\nLa lista de sugerencias no pretende estar completa. Visite la siguiente URL para echar un vistazo a la documentación de Android.\nTambién cualquier aplicación puede enviar eventos personalizados que no aparecerán en la documentación de Android, por supuesto.\n\nMuchas transmisiones requieren permisos específicos para funcionar. Intento solicitar permisos donde sé que serán necesarios. Si cree que se requiere un permiso para la acción que ingresó, hágamelo saber.\n\nNo recibido significa que no ha habido tal transmisión desde que se inició el servicio. Responder a ciertos parámetros está en desarrollo.</string>
<string name="logsExplanation">Para evitar el uso innecesario del almacenamiento, los registros no se guardan de forma predeterminada. Entonces, si tiene un problema, active primero la configuración de inicio de sesión y establezca el nivel de registro en 5. A continuación, reproduzca el problema. Solo entonces se pueden adjuntar registros.</string>
<string name="directionStringDoesNotContain">no contiene</string>
</resources>

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<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">È avvenuto un errore durante l\'esportazione della configurazione.</string>
<string name="accelerometer">Accelerometro</string>
<string name="accelerometerThreshold">Soglia accelerometro</string>
<string name="accelerometerThresholdDescription">Soglia per i movimenti dell\'accelerometro</string>
<string name="accelerometerTimer">Usa l\'accelerometro dopo x minuti senza lunghi cambiamenti delripetitore</string>
<string name="accelerometerTimer">Usa l\'accelerometro dopo x minuti senza lunghi cambiamenti del ripetitore</string>
<string name="actionChangeSoundProfile">Cambia il profilo sonoro</string>
<string name="actionDataConnection">Connessione dati mobile</string>
<string name="actionDataConnection">Connessione dati</string>
<string name="actionDisableScreenRotation">disabilita la rotazione dello schermo</string>
<string name="actionEnableScreenRotation">abilita la rotazione dello schermo</string>
<string name="actionPlayMusic">Apri il lettore musicale</string>
<string name="actionSetBluetooth">Bluetooth</string>
<string name="actionSetDataConnectionOff">disattiva la connessione mobile</string>
<string name="actionSetDataConnectionOn">attiva la connessione mobile</string>
<string name="actionSetDataConnectionOff">disattiva la connessione dati</string>
<string name="actionSetDataConnectionOn">attiva la connessione dati</string>
<string name="actionSetDisplayRotation">Rotazione dello schermo</string>
<string name="actionSetUsbTethering">USB Tethering</string>
<string name="actionSetUsbTethering">Tethering USB</string>
<string name="actionSetWifi">Wifi</string>
<string name="actionSetWifiTethering">Wifi Tethering</string>
<string name="actionSetWifiTethering">Tethering Wifi</string>
<string name="actionSpeakText">Pronuncia testo</string>
<string name="actionTriggerUrl">Apri indirizzo</string>
<string name="actionTurnAirplaneModeOff">termina la modalità aereo</string>
<string name="actionTurnAirplaneModeOn">passa a modalità aereo</string>
<string name="actionTurnAirplaneModeOff">disattiva modalità aereo</string>
<string name="actionTurnAirplaneModeOn">attiva modalità aereo</string>
<string name="actionTurnBluetoothOff">disattiva Bluetooth</string>
<string name="actionTurnBluetoothOn">attiva Bluetooth</string>
<string name="actionTurnUsbTetheringOff">disattiva Tethering USB</string>
@ -29,20 +29,20 @@
<string name="actionTurnWifiOn">attiva Wifi</string>
<string name="actionTurnWifiTetheringOff">disattiva Tethering Wifi</string>
<string name="actionTurnWifiTetheringOn">attiva Tethering Wifi</string>
<string name="actions">Azione(i)</string>
<string name="actions">Azione/i</string>
<string name="actionsComment">(saranno eseguite in quest\'ordine)</string>
<string name="activate">Attiva</string>
<string name="activated">attivo</string>
<string name="activating">Sto attivando</string>
<string name="activated">attivato</string>
<string name="activating">Attivazione in corso</string>
<string name="activePoi">Posizione attiva:</string>
<string name="activityDetection">Rilevamento dell\'attività</string>
<string name="activityDetectionFrequencySummary">Secondi tra i tentativi di rilevamento dell\'attività.</string>
<string name="activityDetectionFrequencyTitle">Frequenza di rilevamento [sec]</string>
<string name="activityDetectionRequiredProbabilitySummary">Attendibilità alla quale esecuzione delle attività è considerata corretta.</string>
<string name="activityDetectionRequiredProbabilitySummary">Attendibilità minima per considerare le attività corrette.</string>
<string name="activityDetectionRequiredProbabilityTitle">Probabilità di rilevamento dell\'attività</string>
<string name="activityOrActionName">Nome attività/azione</string>
<string name="addAction">Aggiungi azione</string>
<string name="addIntentValue">Aggiungi una coppia di intenzioni</string>
<string name="addIntentValue">Aggiungi coppia dell\'Intent</string>
<string name="addParameters">Aggiungi parametri</string>
<string name="addPoi">Aggiungi posizione</string>
<string name="addProfile">Aggiungi profilo</string>
@ -59,37 +59,37 @@
<string name="android.permission.ACCESS_NOTIFICATION_POLICY">Ignora la politica di "non disturbare"</string>
<string name="android.permission.ACCESS_WIFI_STATE">Leggi lo stato della rete wifi</string>
<string name="android.permission.ACTIVITY_RECOGNITION">Identificazione attività</string>
<string name="android.permission.BATTERY_STATS">Leggere lo stato della batteria</string>
<string name="android.permission.BATTERY_STATS">Leggi lo stato della batteria</string>
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leggere le notifiche di sistema</string>
<string name="android.permission.BLUETOOTH">Cambia le impostazioni Bluetooth</string>
<string name="android.permission.BLUETOOTH_ADMIN">Cambia le impostazioni Bluetooth</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Cambia la connessione dati</string>
<string name="android.permission.BLUETOOTH">Modifica le impostazioni Bluetooth</string>
<string name="android.permission.BLUETOOTH_ADMIN">Modifica le impostazioni Bluetooth</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Modifica la connessione dati</string>
<string name="android.permission.GET_TASKS">Rileva i processi attivi</string>
<string name="android.permission.INTERNET">Invia dati su una connessione di rete</string>
<string name="android.permission.MODIFY_AUDIO_SETTINGS">Cambia le impostazioni audio</string>
<string name="android.permission.MODIFY_PHONE_STATE">Cambia le impostazioni del dispositivo</string>
<string name="android.permission.MODIFY_AUDIO_SETTINGS">Modifica le impostazioni audio</string>
<string name="android.permission.MODIFY_PHONE_STATE">Modifica le impostazioni del dispositivo</string>
<string name="android.permission.NFC">Usa il modulo NFC</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Rileva chiamate in uscita</string>
<string name="android.permission.READ_CALENDAR">Leggere gli appuntamenti dal calendario</string>
<string name="android.permission.READ_CALL_LOG">Leggere il registro chiamate</string>
<string name="android.permission.READ_CONTACTS">Leggere informazioni dai Contatti</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Leggere la memoria esterna</string>
<string name="android.permission.READ_CALENDAR">Leggi dal calendario</string>
<string name="android.permission.READ_CALL_LOG">Leggi il registro chiamate</string>
<string name="android.permission.READ_CONTACTS">Leggi informazioni dai contatti</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Leggi dalla memoria esterna</string>
<string name="android.permission.READ_PHONE_STATE">Rileva lo stato del telefono</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Rileva riavvio del dispositivo</string>
<string name="android.permission.RECORD_AUDIO">Registra audio</string>
<string name="android.permission.SEND_SMS">Invia messaggio di testo</string>
<string name="android.permission.VIBRATE">Attiva vibrazione</string>
<string name="android.permission.WAKE_LOCK">Mantienere attivo il dispositivo</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Scrive sulla SD</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Cambia le impostazioni del dispositivo</string>
<string name="android.permission.WRITE_SETTINGS">Cambia le impostazioni del dispositivo</string>
<string name="android10WifiToggleNotice">Sfortunatamente, Google ha deciso di rimuovere questa funzione in Android 10. Applicazioni normali non hanno più accesso alla accensione o spegnimento della connessione wifi on. Questo significa che questa azione non avrà effetto su questo dispositivo.</string>
<string name="android9RecordAudioNotice">Se si sta usando il livello di rumore come evento di attivazione: sfortunatamente, a partire da Android 9 (Pie), Google ha deciso di non permettere l\'accesso al microfono da parte di applicazioni attive in secondo piano. Pertanto questo evento non ha più effetto e non attiverà nessuna azione.</string>
<string name="anotherAppIsRunning">Si è avviata/fermata un\'altra app</string>
<string name="android.permission.VIBRATE">Fa vibrare il telefono</string>
<string name="android.permission.WAKE_LOCK">Mantieni attivo il dispositivo</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Scrivi nella memoria esterna</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Modifica le impostazioni del dispositivo</string>
<string name="android.permission.WRITE_SETTINGS">Modifica le impostazioni del dispositivo</string>
<string name="android10WifiToggleNotice">Purtroppo Google ha deciso di rimuovere questa funzione in Android 10. Le applicazioni normali non hanno più accesso ad attivazione o disattivazione della connessione wifi, perciò questa azione non avrà effetto su questo dispositivo.</string>
<string name="android9RecordAudioNotice">Se si sta usando il livello di rumore come evento di attivazione: purtroppo, a partire da Android 9 (Pie), Google ha deciso di non permettere l\'accesso al microfono da parte di applicazioni attive in secondo piano. Pertanto questo evento non ha più effetto e non attiverà nessuna azione.</string>
<string name="anotherAppIsRunning">È stata avviata/fermata un\'altra app</string>
<string name="anotherPoiByThatName">Nome già usato per un\'altra posizione.</string>
<string name="anotherProfileByThatName">Nome già usato per un altro profilo.</string>
<string name="anotherRuleByThatName">Nome già usato per un\'altra regola.</string>
<string name="any">qualsiaisi</string>
<string name="any">qualsiasi</string>
<string name="anyApp">Qualsiasi applicazione</string>
<string name="anyDevice">qualsiasi dispositivo</string>
<string name="anyLocation">qualsiasi posizione</string>
@ -101,21 +101,21 @@
<string name="areYouSure">Sei sicuro?</string>
<string name="at">al</string>
<string name="audibleSelection">Audio abilitato quando si seleziona lo schermo</string>
<string name="autoBrightness">Abilitare luminosità automatica</string>
<string name="autoBrightnessNotice">Se usi la luminosità automatica, il valore di luminosità scelto a seguito non sarà probabilmente in use per molto.</string>
<string name="batteryLevel">livello della batteria</string>
<string name="autoBrightness">Attiva luminosità automatica</string>
<string name="autoBrightnessNotice">Se usi la luminosità automatica, il valore di luminosità scelto in seguito probabilmente non sarà in uso per molto.</string>
<string name="batteryLevel">Livello della batteria</string>
<string name="bluetoothConnection">Connessione Bluetooth</string>
<string name="bluetoothConnectionTo">Connessione Bluetooth con %1$s</string>
<string name="bluetoothDeviceInRange">Dispositivo Bluetooth %1$s rilevato.</string>
<string name="bluetoothDeviceOutOfRange">Dispositivo Bluetooth %1$s non raggiungibile.</string>
<string name="bluetoothDisconnectFrom">Connessione Bluetooth con %1$s interrotta</string>
<string name="bluetoothFailed">Impossibile attivare il Bluetooth. Questo dispositivo è dotato di Bluetooth?</string>
<string name="bluetoothFailed">Impossibile attivare il Bluetooth. Questo dispositivo ne è dotato?</string>
<string name="brightnessAuto">luminosità automatica</string>
<string name="brightnessManual">luminosità manuale</string>
<string name="cancel">Annulla</string>
<string name="cantFindSoundFile">Impossibile trovate il file audio %1$s e riprodurlo.</string>
<string name="cantMoveDown">Non posso spostare giù l\'elemento. E\' già l\'ultimo.</string>
<string name="cantMoveUp">Non posso spostare su l\'elemento. E\' già il primo.</string>
<string name="cantMoveDown">Impossibile spostare in basso l\'elemento, è già l\'ultimo.</string>
<string name="cantMoveUp">Non posso spostare in alto l\'elemento, è già il primo.</string>
<string name="cantRunRule">Impossibile eseguire le regole.</string>
<string name="cantStopIt">Non posso fermarla.</string>
<string name="cellMastIdleTime">Massimo tempo di inattività del ripetitore</string>
@ -124,25 +124,25 @@
<string name="clickAndHoldForOptions">Clicca e mantieni premuto un elemento per vedere le opzioni.</string>
<string name="closeTo">vicino a</string>
<string name="closestPoi">Posizione più vicina:</string>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controllare i tunnels dell\'applicazione wireguard</string>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlla i tunnel dell\'applicazione wireguard</string>
<string name="configurationExportedSuccessfully">Configurazione esportata con successo.</string>
<string name="configurationImportedSuccessfully">Configurazione esportata con successo.</string>
<string name="configurationImportedSuccessfully">Configurazione importata con successo.</string>
<string name="connected">connesso</string>
<string name="connectedToWifi">connesso al wifi \"%1$s</string>
<string name="connectedToWifi">connesso al wifi \"%1$s\"</string>
<string name="connecting">connessione in corso</string>
<string name="connectionToDevice">connessione al dispositivo</string>
<string name="continueText">continua</string>
<string name="currentId">ID corrente:</string>
<string name="currentId">ID attuale:</string>
<string name="currentVolume">Volume attuale</string>
<string name="deactivate">Disattivazione</string>
<string name="deactivated">non attivo</string>
<string name="deactivate">Disattiva</string>
<string name="deactivated">disattivato</string>
<string name="deactivating">Disattivazione in corso</string>
<string name="defaultSettings">Ripristino impostazioni di default</string>
<string name="delete">rimuovi</string>
<string name="deleteCapital">Rimuovi</string>
<string name="deletePoi">Cancella posizione</string>
<string name="detectedActivity">Attività rilevata:</string>
<string name="detectedActivityInVehicle">In un veicolo (auto, bus,...)</string>
<string name="detectedActivityInVehicle">In un veicolo (auto, bus,)</string>
<string name="detectedActivityInvalidStatus">Attività non valida</string>
<string name="detectedActivityOnBicycle">In bicicletta</string>
<string name="detectedActivityOnFoot">A piedi</string>
@ -151,8 +151,8 @@
<string name="detectedActivityTilting">Ribaltando</string>
<string name="detectedActivityUnknown">Sconosciuto</string>
<string name="detectedActivityWalking">Camminando</string>
<string name="deviceDoesNotHaveBluetooth">Questo dispositivo non sembra avere bluetooth. Puoi comunque configurare questa opzione, ma non avrà probabilmente nessun effetto.</string>
<string name="deviceDoesNotHaveNfc">Sembra che il dispositivo non abbia la funzione NFC.</string>
<string name="deviceDoesNotHaveBluetooth">Questo dispositivo sembra non disporre del Bluetooth. Si può comunque configurare questa opzione, ma probabilmente senza alcun risultato.</string>
<string name="deviceDoesNotHaveNfc">Sembra che il dispositivo non disponga del NFC.</string>
<string name="deviceInRange">dispositivo visibile</string>
<string name="deviceOutOfRange">dispositivo fuori portata</string>
<string name="direction">Direzione</string>
@ -163,71 +163,71 @@
<string name="directionStringStartsWith">comincia con</string>
<string name="disabledFeatures">Funzioni disabilitate</string>
<string name="disconnected">disconnesso</string>
<string name="disconnectedFromWifi">disconnesso dalla rete wifi \"%1$s</string>
<string name="disconnectedFromWifi">disconnesso dalla rete wifi \"%1$s\"</string>
<string name="disconnecting">disconnessione in corso</string>
<string name="disconnectionFromDevice">disconnesso dal dispositivo</string>
<string name="displayNewsOnMainScreen">Visualizza le novità dell\'applicazione sullo schermo principale</string>
<string name="displayNewsOnMainScreenDescription">Novità relative solo a questa applicazione, stiamo parlando di un paio per anno, non di più.</string>
<string name="displayNewsOnMainScreenDescription">Novità relative solo a questa applicazione, saranno un paio ogni anno, non di più.</string>
<string name="distanceBetween">La distanza tra la posizione GPS e la posizione di rete è di %1$d metri. Il raggio minimo è +1 metro.</string>
<string name="distanceForGpsUpdate">Distanza per l\'aggiornamento del GPS [m]</string>
<string name="distanceForNetworkUpdate">Distanza per l\'aggiornamento della rete [m]</string>
<string name="droppingBelow">sta andando sotto</string>
<string name="dropsBelow">inferiore</string>
<string name="droppingBelow">sta scendendo</string>
<string name="dropsBelow">scende sotto</string>
<string name="edit">Modifica</string>
<string name="end">Fine</string>
<string name="enterAPositiveValidNonDecimalNumber">Inserisci un numero intero positivo</string>
<string name="enterAname">Inserisci un nome.</string>
<string name="enterNameForIntentPair">Definisci un nome per la coppia di intenzioni</string>
<string name="enterNameForIntentPair">Definisci un nome per la coppia dell\'Intent</string>
<string name="enterPackageName">Inserisci un nome di pacchetto che sia valido.</string>
<string name="enterPhoneNumber">Inserisci un numero di telefono. Lascia vuoto per accettare qualsiasi numero.</string>
<string name="enterValidAction">Inserisci una azione valida</string>
<string name="enterValidReferenceValue">Inserisci un valore di riferimento valido.</string>
<string name="enterValueForIntentPair">Definisci un valore per la coppia di Intenzioni.</string>
<string name="enterWifiName">Inserire un nome per la wifi. Se vuoto sarà valido per qualsiasi wifi.</string>
<string name="enterValueForIntentPair">Definisci un valore per la coppia dell\'Intent.</string>
<string name="enterWifiName">Inserisci un nome per la rete wifi. Se vuoto sarà valido per qualsiasi wifi.</string>
<string name="entering">entrando in</string>
<string name="eraseSettings">Azzera le impostazioni</string>
<string name="error">Errore</string>
<string name="errorActivatingProfile">Errore nell\'attivazione del profilo:</string>
<string name="errorReadingPoisAndRulesFromFile">Errore nella lettura di regole e posizioni dal file.</string>
<string name="errorRunningRule">C\'è stato un errore cercando di eseguire una regola.</string>
<string name="errorStartingOtherActivity">Errore nel\'avvio dell\'altra attività</string>
<string name="errorRunningRule">È avvenuto un errore durante il tentativo di eseguire di una regola.</string>
<string name="errorStartingOtherActivity">Errore nell\'avvio dell\'altra attività</string>
<string name="errorWritingConfig">Errore nello scrivere la configurazione. È la memoria in sola lettura?</string>
<string name="errorWritingFile">Errore nella scrittura delle impostazioni.</string>
<string name="exceeding">sta sorpassando</string>
<string name="exceeds">è superiore</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Esegui regole/profili con un singolo click.</string>
<string name="exportConfiguration">Esporta la configurazione</string>
<string name="failedToTriggerBluetooth">Non riesco ad attivare il Bluetooth. Questo dispositivo ha il Bluetooth?</string>
<string name="featureNotInFdroidVersion">Questa funzione sfrutta software non basato su codice aperto. Pertanto non è disponibile nella versione F-Droid.</string>
<string name="exceeding">sta superando</string>
<string name="exceeds">supera</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Esegui regole/profili con un click.</string>
<string name="exportConfiguration">Esporta configurazione</string>
<string name="failedToTriggerBluetooth">Non riesco ad attivare il Bluetooth. Questo dispositivo ne dispone?</string>
<string name="featureNotInFdroidVersion">Questa funzione sfrutta software basato su codice non libero, pertanto non è disponibile nella versione F-Droid.</string>
<string name="featuresDisabled">L\'applicazione è in esecuzione in modalità limitata a causa di autorizzazioni mancanti.</string>
<string name="fileDoesNotExist">Il file non esiste.</string>
<string name="filesHaveBeenMovedTo">Automation usa adesso un percorso nuovo per salvare i tuoi files. Tutti i files di Automation sono stati mossi qui: \"%s\". I permessi di accesso alla memoria esterna non sono più necessari e si possono revocare. Questo verrà permanentemente rimosso in una versione futura.</string>
<string name="filesStoredAt">I files di configurazione e log sono salvati nella cartella %1$s. Clicca su questo testo per aprire l\'esploratore di files. Sfortunatamente, questo solo funziona su un dispositivo con accesso root.\n\nPER TUTTI GLI ALTRI DISPOSITIVI: basta usare il bottone \'esporta\' per fare un backup.</string>
<string name="filesHaveBeenMovedTo">Automation usa adesso un percorso nuovo per salvare i tuoi file. Tutti i file di Automation sono stati mossi qui: \"%s\". I permessi di accesso alla memoria esterna non sono più necessari e si possono revocare. Questo verrà permanentemente rimosso in una versione futura.</string>
<string name="filesStoredAt">I file di configurazione e log sono salvati nella cartella %1$s. Clicca su questo testo per aprire l\'esploratore di file. Sfortunatamente, questo solo funziona su un dispositivo con accesso root.\n\nPER TUTTI GLI ALTRI DISPOSITIVI: basta usare il bottone \'esporta\' per fare un backup.</string>
<string name="friday">Venerdì</string>
<string name="from">da</string>
<string name="general">Generale</string>
<string name="generalSettings">Impostazioni globali</string>
<string name="generalText">Per utilizzare questo programma è necessario impostare delle regole. Le regole contengono eventi, per esempio l\'arrivare in una determinata zona o essere in un intervallo temporale. Dopo che è stato fatto, fare clic sul pulsante ON / OFF nella home-page.</string>
<string name="generalSettings">Impostazioni generali</string>
<string name="generalText">Per utilizzare questo programma è necessario impostare delle regole. Le regole contengono eventi, per esempio l\'arrivare in una determinata zona o essere in un intervallo temporale. Dopo che è stato fatto, fare clic sul pulsante ON/OFF nella home-page.</string>
<string name="getCurrentPosition">Rileva la posizione attuale</string>
<string name="gettingListOfInstalledApplications">Sto cercando le applicazioni installate … </string>
<string name="gettingPosition">Sto rilevando la posizione. Attendere prego ...</string>
<string name="gettingListOfInstalledApplications">Ottenimento della lista delle applicazioni installate in corso</string>
<string name="gettingPosition">Sto rilevando la posizione. Attendere prego</string>
<string name="googleLocationChicanery">Questa applicazione accumula dati di localizzazione per abilitare regole basate sulla posizione insieme al rilevamento della velocità anche quando l\'applicazione è chiusa o non in uso.</string>
<string name="googleLocationChicaneryOld">Questa applicazione accumula dati di localizzazione per determinare se sei attualmente ad una delle posizioni che hai creato. Inoltre, questa funzione è usata per determinare la tua velocità attuale se tale evento è stato attivato nelle regole. Questi rilevamenti sono effettuati anche quando l\'applicazione è chiusa o non in uso (ma solo se il servizio è attivato).</string>
<string name="googleSarcasm">Grazie alla infinita sapienza di Google e continui sforzi per proteggere la nostra privacy, nelle regole che possano inviare SMS o coinvolgere lo stato del telefono, sono state rimossi eventi ed azioni rilevanti.</string>
<string name="gpsAccuracy">Precisone del GPS [m]</string>
<string name="gpsComparison">Comparazione GPS</string>
<string name="hapticFeedback">Sensazione tattile (vibrazione al tocco)</string>
<string name="headphoneAny">Oppure</string>
<string name="googleSarcasm">Grazie alla infinita sapienza di Google e i suoi continui sforzi per proteggere la nostra privacy, nelle regole che possano inviare SMS o coinvolgere lo stato del telefono, sono state rimossi eventi ed azioni rilevanti.</string>
<string name="gpsAccuracy">Precisione del GPS [m]</string>
<string name="gpsComparison">Confronto del GPS</string>
<string name="hapticFeedback">Riscontro tattile (vibra al tocco)</string>
<string name="headphoneAny">Uno dei due</string>
<string name="headphoneMicrophone">Microfono</string>
<string name="headphoneSelectType">Seleziona il tipo di auricolare</string>
<string name="headphoneSimple">Auricolari</string>
<string name="headsetConnected">Connesso auricolare (tipo: %1$s) </string>
<string name="headsetDisconnected">Disconnesso auticolari (tipo: %1$s) </string>
<string name="headsetConnected">"Connessi auricolari (tipo: %1$s) "</string>
<string name="headsetDisconnected">"Disconnessi auricolari (tipo: %1$s) "</string>
<string name="helpTextActivityDetection">Questa funzione può identificare se sei attualmente in movimento e se sei a piedi o in che tipo di veicolo (almeno con una certa precisione). Questa funzione non è completamente integrata con Automation, ma viene fornita dai servizi di Google Play. In pratica, non fornisce un risultato si/no, ma provvede una percentuale del livello di sicurezza dello stato di movimento identificato. Puoi scegliere la percentuale raggiunta la quale Automation accetterà un resultato. Nota: 1) è possibile che più di uno stato sia identificato nello stesso momento. Per esempio, potresti star CAMMINANDO dentro a un bus in movimento; 2) Questo sensore ha bisogno di molte risorse di sistema. Se possibile, potresti considerare delle alternative, per esempio, potresti identificare che stai guidando, forzando una connessione con il vivavoce.</string>
<string name="helpTextEnergySaving">Molti produttori di dispositive Android cercano di salvare energia limitando le attività di applicazioni eseguite in secondo piano. Sfortunatamente, questo spesso fa che tali applicazioni non funzionino correttamente e Automation è fra queste. Puoi leggere questa <a href="https://dontkillmyapp.com/">pagina web</a> per scoprire come escludere Automation da queste funzioni di risparmio energetico.</string>
<string name="helpTextPoi">Una posizione è composta da cooridinate GPS ed un raggio d\'azione. Dato che il posizionamento realizzato tramite i ripetitori del tuo gestore è piuttosto impreciso (ma veloce e consuma poca batteria), è bene non specificare un raggio troppo piccolo. L\'applicazione suggerisce un raggio minimo quando si crea una nuova posizione.</string>
<string name="helpTextPoi">Una posizione è composta da coordinate GPS ed un raggio d\'azione. Dato che il posizionamento realizzato tramite i ripetitori del tuo gestore è piuttosto impreciso (ma veloce e consuma poca batteria), è bene non specificare un raggio troppo piccolo. L\'applicazione suggerisce un raggio minimo quando si crea una nuova posizione.</string>
<string name="helpTextProcessMonitoring">Se si specifica una regola che controlli l\'esecuzione di un processo, Automation eseguirà la verifica ogni x secondi (con x selezionabile nelle impostazioni). Bisogna considerare che un monitoraggio costante provocherebbe un rapido esaurimento della batteria e non esistono notifiche di questo tipo di attività proviste dal sistema operativo.</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="helpTextRules">Gli eventi di attivazione sono in AND logico. La regola sarà eseguita solo se tutti gli eventi sono soddisfatti. Per l\'OR logico basta creare un\'altra regola.</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="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>
@ -242,15 +242,15 @@
<string name="httpAttemptsTimeoutTitle">Timeout [sec]</string>
<string name="httpAttemptsTitle">Numero di tentativi HTTP</string>
<string name="importConfiguration">Importa configurazione</string>
<string name="importExportExplanation">Quando si clicca su importa o esporta, stai scegliendo la direzione in cui i files vengono importati o esportati. Quando si procede alla esportazione, files esistenti potrebbero essere sovrascritti.</string>
<string name="importExportExplanation">Quando si clicca su importa o esporta, stai scegliendo la direzione in cui i file vengono importati o esportati. Quando si procede alla esportazione, file esistenti potrebbero essere sovrascritti.</string>
<string name="importNumberFromContacts">Importa numero dai contatti</string>
<string name="incoming">in arrivo</string>
<string name="incomingAdjective">in arrivo</string>
<string name="incomingCallFrom">Chiamata in arrivo da %1$s.</string>
<string name="incomingCallsRingtone">Suoneria per le chiamate in arrivo</string>
<string name="insideOrOutsideTimeFrames">Dentro o fuori questi intervalli?</string>
<string name="intentDataComment">Se il tuo parametro è di tipo Uri e usi \"IntentData\" come nome (in maiuscole o minuscole non importa), il parametro non verrà aggiunto come parametro normale con putExtra(), ma sarà aggiunto all\'intento con setData().</string>
<string name="invalidDevice">Dispositivo non valido.</string>
<string name="intentDataComment">Se il tuo parametro è di tipo Uri e usi \"IntentData\" come nome (in maiuscole o minuscole non importa), il parametro non verrà aggiunto come parametro normale con putExtra(), ma sarà aggiunto all\'Intent con setData().</string>
<string name="invalidDevice">Dispositivo non valido</string>
<string name="invalidPoiName">Nome posizione non valido.</string>
<string name="invalidProfileName">Nome profilo non valido.</string>
<string name="is">è</string>
@ -266,15 +266,15 @@
<string name="locationEngineDisabledLong">Purtroppo la tua posizione non può più essere determinata. Un debito di gratitudine è dovuto a Google per la sua infinita saggezza e amabilità.\\n\\nVediamo di approfondire questo problema. A partire da Android 10 è stato introdotto un nuovo permesso che è necessario per determinare la vostra posizione in secondo piano (che naturalmente è necessario per un\'app come questa). Sebbene la consideri una buona idea in generale, i problemi che comporta per gli sviluppatori non lo sono.\\n\\nWQuando si sviluppa un\'app si può cercare di qualificarsi per questo permesso rispettando un catalogo di requisiti. Purtroppo le nuove versioni della mia app sono state rifiutate per un periodo di tre mesi. Ho soddisfatto tutti questi requisiti, mentre il merdoso supporto allo sviluppo di Google ha affermato che non l\'ho fatto. Dopo aver dato loro la prova che l\'ho fatto - ho ottenuto una risposta del tipo \"non posso più aiutarti\". Alla fine mi sono arreso. \\n\\nDi conseguenza, la versione di Google Play non può più usare la tua posizione come trigger. La mia unica opzione alternativa sarebbe stata quella di avere questa applicazione rimossa dal negozio interamente.\\n\\nNe sono molto dispiaciuto, ma ho fatto del mio meglio per discutere con un \"supporto\" che ripetutamente non ha superato il test di Turing.\n\\nInfine, c\'è una buona notizia: puoi ancora avere tutto!\\n\\nAutomation è adesso una applicazione di codice aperto e si può trovare su F-Droid. Questo è un app store che si preoccupa davvero della tua privacy - invece che fingere di farlo. Basta fare il backup del tuo file di configurazione, disinstallare questa app, installarla di nuovo da F-Droid e ripristinare il tuo file di configurazione - fatto.\\n\\nClicca qui per maggiori informazioni:</string>
<string name="locationEngineDisabledShort">La localizzazione non può più essere determinata. Clicca qui per scoprirne il perché.</string>
<string name="locationEngineNotActive">Ricerca posizione non attiva.</string>
<string name="lockSoundChanges">Blocca il cambio dei suoni:</string>
<string name="logFileMaxSizeSummary">Massima dimensione del file di log in Megabyte. Tronca quando la dimensione eccede.</string>
<string name="lockSoundChanges">Blocca il cambio dei suoni</string>
<string name="logFileMaxSizeSummary">Massima dimensione del file di log in Megabyte. Tronca quando la dimensione eccede.</string>
<string name="logFileMaxSizeTitle">Massima dimensione del file di log [Mb]</string>
<string name="logLevelSummary">Dettaglio del file di Log (1=minimo, 5=massimo)</string>
<string name="logLevelSummary">Dettaglio del file di log (1=minimo, 5=massimo)</string>
<string name="logLevelTitle">Dettaglio del file di log</string>
<string name="logServiceStopping">Arrestando il servizio.</string>
<string name="logServiceStopping">Arresto del servizio in corso.</string>
<string name="longitude">Longitudine</string>
<string name="mainScreenPermissionNote">Automation richiede ulteriori autorizzazioni per funzionare correttamente. Clicca su questo testo per saperne di più e richiederle.</string>
<string name="manageLocations">Creare o modificare posizioni</string>
<string name="manageLocations">Crea o modifica posizioni</string>
<string name="matching">abbinando</string>
<string name="messageNotShownAgain">Questo messaggio non sarà mostrato più.</string>
<string name="minimumDistanceChangeForGpsLocationUpdates">Minimo intervallo (in metri) per aggiornare le posizioni GPS </string>
@ -283,24 +283,24 @@
<string name="monday">Lunedì</string>
<string name="moreSettings">Altre impostazioni</string>
<string name="moveDown">Sposta verso il basso</string>
<string name="moveUp">Sposta versol\'alto</string>
<string name="muteTextToSpeechDuringCallsSummary">Disabilitazione del TextToSpeach durante le chiamate</string>
<string name="muteTextToSpeechDuringCallsTitle">Silenziare durante le chiamate</string>
<string name="moveUp">Sposta verso l\'alto</string>
<string name="muteTextToSpeechDuringCallsSummary">Silenzia il TextToSpeach durante le chiamate</string>
<string name="muteTextToSpeechDuringCallsTitle">Silenzia durante le chiamate</string>
<string name="name">Nome</string>
<string name="needLocationPermForWifiList">L\'elenco delle wifi a cui il tuo dispositivo è stato connesso potrebbe essere usato per determinare i luoghi in cui sei stato. Questo è il motivo per cui il permesso di localizzazione è richiesto per caricare l\'elenco delle wifi. Se vuoi essere in grado di sceglierne una dalla lista devi concedere questo permesso. Altrimenti puoi ancora inserire il nome della tua wifi manualmente.</string>
<string name="needLocationPermForWifiList">L\'elenco delle reti wifi a cui il dispositivo è stato connesso potrebbe essere usato per determinare i luoghi in cui sei stato. Questo è il motivo per cui il permesso di localizzazione è richiesto per caricare l\'elenco delle wifi. Se vuoi essere in grado di sceglierne una dalla lista devi concedere questo permesso. Altrimenti puoi ancora inserire il nome della tua wifi manualmente.</string>
<string name="networkAccuracy">Precisione della rete [m]</string>
<string name="newId">Nuovo ID:</string>
<string name="newNfcId">Scrivi un nuovo ID NFC</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="nfcApplyTagToRule">Applicazione della etichetta alla regola</string>
<string name="nfcBringTagIntoRange">Portare una etichetta NFC nel campo d\'azione.</string>
<string name="nfcBringTagIntoRangeToRead">Avvicina la etichetta da leggere.</string>
<string name="nfcApplyTagToRule">Applica etichetta alla regola</string>
<string name="nfcBringTagIntoRange">Porta una etichetta NFC nel campo d\'azione.</string>
<string name="nfcBringTagIntoRangeToRead">Avvicina l\'etichetta da leggere.</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 Intent NFC NDEF, ma</string>
<string name="nfcNoTag">Nessuna etichetta rilevata.</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC non ancora supportato in questa versione di Android.</string>
<string name="nfcReadTag">Lettura ID dall\'etichetta</string>
<string name="nfcReadTag">Leggi ID dall\'etichetta</string>
<string name="nfcTag">Etichetta NFC</string>
<string name="nfcTagDataNotUsable">Dati dell\'etichetta non leggibili, si prega di riscriverli.</string>
<string name="nfcTagDiscovered">Etichetta rilevata</string>
@ -310,15 +310,15 @@
<string name="nfcTagWrittenSuccessfully">Scrittura dell\'etichetta eseguita con successo.</string>
<string name="nfcUnsupportedEncoding">Codifica non supportata:</string>
<string name="nfcValueNotSuitable">Valore memorizzato non adatto.</string>
<string name="nfcWriteTag">Scrittura etichetta</string>
<string name="nfcWriteTag">Scrivi etichetta</string>
<string name="no">No</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>
<string name="noDataChangedReadingAnyway">Sembra che non siano state salvate le modifiche. Tuttavia ci possono essere stati cambiamenti in memoria che devono essere rimossi. Devo ricaricare il file.</string>
<string name="noDevice">nessun dispositivo</string>
<string name="noFileManageInstalled">Nessun esploratore di files installato.</string>
<string name="noFileManageInstalled">Nessun esploratore di file installato.</string>
<string name="noFilesImported">Non è stato possibile importare nessun file.</string>
<string name="noKnownWifis">Non c\'è nessuna wifi conosciuta sul tuo dispositivo.</string>
<string name="noKnownWifis">Non c\'è nessuna rete wifi nota sul dispositivo.</string>
<string name="noMapsApplicationFound">Non trovo un navigatore installato.</string>
<string name="noPoisDefinedShort">Nessuna posizione indicata.</string>
<string name="noPoisSpecified">Non hai specificato nessuna posizione. È necessario.</string>
@ -329,8 +329,8 @@
<string name="none">nessuno</string>
<string name="notAllFilesImported">Non è stato possibile importare tutti i file rilevanti.</string>
<string name="notification">Notifica</string>
<string name="notificationAppears">La notifica appare</string>
<string name="notificationDisappears">La notifica non appare</string>
<string name="notificationAppears">La notifica compare</string>
<string name="notificationDisappears">La notifica scompare</string>
<string name="notificationRingtone">Tono di notifica</string>
<string name="notificationTriggerExplanation">Questo evento risponderà ad altre applicazioni che aprono notifiche nell\'area apposita (o che vengono chiuse). Puoi specificare un\'altra applicazione da cui la notifica deve provenire. Se non lo fai, saranno incluse le notifiche da qualsiasi altra applicazione. Puoi anche specificare le stringhe che devono o non devono essere presenti nel titolo o nel corpo della notifica. Il confronto fatto non è sensibile alle maiuscole e alle minuscole.</string>
<string name="number">numero</string>
@ -345,17 +345,17 @@
<string name="packageName">Nome del pacchetto</string>
<string name="parameterName">Nome parametro</string>
<string name="parameterType">Tipo parametro</string>
<string name="parameterValue">Valore</string>
<string name="parameterValue">Valore del parametro</string>
<string name="password">Password</string>
<string name="permissionsExplanation">Spiegazione delle autorizzazioni richieste</string>
<string name="permissionsExplanationGeneric">L\'applicazione si sta eseguendo in modalità limitata ed ha pertanto disattivato alcune funzioni. Per funzionare appieno richiede ulteriori permessi. Se vuoi utilizzare tutte le funzionalità è necessario concedere i permessi nelle successive finestre o alcune regole non potranno essere eseguite. Di seguito ti viene data una spiegazione dei permessi richiesti. Clicca su \"Continua\" quando sei pronto a procedere.</string>
<string name="permissionsExplanationGeneric">Si sta eseguendo l\'applicazione in modalità limitata, pertanto alcune funzioni sono disattivate. Per funzionare appieno richiede ulteriori permessi. Se vuoi utilizzare tutte le funzionalità, è necessario concedere i permessi nelle successive finestre altrimenti alcune regole non potranno essere eseguite. Di seguito ti viene data una spiegazione dei permessi richiesti. Clicca su \"Continua\" quando sei pronto a procedere.</string>
<string name="permissionsExplanationSmall">Per attivare la funzione che hai appena tentato di utilizzare, sono necessari ulteriori permessi. Clicca \"Continua\" per richiederli.</string>
<string name="permissionsTitle">Permessi necessari</string>
<string name="permissionsTitle">Sono necessari dei permessi</string>
<string name="phoneCall">Chiamata</string>
<string name="phoneDirection">Seleziona se\nentrante o uscente</string>
<string name="phoneNrReplacementError">Non ho l\'ultimo numero di telefono e quindi non posso inserirlo nella variabile.</string>
<string name="phoneNumber">Numero di telefono</string>
<string name="phoneNumberExplanation">È possibile inserire un numero di telefono specifico, ma non è necessario. Se vuoi specificarne uno, puoi sceglierlo dalla tua rubrica o inserirlo manualmente. Inoltre puoi usare espressioni regolari. Per testare un\'espressione regolare mi piace questa pagina:</string>
<string name="phoneNumberExplanation">È possibile inserire un numero di telefono specifico, ma non è obbligatorio. Se si vuole farlo, si può scegliere dalla rubrica o lo si può inserire manualmente. Si può anche usare un\'espressione regolare. Per testarle, mi piace questa pagina:</string>
<string name="playSound">Esegui suono</string>
<string name="pleaseEnterValidLatitude">Inserisci una latitudine valida.</string>
<string name="pleaseEnterValidLongitude">Inserisci una longitudine valida.</string>
@ -365,15 +365,15 @@
<string name="pleaseSpecifiyTrigger">Indica almeno un evento.</string>
<string name="poi">Posizione</string>
<string name="poiList">Elenco delle posizioni:</string>
<string name="poiStillReferenced">Ci sono ancora regole che fanno riferimento a questa posizione (%1$s). Quindi non posso cancellarla ancora.</string>
<string name="poiStillReferenced">Ci sono ancora regole che fanno riferimento a questa posizione (%1$s), per cui non posso ancora cancellarla.</string>
<string name="pois">Posizioni</string>
<string name="positioningEngine">Modulo di posizionamento</string>
<string name="positioningSettings">Impostazioni del posizionamento</string>
<string name="positioningThresholds">Soglie del posizionamento</string>
<string name="positioningWindowNotice">Se sei all\' interno di un edificio è fortemente consigliato avvicinarsi ad una finestra fino a quando è stata trovata una posizione. Diversamente la ricerca potrebbe richiedere molto tempo o non riuscire a trovare nulla.</string>
<string name="positioningWindowNotice">Se sei all\'interno di un edificio è fortemente consigliato avvicinarsi ad una finestra fino a quando è stata trovata una posizione. Diversamente la ricerca potrebbe richiedere molto tempo o non riuscire a trovare nulla.</string>
<string name="postsNotification">%1$s notifica dei messaggi</string>
<string name="prefsImportError">C\'è stato un errore nell\'importazione delle preferenze.</string>
<string name="privacy">Informativa sulla Privacy</string>
<string name="privacy">Informativa sulla privacy</string>
<string name="privacyConfirmationText">Sarai reindirizzato al sito dello sviluppatore per scaricare l\'informativa sulla privacy.</string>
<string name="privacyLocationingSummary">Evita i metodi di localizzazione che possono inviare la tua posizione a un provider, ad esempio Google. Userà solo il GPS e pertanto potrebbe essere lento o non funzionare correttamente.</string>
<string name="privacyLocationingTitle">Solo posizioni private</string>
@ -385,20 +385,20 @@
<string name="publishedOn">pubblicato il</string>
<string name="radiusHasToBePositive">Il raggio deve essere un numero positivo.</string>
<string name="radiusWithUnit">Raggio [m]</string>
<string name="readLocation">Legge la posizione</string>
<string name="readLocation">Leggi la posizione</string>
<string name="referenceValueForNoiseLevelMeasurementsSummary">Valore di riferimento fisico per la misura di rumore</string>
<string name="referenceValueForNoiseLevelMeasurementsTitle">Riferimento per la misura di rumore</string>
<string name="rememberLastActivePoiSummary">Se sei in una posizione, riavvia il tuo dispositivo o l\'applicazione e lascia la posizione. L\'applicazione eseguirà le regole associate alla uscita dal luogo al suo prossimo avvio.</string>
<string name="rememberLastActivePoiSummary">Se sei in una posizione, riavvia il tuo dispositivo o l\'applicazione e lascia la posizione. L\'applicazione eseguirà le regole associate all\'uscita dal luogo al suo prossimo avvio.</string>
<string name="rememberLastActivePoiTitle">Ricorda la ultima posizione attiva</string>
<string name="removedNotification">la notifica da %1$s rimossa</string>
<string name="ringing">squillando</string>
<string name="roaming">Roaming</string>
<string name="rootExplanation">È necessario avere permessi di root per utilizzare questa funzione. Una volta abilitato l\'accesso root, dovrai \"eseguire la regola manualmente\" per attivare la richiesta di autorizzazione come superuser. Quando la finestra di superuser appare, bisognerà autorizzare l\'applicazione a utilizzare superuser sempre. In caso contrario, la regola non potrà funzionare quando il telefono è inattivo.</string>
<string name="rootExplanation">È necessario avere i permessi di root per utilizzare questa funzione. Una volta abilitato l\'accesso root, dovrai \"eseguire la regola manualmente\" per attivare la richiesta di autorizzazione come superuser. Nella finestra di popup di superuser, bisognerà consentire sempre l\'esecuzione dell\'applicazione con questi permessi. In caso contrario, la regola non potrà funzionare quando il telefono è inattivo.</string>
<string name="rule">Regola</string>
<string name="ruleActivate">Attivando la regola %1$s</string>
<string name="ruleActivateToggle">Attivando la regola %1$s in modalità reversibile</string>
<string name="ruleActive">Regola attiva</string>
<string name="ruleHistory">Cronologia delle regole (dalla più recente):</string>
<string name="ruleHistory">Cronologia delle regole (dalla più recente):</string>
<string name="ruleLegend">Verde = abilitata, Rosso = disabilitata, Giallo = necessita ulteriori permessi</string>
<string name="ruleList">Elenco delle regole:</string>
<string name="ruleName">Nome della regola</string>
@ -408,12 +408,12 @@
<string name="rulesImportError">C\'è stato un errore nell\'importazione di regole e posizioni</string>
<string name="rulesImportedSuccessfully">Le regole e le posizioni sono state importate con successo.</string>
<string name="runManually">Esecuzione manuale</string>
<string name="satisfactoryAccuracyGps">Precisione minima in metri quando la posizione è individuata via GPS</string>
<string name="satisfactoryAccuracyNetwork">Precisione minima quando la localizzazione è effettuata in metri attraverso i ripetitori</string>
<string name="satisfactoryAccuracyGps">Precisione sufficiente in metri quando la posizione è individuata tramite GPS</string>
<string name="satisfactoryAccuracyNetwork">Precisione sufficiente quando la localizzazione è effettuata in metri attraverso i ripetitori</string>
<string name="saturday">Sabato</string>
<string name="save">Salva</string>
<string name="savePoi">Salva posizione</string>
<string name="saveRule">Salva Regola</string>
<string name="saveRule">Salva regola</string>
<string name="screenLockSoundNotice">I suoni di blocco dello schermo non possono più essere modificati automaticamente sui dispositivi con Android versione 6.0 o superiore. Qualunque cosa tu abbia impostato qui, non funzionerà in nessuna direzione.</string>
<string name="screenLockUnlockSound">Suono di blocco/sblocco schermo</string>
<string name="screenRotationAlreadyDisabled">Rotazione schermo già disattivata.</string>
@ -421,22 +421,22 @@
<string name="screenRotationDisabled">Rotazione schermo disabilitata.</string>
<string name="screenRotationEnabled">Rotazione schermo attivata.</string>
<string name="selectActivityToBeStarted">Seleziona l\'attività del pacchetto scelto</string>
<string name="selectApplication">Scegli App</string>
<string name="selectApplication">Scegli app</string>
<string name="selectBattery">Seleziona il livello di batteria</string>
<string name="selectConnectionOption">Seleziona una opzione di connessione.</string>
<string name="selectDeviceFromList">uno dalla lista</string>
<string name="selectDeviceOption">Seleziona una opzione di dispositivo</string>
<string name="selectDeviceOption">Seleziona una opzione di dispositivo.</string>
<string name="selectNoiseLevel">Seleziona il livello di rumore</string>
<string name="selectOneDay">Seleziona almeno un giorno</string>
<string name="selectPackageOfApplication">Seleziona il pacchetto dell\'applicazione</string>
<string name="selectPoi">Seleziona la posizione</string>
<string name="selectSoundFile">Select sound file</string>
<string name="selectSoundFile">Scegli file musicale</string>
<string name="selectSoundProfile">Seleziona il profilo audio</string>
<string name="selectSpeed">Seleziona la velocità</string>
<string name="selectToggleDirection">Seleziona acceso o spento?</string>
<string name="selectTypeOfAction">Seleziona il tipo di azione</string>
<string name="selectTypeOfActivity">Seleziona il tipo di attività</string>
<string name="selectTypeOfIntentPair">Seleziona il tipo per la coppia di Intenzioni</string>
<string name="selectTypeOfIntentPair">Seleziona il tipo per la coppia dell\'Intent</string>
<string name="selectTypeOfTrigger">Seleziona il tipo di evento</string>
<string name="sendTextMessage">Invia messaggio di testo</string>
<string name="service">Servizio:</string>
@ -444,9 +444,9 @@
<string name="serviceNotRunning">Servizio non attivo.</string>
<string name="serviceStarted">Il servizio di Automation è attivo.</string>
<string name="serviceStopped">Il servizio di Automation è stato fermato.</string>
<string name="serviceWontStart">Nessuna regola definita. Il servizio non può iniziare.</string>
<string name="setScreenBrightness">Impostare la luminosità dello schermo</string>
<string name="setScreenBrightnessEnterValue">Digitare la luminosità desiderata (da 0 a 100).</string>
<string name="serviceWontStart">Nessuna regola definita. Il servizio non può essere avviato.</string>
<string name="setScreenBrightness">Imposta la luminosità dello schermo</string>
<string name="setScreenBrightnessEnterValue">Inserisci la luminosità voluta (da 0 a 100).</string>
<string name="settings">Impostazioni</string>
<string name="settingsCategoryHttp">Richieste HTTP(s)</string>
<string name="settingsCategoryNoiseLevelMeasurements">Misura del livello di rumore</string>
@ -456,8 +456,8 @@
<string name="settingsSetToDefault">Impostazioni predefinite ripristinate.</string>
<string name="settingsWillTakeTime">Alcune impostazioni non saranno applicate prima che alcune impostazioni contestuali cambino o che il servizio venga riavviato.</string>
<string name="shareConfigAndLogExplanation">Questo creerà una email con la tua configurazione e i file di log allegati come file zip. Non sarà inviata automaticamente, dovrai premere \"invia\". Puoi anche cambiare il destinatario con te stesso, per esempio.</string>
<string name="shareConfigAndLogFilesWithDev">Allegare i file di configurazione e di registro</string>
<string name="showHelp">Mostra Aiuto</string>
<string name="shareConfigAndLogFilesWithDev">Allega i file di configurazione e di registro</string>
<string name="showHelp">Mostra aiuto</string>
<string name="showIcon">Mostra icona</string>
<string name="showIconWhenServiceIsRunning">Mostra una icona quando il servizio è attivo (nasconderla funziona solo in versioni inferiori ad Android 7). Se hai una versione superiore, vai alle impostazioni di sistema, quindi Automation, e poi seleziona Notifiche, dove potrai disabilitare la \"Service notification\".</string>
<string name="showOnMap">Mostra sulla mappa</string>
@ -466,7 +466,7 @@
<string name="soundModeNormal">Normale</string>
<string name="soundModeSilent">Silenziosa</string>
<string name="soundModeVibrate">Vibrazione</string>
<string name="soundSettings">Impostazioni del suono</string>
<string name="soundSettings">Impostazioni audio</string>
<string name="speedMaximumTime">Tempo in minuti</string>
<string name="speedMaximumTimeBetweenLocations">Tempo massimo tra la rilevazione di due posizioni per determinarne la velocità.</string>
<string name="start">Inizio</string>
@ -477,19 +477,19 @@
<string name="startAppChoiceNote">Qui hai 2 opzioni generali:\n\n1. Puoi avviare un programma selezionando un\'attività. Immagina questo come la preselezione di una specifica schermata/finestra di un\'applicazione. Tieni a mente che questo potrebbe non funzionare sempre. Questo perché le finestre di un\'applicazione potrebbero interagire tra loro, ad esempio per passarsi dei parametri. Quando si avvia direttamente una schermata specifica la cui\n\ninterazione non è ancora avvenuta, la finestra potrebbe chiudersi istantaneamente (quindi non verrà mai mostrata). Ma puoi provare comunque! Inserisci un percorso di attività manualmente, ma si raccomanda di usare il pulsante \"Seleziona\". Se decidi di inserirlo manualmente, digita il nome del pacchetto dell\'applicazione nel campo superiore e il percorso completo dell\'attività in quello inferiore.\n\n2. Selezione per azione. Invece che selezionare una specifica finestra puoi anche avviare un programma per mezzo di un\'azione. Questo è come gridare "Vorrei xyz" e se c\'è un\'applicazione installata che è registrata con quella funzione, verrà avviata. Un buon esempio sarebbe avviare un navigatore - potresti anche averne più di uno installato (ma uno è di solito quello di default). Devi inserire questo manualmente, mentre PackageName è opzionale qui. Tieni a mente che nessuna variabile sarà risolta. Se vuoi avviare la fotocamera per esempio usando \"MediaStore.ACTION_IMAGE_CAPTURE\" non funzionerà. Devi dare un\'occhiata alla documentazione di Android e usare invece il valore effettivo di questa variabile che in questo esempio sarebbe \"android.media.action.IMAGE_CAPTURE\".</string>
<string name="startAppSelectionType">Metodo per\nselezionare l\'applicazione</string>
<string name="startAppStartType">Seleziona tipo di avvio</string>
<string name="startAtSystemBoot">Avvio automatico al boot</string>
<string name="startAtSystemBoot">Avvia all\'accensione</string>
<string name="startAutomationAsService">Avvia Automation come un servizio</string>
<string name="startNewThreadForRuleExecution">Iniziata nuova esecuzione per l\'attivazione della regola.</string>
<string name="startOtherActivity">Inizia una nuova app</string>
<string name="startScreen">Schermo di Avvio</string>
<string name="startOtherActivity">Avvia una nuova app</string>
<string name="startScreen">Schermata di avvio</string>
<string name="startScreenSummary">Seleziona la schermata con cui le applicazioni si aprono all\'inizio.</string>
<string name="startServiceAfterAppUpdate">Riavvia automaticamente il servizio se era già in esecuzione, dopo che l\'applicazione venga aggiornata.</string>
<string name="startServiceAfterAppUpdate">Riavvia automaticamente il servizio se era già in esecuzione, dopo che l\'applicazione viene aggiornata.</string>
<string name="startServiceAfterAppUpdateShort">Riavvio del servizio dopo l\'aggiornamento</string>
<string name="started">avviato</string>
<string name="starting">avviando</string>
<string name="starting">avvio in corso</string>
<string name="status">Stato</string>
<string name="stillGettingPosition">Ancora in attesa della posizione</string>
<string name="stopped">terminatoo</string>
<string name="stopped">terminato</string>
<string name="stopping">terminando</string>
<string name="storeSettings">Leggere e scrivere le impostazioni</string>
<string name="stringNotAllowed">La stringa %1$s non è permessa.</string>
@ -515,21 +515,21 @@
<string name="timeoutForGpsComparisonsTitle">Timeout del GPS [sec]</string>
<string name="title">Titolo</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="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="toggling">Attivando</string>
<string name="triggerCharging">Batteria sotto carica</string>
<string name="triggerHeadsetPlugged">Connessione Auricolari</string>
<string name="triggerHeadsetPlugged">Connessione auricolari</string>
<string name="triggerNoiseLevel">Livello del rumore di fondo</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Questa evento è valido solo se Google play service è installato.</string>
<string name="triggerPointOfInterest">Posizione</string>
<string name="triggerSpeed">Velocità</string>
<string name="triggerTimeFrame">Intervallo</string>
<string name="triggerUsb_host_connection">connessione al computer (USB)</string>
<string name="triggers">Evento(i)</string>
<string name="triggersComment">(tutti gli eventi devono essere validi allo stesso tempo)</string>
<string name="triggerUsb_host_connection">Connessione al computer (USB)</string>
<string name="triggers">Evento/i</string>
<string name="triggersComment">(tutti gli eventi devono essere validi contemporaneamente)</string>
<string name="tuesday">Martedì</string>
<string name="unknownError">Errore indeterminato.</string>
<string name="until">finchè</string>
@ -538,25 +538,25 @@
<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="useAuthentication">Usa l\'autenticazione</string>
<string name="useExistingTag">Utilizzo di una etichetta NFC esistente</string>
<string name="useTextToSpeechOnNormalSummary">Usa TextToSpeech nel modo normale</string>
<string name="useTextToSpeechOnNormalTitle">TTS in modo normale</string>
<string name="useTextToSpeechOnSilentSummary">Usa TextToSpeech nel modo silenzioso</string>
<string name="useTextToSpeechOnSilentTitle">TTS in modo silenzioso</string>
<string name="useTextToSpeechOnVibrateSummary">Usa TextToSpeech nel modo vibrazione</string>
<string name="useTextToSpeechOnVibrateTitle">TTS in modo vibrazione</string>
<string name="useExistingTag">Usa una etichetta NFC esistente</string>
<string name="useTextToSpeechOnNormalSummary">Usa TextToSpeech nella modalità normale</string>
<string name="useTextToSpeechOnNormalTitle">TTS in modalità normale</string>
<string name="useTextToSpeechOnSilentSummary">Usa TextToSpeech nella modalità silenziosa</string>
<string name="useTextToSpeechOnSilentTitle">TTS in modalità silenzioso</string>
<string name="useTextToSpeechOnVibrateSummary">Usa TextToSpeech nella modalità vibrazione</string>
<string name="useTextToSpeechOnVibrateTitle">TTS in modalità vibrazione</string>
<string name="username">Nome utente</string>
<string name="usingNewThreadForRuleExecution">Iniziata nuova esecuzione per l\'attivazione della regola.</string>
<string name="version">Versione %1$s.</string>
<string name="vibrateWhenRinging">Vibrazione alla chiamata</string>
<string name="vibrateWhenRinging">Vibra alla chiamata</string>
<string name="volumeAlarms">Allarmi sonori</string>
<string name="volumeMusicVideoGameMedia">Multimedia (musica, video …)</string>
<string name="volumeRingtoneNotifications">Toni e notifiche</string>
<string name="volumeTest">Calibratura audio</string>
<string name="volumeTest">Calibrazione audio</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="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="waitBeforeNextAction">Attendi prima della azione successiva</string>
<string name="waitBeforeNextActionEnterValue">Inserisci il valore della pausa tra un\'azione e la successiva (millisecondi).</string>
<string name="wakeupDevice">Sveglia il dispositivo</string>
<string name="wakeupDeviceValue">Inserisci per quanto tempo il dispositivo deve rimanere attivo (millisecondi). Usa 0 per i valori standard.</string>
<string name="warning">Attenzione</string>
@ -571,13 +571,13 @@
<string name="wifi">wifi</string>
<string name="wifiConnection">Connessione wifi</string>
<string name="wifiName">Nome wifi</string>
<string name="wifiState">Stato Wifi</string>
<string name="wifiState">Stato wifi</string>
<string name="with">con</string>
<string name="withLabel">con etichetta</string>
<string name="writeLogFile">Memorizza un file di log</string>
<string name="yes">Si</string>
<string name="clone">Clonare</string>
<string name="state">Status</string>
<string name="yes">Sì</string>
<string name="clone">Clona</string>
<string name="state">Stato</string>
<string name="urlToTriggerExplanation">Questa funzione NON apre un navigatore, ma attiva un indirizzo URL in secondo piano. Puoi usarla per esempio per mandare dei comandi al tuo sistema di domotica.</string>
<string name="automaticUpdateCheck">Controlla aggiornamenti</string>
<string name="automaticUpdateCheckSummary">Applicabile solo alla versione APK.</string>
@ -586,62 +586,62 @@
<string name="locationFoundInaccurate">È stato possibile solo trovare una ubicazione con una precisione limitata. Potrebbe non funzionare in maniera affidabile. Il raggio minimo per le ubicazioni è di %1$d m.</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="tones">Suonerias</string>
<string name="tones">Suonerie</string>
<string name="dnd">Non disturbare</string>
<string name="deviceOrientation">Orientamento</string>
<string name="tolerance">Tolleranza</string>
<string name="deviceOrientation">Orientamento del dispositivo</string>
<string name="tolerance">Tolleranza (0180)</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="actionSetBluetoothTethering">Tethering Bluetooth</string>
<string name="actionTurnBluetoothTetheringOn">attiva Tethering Bluetooth</string>
<string name="actionTurnBluetoothTetheringOff">disattiva Tethering Bluetooth</string>
<string name="vibrate">Vibra</string>
<string name="test">Prova</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="top">In alto</string>
<string name="bottom">In basso</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="silentTriggersDnd">ATTENZIONE: La modalità silenziosa spesso attiva quella \"non disturbare\" sui dispositivi più nuovi. Se questo è vero, è raccomandabile usare la modalità normale abbassando tutti i volumi a zero.</string>
<string name="miscellaneous">Altro</string>
<string name="dndOff">Spegni \"Non disturbare\"</string>
<string name="dndOff">Disattiva \"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="automationNotificationsIgnored">Se non scegli una applicazione specifica, ma scegli \"Qualsiasi applicazione\", le notifiche provenienti da Automation saranno ignorate per evitare cicli infiniti.</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="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. Su Android 11 sicuramente non funziona più. Se hai una versione intermedia, per favore fammi sapere se funziona o no sul tuo dispositivo.</string>
<string name="notice">Avviso</string>
<string name="orientationPitch">Inclinazione:</string>
<string name="orientationRoll">Rotazione:</string>
<string name="orientationPitch">Beccheggio:</string>
<string name="orientationRoll">Rollio:</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="deviceOrientationExplanation">Muovendo il dispositivo i numeri qua sotto cambieranno, dove si può vedere l\'orientamento attuale del dispositivo, misurata in gradi. Se è nell\'orientamento voluto, si può cliccare il tasto applica per copiare i valori attuali nei campi desiderati. Siccome è impossibile ritrovare questo orientamento preciso, è necessario indicare una tolleranza. Questa indica il numero di gradi di deviazione dell\'orientamento accettati in entrambe le direzioni. 15° comporta un angolo complessivo di 30°, 15° in ogni direzione. Se solo un asse è di interesse, allora specifica una tolleranza di 180° per gli altri due.</string>
<string name="wouldCurrentlyApply">Sarebbe applicabile?</string>
<string name="deviceIsInCertainOrientation">il dispositivo si trova in un certo orientamento</string>
<string name="toleranceOf180OnlyAllowedIn2Fields">Una tolleranza di 180 è permessa solo per 2 campi, non tutti e tre, altrimenti l\'evento sarebbe SEMPRE verificato.</string>
<string name="unknown">sconosciuto</string>
<string name="orientation">Orientazione</string>
<string name="orientation">Orientamento</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="turnScreenOnOrOff">Accendi o 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="mustApply">Deve verificarsi</string>
<string name="explanationDeviceOrientationDirection">Se la casella di controllo è spuntata, allora il dispositivo deve essere nell\'orientamento specificato. Se non è spuntata, qualsiasi orientamento che NON rientra nelle specifiche 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>
<string name="profileTriggerCheckSettings">Se questa casella di controllo non è disabilitata, verrà selezionata solo se il profilo selezionato è stato l\'ultimo ad essere attivato. Non importa se le impostazioni relative all\'audio sono state modificate esternamente.\nTuttavia, se la casella di controllo è abilitata, le impostazioni audio correnti devono essere definite nel profilo. ATTENZIONE: il controllo del file della suoneria non è ancora supportato.</string>
<string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Escludere dall\'ottimizzazione della batteria</string>
<string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Escludi dall\'ottimizzazione della batteria</string>
<string name="recommendedForBetterReliability">Consigliato per una migliore affidabilità</string>
<string name="needsToBeActive">Deve essere attivo</string>
<string name="checkSettings">Controlla le impostazioni</string>
@ -665,25 +665,25 @@
<string name="info">Informazioni</string>
<string name="profileWasNotFound">Il profilo utilizzato in questa regola non sembra più esistere. Il primo in ordine alfabetico è stato selezionato.</string>
<string name="comparisonCaseInsensitive">I confronti non distinguono fra maiuscole e minuscole</string>
<string name="closeNotifications">Chiudi notifica(e)</string>
<string name="notificationCloseActionExplanation">Se non specifichi alcun criterio, questa azione chiuderà TUTTE le notifiche. Quindi si consiglia di specificare almeno i criteri per almeno una applicazione, titolo o testo.</string>
<string name="profileWarning">Le impostazioni che modifichi in questa sezione possono far sì che tu non possa più notare certe cose dal tuo telefono. Possono perfino silenziare la sveglia. Quindi, qualunque cosa tu faccia, ti consigliamo di provarlo.</string>
<string name="closeNotifications">Chiudi notifica/e</string>
<string name="notificationCloseActionExplanation">Se è non specificato alcun criterio, questa azione chiuderà TUTTE le notifiche. Quindi si consiglia di specificare almeno i criteri per almeno una applicazione, titolo o testo.</string>
<string name="profileWarning">Le impostazioni che si possono modificare in questa sezione possono impedirti di notare certe cose del tuo telefono. Si può perfino silenziare la sveglia, quindi, qualunque cosa tu faccia, ti consigliamo di provarlo.</string>
<string name="ifString">se</string>
<string name="actionMediaControlNotice">Tieni presente che questa azione potrebbe non funzionare con TUTTI i lettori là fuori. E anche se lo facesse, non tutti i pulsanti funzionerebbero necessariamente.</string>
<string name="actionMediaControlNotice">Tieni presente che questa azione potrebbe non funzionare con TUTTI i lettori esistenti. E anche fosse, non è detto che tutti i pulsanti funzionerebbero.</string>
<string name="pleaseSelectActionValue">Si prega di selezionare un\'azione!</string>
<string name="stop">stop</string>
<string name="android.permission.MEDIA_CONTENT_CONTROL">Controllo riproduzione multimediale</string>
<string name="next">prossimo</string>
<string name="android.permission.MEDIA_CONTENT_CONTROL">Controlla riproduzione multimediale</string>
<string name="next">successivo</string>
<string name="previous">precedente</string>
<string name="pause">pausa</string>
<string name="play">riproduci</string>
<string name="playPause">attiva/disattiva riproduzione/pausa</string>
<string name="playPause">commuta riproduzione/pausa</string>
<string name="selectCommand">Seleziona comando</string>
<string name="actionMediaControl">Controllare la riproduzione multimediale</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">A causa della saggezza infinita di Google, l\'ultima versione di Android su cui questa funzione è nota per funzionare è %1 $s. Puoi configurarlo, ma probabilmente non avrà alcun effetto.</string>
<string name="actionMediaControl">Controlla la riproduzione multimediale</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">A causa della sconfinata saggezza di Google, l\'ultima versione di Android su cui questa funzione si sa che funziona è la %1$s. Puoi configurarla, ma probabilmente non avrà alcun effetto.</string>
<string name="screenState">Stato dello schermo</string>
<string name="selectDesiredState">Seleziona lo stato desiderato</string>
<string name="unlocked">Sbloccato</string>
<string name="unlocked">sbloccato</string>
<string name="off">spento</string>
<string name="on">attivo</string>
<string name="screenIs">lo schermo è %1$s</string>
@ -693,12 +693,48 @@
<string name="musicPlaying">La musica è in riproduzione</string>
<string name="musicIsPlaying">la musica è in riproduzione</string>
<string name="musicIsNotPlaying">la musica non viene riprodotta</string>
<string name="selectParameters">Selezionare i parametri</string>
<string name="selectParameters">Seleziona i parametri</string>
<string name="musicCheckFrequencyTitle">Frequenza dei controlli [ms]</string>
<string name="musicCheckFrequencySummary">Millisecondi tra i controlli</string>
<string name="musicPlayingDetection">Rilevamento della riproduzione musicale</string>
<string name="profileXrequiresThis">Questo è richiesto dal profilo \"%1$s\".</string>
<string name="locationNotWorkingOn12">Ottenere la posizione non sembra funzionare su dispositivi Android 12 al momento. Se non funziona per te, mi dispiace. Cercherò di risolvere questo problema non appena conoscerò la causa. Quindi, se cerchio rotante non smette di girare, sai perché.</string>
<string name="locationNotWorkingOn12">Ottenere la posizione non sembra funzionare su dispositivi Android 12 al momento. Se a te non funziona, mi dispiace. Cercherò di risolvere questo problema non appena capirò la causa. Se il cerchio di caricamento non smette di girare, sai perché.</string>
<string name="lastProfile">Ultimo profilo:</string>
<string name="queryAllPackages">Ottenere un elenco delle applicazioni installate</string>
<string name="queryAllPackages">Ottieni un elenco delle applicazioni installate</string>
<string name="timeFrameDaysHint">Se si utilizza un intervallo di tempo che si estende oltre la mezzanotte, è necessario selezionare anche il giorno successivo se si desidera che il trigger venga applicato dopo la mezzanotte.</string>
<string name="featureNotInGooglePlayVersion">Questa funzione non è più disponibile nella versione di Google Play.\\n\\nOltre di tanto in tanto Google bullizza gli sviluppatori. Se si desidera continuare a utilizzare determinate funzionalità, è necessario archiviare i documenti. Sfortunatamente c\'è una probabilità del 99% che i documenti vengano rifiutati. È più o meno come nel fumetto / film di Asterix.\\n\\nHo passato settimane a discutere con loro su casi del genere in passato, ma ho continuato a ricevere rifiuti - sia da bot che da persone che sono intelligenti come i bot. Nella sezione Posso decidere se l\'app viene rimossa completamente dal Play Store o rimuovere la funzione.\\nConsigliare l\'utilizzo della versione APK dal mio sito Web o quella di F-Droid se sono necessarie tali funzionalità.</string>
<string name="startActivityInsertManually">Questa limitazione riguarda solo la selezione di un\'app, non l\'avvio effettivo. Quindi puoi comunque inserire manualmente il nome di un\'applicazione se lo conosci.</string>
<string name="deviceStarts">Device starts</string>
<string name="serviceStarts">Avvio del servizio</string>
<string name="deviceHasJustStarted">il dispositivo è appena stato avviato</string>
<string name="serviceHasJustStarted">il servizio è appena stato avviato</string>
<string name="broadcastReceived">broadcast ricevuto</string>
<string name="broadcastNotReceived">broadcast non ricevuto</string>
<string name="broadcastReceivedTitle">Broadcast ricevuto</string>
<string name="broadcastsShowSuggestions">Mostra suggerimenti</string>
<string name="selectBroadcast">Seleziona trasmissione</string>
<string name="lockedWithoutSecurity">bloccato (solo scorrimento rapido, nessun PIN)</string>
<string name="lockedWithSecurity">bloccato (con PIN, ecc.)</string>
<string name="lockedCommentScreenMustBeOff">Qualsiasi stato di blocco verrà rilevato solo se lo schermo è spento.</string>
<string name="emailPretext">Se hai un problema, suggerimenti o domande, scrivi qualcosa nell\'e-mail. Non inviarmi semplicemente i file con il testo predefinito. Ignorerò tutto ciò che li riguarda a meno che non siamo già in una conversazione.</string>
<string name="broadcastExplanation">Questa azione consente di inviare un broadcast all\'interno del sistema di messaggi di Android. Questo non è visibile all\'utente, ma le applicazioni che si sono registrate a determinati broadcast possono rispondere.</string>
<string name="sendBroadcast">Invia broadcast</string>
<string name="enterBroadcast">Immettere un\'azione per il broadcast.</string>
<string name="explanationBroadcastTrigger">La maggior parte degli eventi sul telefono verrà \"pubblicata\" trasmettendoli in tutto il sistema operativo.\nAd esempio, l\'attivazione/disattivazione della modalità aereo attiverà tale trasmissione. Queste trasmissioni non sono automaticamente visibili / udibili, ma se un\'applicazione (come l\'automazione) è interessata può collegarsi a loro. Quando si verificano, riceverà una notifica e può reagire.\n\nÈ possibile definire qui un evento di trasmissione per il quale l\'applicazione attenderà. Puoi inserirlo manualmente, copiarlo e incollarlo da qualche parte o sceglierne uno dall\'elenco dei suggerimenti. Poiché questo trigger è pensato per essere e rimanere molto flessibile, non posso fornirti spiegazioni per gli articoli.\n\nL\'elenco dei suggerimenti non pretende di essere completo. Si prega di visitare l\'URL sottostante per dare un\'occhiata alla documentazione Android.\nInoltre qualsiasi app può inviare eventi personalizzati che ovviamente non saranno presenti nella documentazione Android.\n\nMolti broadcast richiedono autorizzazioni specifiche per funzionare. Provo a richiedere le autorizzazioni dove so che servono. Se ritieni che sia necessaria un\'autorizzazione per l\'azione che hai inserito, fammi sapere.\n\nNon ricevuto significa che non è capitato un broadcast di questo tipo da quando il servizio è stato avviato. La risposta a certi parametri è in fase di sviluppo.</string>
<string name="logsExplanation">Per evitare di sprecare lo spazio di archiviazione, i registri non vengono salvati per impostazione predefinita. Quindi, se hai un problema, attiva prima le impostazioni di accesso e imposta il livello di registro su 5, poi riproduci il problema. Solo allora i registri possono essere allegati.</string>
<string name="directionStringDoesNotContain">non contiene</string>
<string name="path">Percorso</string>
<string name="runExecutable">Esegui script o eseguibile</string>
<string name="parameters">Parametri</string>
<string name="chooseExecutable">Scegli eseguibile</string>
<string name="runAsRoot">Esegui con root</string>
<string name="selectValidExecutable">Scegli un file eseguibile valido.</string>
<string name="fileNotExecutable">Questo file non è eseguibile.</string>
<string name="usingRoot">usando il root</string>
<string name="tetheringActive">il tethering è attivo</string>
<string name="tetheringNotActive">il tethering non è attivo</string>
<string name="tetheringState">Stato del tethering</string>
<string name="wifiExplanation2">Quando la modalità aereo è attiva, lo stato del wifi può essere commutato soltanto da applicazioni che usano i permessi di root.</string>
<string name="wifiExplanation1">Le app che hanno come target Android Q o superiore non possono più attivare o disattivare il wifi. Lamentatevi con Google per questa limitazione, non con me.\n\nSi può aggirare questa limitazione usando il root e spuntando la casella qua sotto. In alternativa si può scaricare questa applicazione da F-Droid o dal mio sito, dove non sono obbligato a usare come target le ultime API.</string>
<string name="runExecutableExplanation">"Si può scegliere uno script o un eseguibile che sarà eseguito come azione.\n\nCi sono però dei prerequisiti che devi sistemare per conto tuo. Google ha reso molto difficile eseguire tutto tranne le normali applicazioni Android.\n\n1.\nIl file deve essere eseguibile nel file system. In un sistema Android normale (senza root) questa è la parte più difficile.\n\n2.\nAnche Automation deve poter eseguire il file, non soltanto il proprietario o il gruppo.\n\n3.\nSe si tratta di uno script, deve essere specificata una shell valida nell'intestazione. "</string>
</resources>

View File

@ -543,7 +543,7 @@
<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="phoneNumberExplanation">U kunt een specifiek telefoonnummer opgeven (van de bellende partner), 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>
@ -699,4 +699,26 @@
<string name="profileXrequiresThis">Profiel \"%1$s\" vereist dit.</string>
<string name="lastProfile">Laatste profiel:</string>
<string name="queryAllPackages">Een lijst met geïnstalleerde toepassingen ophalen</string>
<string name="timeFrameDaysHint">Als u een tijdsbestek gebruikt dat zich uitstrekt over middernacht, moet u ook de volgende dag selecteren als u wilt dat de trigger na middernacht van toepassing is.</string>
<string name="featureNotInGooglePlayVersion">Deze functie is niet meer beschikbaar in de Google Play-versie.\\n\\nAlles af en toe pest Google ontwikkelaars. Als u bepaalde functies wilt blijven gebruiken, moet u papierwerk indienen. Helaas is er een kans van 99% dat het papierwerk wordt afgewezen. Het is vrijwel net als in de Asterix-strip / film.\\n\\nIk heb in het verleden wekenlang met hen gediscussieerd over dergelijke gevallen, maar ik bleef afwijzingen krijgen - hetzij door bots of mensen die ongeveer net zo intelligent zijn als bots. In de ik kan kiezen tussen de app die volledig uit de Play Store wordt verwijderd of de functie verwijdert.\\n Overweeg de APK-versie van mijn website of die van F-Droid te gebruiken als je die functies nodig hebt.</string>
<string name="startActivityInsertManually">Deze beperking heeft alleen betrekking op de selectie van een app, niet op de daadwerkelijke start. U kunt dus nog steeds handmatig de naam van een toepassing invoeren als u deze kent.</string>
<string name="deviceHasJustStarted">apparaat is net gestart</string>
<string name="serviceHasJustStarted">service is net begonnen</string>
<string name="serviceStarts">Service start</string>
<string name="deviceStarts">Apparaat start</string>
<string name="emailPretext">Als je een probleem, suggesties of vraag hebt, schrijf dan iets in de e-mail. Stuur me niet alleen de bestanden met de standaard e-mailtekst. Ik zal alles negeren, tenzij we al in gesprek zijn.</string>
<string name="lockedCommentScreenMustBeOff">Elke vergrendelde status wordt alleen gedetecteerd als het scherm is uitgeschakeld.</string>
<string name="lockedWithSecurity">vergrendeld (met PINCODE, enz.)</string>
<string name="lockedWithoutSecurity">vergrendeld (alleen vegen, geen pincode)</string>
<string name="selectBroadcast">Selecteer broadcast</string>
<string name="broadcastsShowSuggestions">Toon suggesties</string>
<string name="broadcastReceivedTitle">Broadcast ontvangen</string>
<string name="broadcastNotReceived">broadcast niet ontvangen</string>
<string name="broadcastReceived">broadcast ontvangen</string>
<string name="broadcastExplanation">Deze actie maakt het mogelijk om een uitzending te versturen via het berichtensysteem van Android. Dit is niet zichtbaar voor de gebruiker, maar applicaties die zich voor bepaalde uitzendingen hebben geregistreerd, kunnen hierop reageren.</string>
<string name="sendBroadcast">Broadcast verzenden</string>
<string name="enterBroadcast">Voer een uitzendactie in.</string>
<string name="explanationBroadcastTrigger">De meeste gebeurtenissen op uw telefoon worden \"gepubliceerd\" door ze uit te zenden in het hele besturingssysteem.\nHet in- en uitschakelen van de vliegtuigmodus zal bijvoorbeeld een dergelijke uitzending activeren. Die uitzendingen zijn niet automatisch zichtbaar/hoorbaar, maar als een applicatie (zoals Automation) geïnteresseerd is, kan deze erop aansluiten. Wanneer ze zich voordoen, wordt het een melding gegeven en kan het reageren.\n\nU kunt hier een uitzendgebeurtenis definiëren waarop de toepassing zal wachten. U kunt het handmatig invoeren, ergens vandaan kopiëren en plakken of er een kiezen uit de lijst met suggesties. Omdat deze trigger bedoeld is en zeer flexibel is, kan ik u geen uitleg geven voor de items.\n\nDe lijst met suggesties beweert niet volledig te zijn. Ga naar de onderstaande URL om de Android-documentatie te bekijken.\nOok kan elke app aangepaste gebeurtenissen verzenden die natuurlijk niet in de Android-documentatie worden weergegeven.\n\nVeel uitzendingen vereisen specifieke machtigingen om te kunnen werken. Ik probeer toestemmingen te vragen waarvan ik weet dat ze nodig zijn. Als u denkt dat er een toestemming vereist is voor de actie die u hebt ingevoerd, laat het me dan weten.\n\nNiet ontvangen betekent dat er sinds de service is gestart niet meer zo\'n uitzending is geweest. Inspelen op bepaalde parameters is in ontwikkeling.</string>
<string name="logsExplanation">Om onnodige slijtage van uw opslag te voorkomen, worden logboeken niet standaard opgeslagen. Dus als u een probleem hebt, activeer dan eerst de inloginstellingen en stel het logniveau in op 5. Reproduceer vervolgens het probleem. Alleen dan kunnen logs worden bijgevoegd.</string>
<string name="directionStringDoesNotContain">bevat geen</string>
</resources>

View File

@ -645,7 +645,7 @@
<string name="enterValidAction">Enter a valid action</string>
<string name="enterPackageName">Enter a valid package name.</string>
<string name="state">State</string>
<string name="phoneNumberExplanation">You can enter a specific phone number, but you don\'t have to. If you want to specify one you can either pick one from your address book or enter it manually. In addition you may use regular expressions. To test a regular expression I like this page:</string>
<string name="phoneNumberExplanation">You can enter a specific remote phone number, but you don\'t have to. If you want to specify one you can either pick one from your address book or enter it manually. In addition you may use regular expressions. To test a regular expression I like this page:</string>
<string name="importConfiguration">Import configuration</string>
<string name="exportConfiguration">Export configuration</string>
<string name="moreSettings">More settings</string>
@ -797,4 +797,41 @@
<string name="locationNotWorkingOn12">Getting the location does not seem to be working on Android 12 devices currently. If it isn\'t working for you, I\'m sorry. I\'ll try to fix this as soon as I know the cause. So if the donut doesn\'t stop spinning, you know why.</string>
<string name="lastProfile">Last profile:</string>
<string name="queryAllPackages">Get a list of installed applications</string>
<string name="timeFrameDaysHint">If you use a timeframe that stretches over midnight you need to select the following day as well if you want the trigger to apply after midnight.</string>
<string name="featureNotInGooglePlayVersion">This feature is not available in the Google Play version anymore.\n\nEvery now and then Google bullies developers. If you want to keep using certain features you have to file paperwork. Unfortunately there\'s a 99% chance that the paperwork gets rejected. It\'s pretty much like in the Asterix comic/movie.\n\nI\'ve spent weeks arguing with them about cases like that in the past, but I kept getting rejections - either by bots or people who are about as intelligent as bots. In the I can decide between the app being removed from the Play Store entirely or remove the feature.\nPlease consider using the APK version from my website or the one from F-Droid if you need those features.</string>
<string name="startActivityInsertManually">This limitation concerns only the selection of an app, not the actual start. So you can still enter the name of an application manually if you know it.</string>
<string name="deviceStarts">Device starts</string>
<string name="serviceStarts">Service starts</string>
<string name="deviceHasJustStarted">device has just started</string>
<string name="serviceHasJustStarted">service has just started</string>
<string name="broadcastReceived">broadcast received</string>
<string name="broadcastNotReceived">broadcast not received</string>
<string name="explanationBroadcastTrigger">Most events on your phone will be \"published\" by broadcasting them throughout the operating system.\nFor example turning on/off airplane mode will trigger such a broadcast. Those broadcasts are not automatically visible/audible, but if an application (like Automation) is interested it can hook up to them. When they occur it will get notified and can react.\n\nYou can define a broadcast event here for which the application will wait. You may enter it manually, copy &amp; paste it from somewhere or pick one from the list of suggestions. As this trigger is meant to be and remain very flexible I cannot provide you with explanations for the items.\n\nThe list of suggestions does not claim to be complete. Please visit the below URL to have a look at the Android documentation.\nAlso any app can send custom events which will not appear in the Android documentation of course.\n\nMany broadcasts require specific permissions in order to work. I try to request permissions where I know they will be required. If you think a permission is required for the action you entered, please let me know.\n\nNot received means there has not been such a broadcast ever since the service has been started. Responding to certain parameters is in development.</string>
<string name="broadcastListUrl" translatable="false">https://developer.android.com/reference/android/content/Intent.html</string>
<string name="broadcastReceivedTitle">Broadcast received</string>
<string name="logsExplanation">To avoid unnecessary wearing of your storage, logs are not saved by default. So if you have a problem please activate logging in settings first and set log level to 5. Then reproduce the problem. Only then logs can be attached.</string>
<string name="broadcastsShowSuggestions">Show suggestions</string>
<string name="selectBroadcast">Select broadcast</string>
<string name="lockedWithoutSecurity">locked (swipe only, no PIN)</string>
<string name="lockedWithSecurity">locked (with PIN, etc.)</string>
<string name="lockedCommentScreenMustBeOff">Any state of locked will only be detected if the screen is off.</string>
<string name="emailPretext">If you have a problem, suggestions or question, please write something in the email. Do not just send me the files with the default mail body. I will ignore everything those unless we\'re already in a conversation.</string>
<string name="sendBroadcast">Send broadcast</string>
<string name="enterBroadcast">Enter a broadcast action.</string>
<string name="broadcastExplanation">This action allows to send a broadcast across the Android OS messaging system. This is not user-visible, but apps who listen for that specific broadcast can respond to it being sent.</string>
<string name="directionStringDoesNotContain">does not contain</string>
<string name="runExecutable">Run script or executable</string>
<string name="path">Path</string>
<string name="parameters">Parameters</string>
<string name="chooseExecutable">Choose executable</string>
<string name="runAsRoot">Run as root</string>
<string name="selectValidExecutable">Select a valid executable file.</string>
<string name="fileNotExecutable">The file is not executable.</string>
<string name="wifiExplanation1">Apps targeting Android Q or higher cannot turn wifi on or off anymore. Please blame Google for this restriction, not me.\n\nYou can bypass this restriction by rooting your device and activating the checkbox below. Alternatively download this application from F-Droid or my website as I am not forced to target the latest API level in those versions.</string>
<string name="wifiExplanation2">While airplane mode is activated, wifi can only be toggled from applications when using root permissions for that.</string>
<string name="usingRoot">using root</string>
<string name="runExecutableExplanation">You can select a script or an executable file here that will be executed as an action.\n\nBut there are some prerequisites which you have to deal with on your own. Google has made it very hard to run anything other than regular Android applications.\n\n1.\nThe file must be marked as executable in the file system. On a regular Android system (without root) this is actually the hard part.\n\n2.\nThat also means Automation must be able to execute the file, not just the owner or the group.\n\n3.\nIf it is a script, a valid shell be specified in the script\'s header.</string>
<string name="tetheringActive">tethering is active</string>
<string name="tetheringNotActive">tethering is not active</string>
<string name="tetheringState">Tethering state</string>
</resources>

View File

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

View File

@ -21,6 +21,7 @@ Mögliche Auslöser:
* Benachrichtigungen anderer Anwendungen
* Geräteausrichtung (Gyroskop)
* Profile aktiv oder nicht
* Broadcasts anderer Anwendungen
Mögliche Aktionen:
* WLAN ein-/ausschalten
@ -52,6 +53,9 @@ Wenn Sie ein Problem mit der Anwendung haben und mich dazu kontaktieren möchten
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 (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.
* Wenn Ihnen die Anwendung gefällt, freue ich mich auch einfach nur über eine Email mit ein paar netten Worten.
* Außerdem ist immer Hilfe bei der Übersetzung willkommen. Englisch, Spanisch und Deutsch kann ich selbst, Italienisch ist bereits abgedeckt. Aber sonst ist alles gern gesehen.
* Wenn Sie ein Talent/Erfahrung auf dem Gebiet Grafikdesign haben und Ideen für hübschere Symbole haben, lassen Sie es mich wissen.
* Falls Sie einen interessanten Anwendungsfall haben oder einen Weg gefunden haben, Auslöser und Aktionen so zu kombinieren, um etwas Besonderes umzusetzen und Sie denken, daß man das auf die Beispielseite (https://server47.de/automation/examples.html) setzen sollte, kontaktieren Sie mich doch.
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.php

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

View File

@ -0,0 +1,7 @@
* New trigger: device has just started
* New trigger: service has just started
* New trigger: Respond to customizable broadcasts
* New parameter for trigger Screen state: New state "locked"
* New action: Send broadcasts
* Fixed: Crash when editing notification trigger
* Fixed: TimeFrame trigger - time may have changed when crossing timezones

View File

@ -21,6 +21,7 @@ Supported triggers:
* Notifications of other apps
* Device orientation (gyroscope)
* Profile active or not
* Broadcasts of other apps
Supported actions:
* Change wifi state
@ -52,6 +53,9 @@ If you have a problem and think about contacting me please
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 (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.
* If you like the app, simply some warm words via email are always appreciated.
* Furthermore I can always use help in translating the app. English, German and some Spanish are among my own skills. Italian is covered by somebody already. But everything else is more than welcome.
* If you have a talent/experience in graphics design and have some ideas for nicer icons let me know.
* If you have an interesting use-case or found a way to combine triggers and actions to achieve something intriguing and you think it's worth putting it on the examples page (https://server47.de/automation/examples.html), let me know.
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.php

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -21,6 +21,7 @@ Disparadores:
* Notificaciónes de otras apps
* Orientación del dispositivo (giroscopio)
* Perfil activado o no
* Broadcasts de otras apps
Aciónes:
* Pasar de wifi
@ -52,6 +53,9 @@ Si tiene un problema y considera contactarme
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 (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.
* Si le gusta la aplicación, simplemente algunas palabras cálidas por correo electrónico siempre son apreciadas.
* Además siempre necesito ayuda en traduciendo la app. Ingles, Aleman y Español estan en mis habilidades. Todavia tengo ayuda con Italiono. Per todo lo demás es bienvenido.
* Si tiene talento/experiencia en el campo del diseño gráfico y tienes ideas para crear iconos más bonitos, házmelo saber.
* Si tiene un caso de uso interesante o ha encontrado una forma de combinar condiciones y acciones para lograr algo intrigante y cree que vale la pena ponerlo en la página de ejemplos (https://server47.de/automation/examples.html), házmelo saber.
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.php

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -21,6 +21,7 @@ Eventi supportati:
* Notificazione di un altra applicazione
* Orientamento del dispositivo (giroscopio)
* Profilo attivo o meno
* Broadcasts di altre app
Azioni supportate:
* Cambia lo stato del wifi
@ -52,12 +53,13 @@ Se hai un problema e stai pensando di contattarmi, per favore:
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.
* Se l'applicazione vi piace, sono sempre gradite alcune parole affettuose via e-mail.
* Inoltre, ho sempre bisogno di aiuto per tradurre l'applicazione. Inglese, Tedesco e un po' di Spagnolo son parte delle mie abilità. L'italiano è già coperto da qualcuno. Ma per tutte le altre, apprezzo molto ogni aiuto.
* Se avete talento/esperienza nel design grafico e avete qualche idea per icone più belle fatemelo sapere.
* Se avete un caso d'uso interessante o avete trovato un modo per combinare trigger e azioni per ottenere qualcosa di intrigante e pensate che valga la pena inserirlo nella pagina degli esempi (https://server47.de/automation/examples.html), fatemelo sapere.
Una spiegazione di tutti i permessi si trova qui:
https://server47.de/automation/permissions_en.html
https://server47.de/automation/permissions.php

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@ -23,6 +23,7 @@ Ondersteunde triggers:
* Meldingen van andere apps
* Apparaat oriëntatie (gyroscoop)
* Profiel actief of niet
* Broadcasts van andere apps
Ondersteunde acties:
* Wijzig wifi status
@ -55,6 +56,9 @@ Als je een probleem hebt en erover denkt om contact met me op te nemen
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.
* Als de app u bevalt, worden enkele warme woorden via e-mail altijd op prijs gesteld.
* Verder kan ik altijd hulp gebruiken bij het vertalen van de app. Engels, Duits en wat Spaans behoren tot mijn eigen vaardigheden. Italiaans wordt al door iemand gedekt. Maar al het andere is meer dan welkom.
* Als je talent/ervaring hebt in grafische vormgeving en ideeën hebt voor mooiere iconen, laat het me weten.
* Als u een interessante use-case heeft of een manier om triggers en acties te combineren om iets intrigerends te bereiken en u denkt dat het de moeite waard is om het op de voorbeelden pagina te zetten (https://server47.de/automation/examples.html), laat het me weten.
Uitleg van de vele permissies vind je hier (Engels) : https://server47.de/automation/permissions_en.html
Uitleg van de vele permissies vind je hier (Engels) : https://server47.de/automation/permissions.php

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip