17 Commits

Author SHA1 Message Date
19fd2d098b wifi trigger needs location permission 2022-07-17 23:40:17 +02:00
d07c1a05e4 set wifi with root fix 2022-07-15 22:37:55 +02:00
f9f9b30116 su changes 2022-07-14 22:55:54 +02:00
d154a3d64f wifi trigger - enabled regex 2022-07-12 17:03:32 +02:00
eeb4f4a39e battery level trigger fixed 2022-07-11 22:56:43 +02:00
53e62068a5 close notification with button 2022-07-09 14:22:33 +02:00
922807d903 meta data changed 2022-07-07 20:40:29 +02:00
a7d294c115 translations 2022-07-04 23:02:46 +02:00
2d2fd901a1 translations 2022-07-04 22:57:07 +02:00
536a5e22f9 wakelock action 2022-07-02 12:46:34 +02:00
99faa2f7ef wakelock action 2022-07-02 01:38:39 +02:00
f3fac2f4e8 wakelock 2022-07-01 20:24:58 +02:00
b3b713e454 email tetx 2022-06-30 23:01:26 +02:00
b0d509aafe Merge remote-tracking branch 'origin/development-stable' into development
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values/strings.xml
2022-06-27 23:04:33 +02:00
efb4919a1e regex where comparisons are made 2022-06-27 23:02:53 +02:00
7bc858fee3 number format fix attempt 2022-06-27 22:42:55 +02:00
647d5bd511 fix attempt number format 2022-06-27 20:07:06 +02:00
40 changed files with 601 additions and 119 deletions

2
.gitignore vendored
View File

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

View File

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

View File

@ -169,6 +169,7 @@
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity android:name=".ActivityManageActionWakeLock" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -396,7 +396,7 @@ public class Rule implements Comparable<Rule>
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}

View File

@ -167,6 +167,7 @@
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity android:name=".ActivityManageActionWakeLock" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -393,7 +393,7 @@ public class Rule implements Comparable<Rule>
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}

View File

@ -154,6 +154,7 @@
<activity android:name=".ActivityManageActionRunExecutable" />
<activity android:name=".ActivityManageActionWifi" />
<activity android:name=".ActivityManageTriggerTethering" />
<activity android:name=".ActivityManageActionWakeLock" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">

View File

@ -396,7 +396,7 @@ public class Rule implements Comparable<Rule>
return true;
}
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 4);
return false;
}

View File

@ -53,6 +53,7 @@ public class Action
closeNotification,
sendBroadcast,
runExecutable,
wakelock,
sendTextMessage;
public String getFullName(Context context)
@ -127,6 +128,8 @@ public class Action
return context.getResources().getString(R.string.sendBroadcast);
case runExecutable:
return context.getResources().getString(R.string.runExecutable);
case wakelock:
return context.getResources().getString(R.string.keepDeviceAwake);
default:
return "Unknown";
}
@ -273,6 +276,9 @@ public class Action
case runExecutable:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.runExecutable));
break;
case wakelock:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.keepDeviceAwake) + " (" + String.valueOf(getParameter1()) + ")");
break;
default:
returnString.append(action.toString());
}
@ -485,7 +491,7 @@ public class Action
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
break;
case setWifi:
Actions.WifiStuff.setWifi(context, getParameter1(), toggleActionIfPossible);
Actions.WifiStuff.setWifi(context, getParameter1(), getParameter2(), toggleActionIfPossible);
break;
case setWifiTethering:
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
@ -570,6 +576,12 @@ public class Action
else if(execParts.length == 2)
Actions.runExecutable(context, this.getParameter1(), execParts[0], execParts[1]);
break;
case wakelock:
if(this.getParameter1())
Actions.wakeLockStart(context, Long.parseLong(this.getParameter2()));
else
Actions.wakeLockStop();
break;
default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break;

View File

@ -36,6 +36,7 @@ import android.view.KeyEvent;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.legacy.content.WakefulBroadcastReceiver;
import com.jens.automation2.actions.wifi_router.MyOnStartTetheringCallback;
import com.jens.automation2.actions.wifi_router.MyOreoWifiManager;
@ -43,6 +44,7 @@ import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver;
import com.jens.automation2.receivers.NotificationListener;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
@ -82,10 +84,6 @@ public class Actions
public static AutomationService automationServerRef;
public static Context context;
private static Intent playMusicIntent;
private static boolean suAvailable = false;
private static String suVersion = null;
private static String suVersionInternal = null;
private static List<String> suResult = null;
public final static String smsSeparator = "&sms&";
public final static String dummyPackageString = "dummyPkg239asd";
@ -214,9 +212,20 @@ public class Actions
public static class WifiStuff
{
public static Boolean setWifi(Context context, Boolean desiredState, boolean toggleActionIfPossible)
public static Boolean setWifi(Context context, Boolean desiredState, String parameter2, boolean toggleActionIfPossible)
{
if(context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q)
boolean forceUseRoot = false;
try
{
forceUseRoot = Boolean.parseBoolean(parameter2);
}
catch(Exception e)
{
}
if(context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q || forceUseRoot)
return setWifiWithRoot(context, desiredState, toggleActionIfPossible);
else
return setWifiOldFashioned(context, desiredState, toggleActionIfPossible);
@ -252,8 +261,15 @@ public class Actions
{
Miscellaneous.logEvent("i", "Wifi", "Changing wifi to " + String.valueOf(desiredState), 4);
try
{
if (desiredState && Settings.useWifiForPositioning)
WifiBroadcastReceiver.startWifiReceiver(automationServerRef.getLocationProvider());
}
catch(Exception e)
{
Miscellaneous.logEvent("w", "setWifiOldFashioned()", Log.getStackTraceString(e), 4);
}
WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@ -1864,6 +1880,12 @@ public class Actions
protected static boolean executeCommandViaSu(String[] commands)
{
boolean suAvailable = false;
String suVersion = null;
String suVersionInternal = null;
// List<String> suResult = null;
int suResult;
boolean success = false;
try
@ -1873,17 +1895,30 @@ public class Actions
{
suVersion = Shell.SU.version(false);
suVersionInternal = Shell.SU.version(true);
suResult = Shell.SU.run(commands);
if (suResult != null)
Miscellaneous.logEvent("i", "executeCommandViaSu()", "suVersion: " + suVersion + ", suVersionInternal: " + suVersionInternal, 5);
// suResult = Shell.SU.run(commands);
suResult = Shell.Pool.SU.run(commands);
// if (suResult != null)
// success = true;
Miscellaneous.logEvent("i", "executeCommandViaSu()", "RC=" + String.valueOf(suResult), 3);
if(suResult == 0)
success = true;
}
else
Miscellaneous.logEvent("w", "executeCommandViaSu()", "su not available.", 4);
}
catch (Exception e)
{
success = false;
}
Miscellaneous.logEvent("i", "executeCommandViaSu()", "Returning " + String.valueOf(success), 4);
return success;
}
@ -2092,4 +2127,61 @@ public class Actions
return false;
}
public final static int wakeLockTimeoutDisabled = -1;
static boolean wakeLockStopRequested = false;
public static void wakeLockStart(Context context, long duration)
{
Thread lockThread = new Thread(new Runnable()
{
@Override
public void run()
{
wakeLockStopRequested = false;
long waited = 0;
int step = 2000;
try
{
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK");
fullWakeLock.acquire(); // turn on
do
{
try
{
Thread.sleep(step); // turn on duration
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(duration > 0)
waited += step;
if(wakeLockStopRequested) //stop requested
Miscellaneous.logEvent("i", "WakeLockStart", "Stop requested.", 4);
}
while(!wakeLockStopRequested && (duration < 0 || waited <= duration));
fullWakeLock.release();
}
catch (Exception e)
{
}
}
});
lockThread.start();
}
public static void wakeLockStop()
{
Miscellaneous.logEvent("i", "WakeLockStart", "Requesting stop.", 4);
wakeLockStopRequested = true;
}
}

View File

@ -172,6 +172,29 @@ public class ActivityManageActionSendBroadcast extends Activity
return;
}
switch(supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()])
{
case "int":
case "long":
case "short":
if(!Miscellaneous.isNumeric(etParameterValue.getText().toString()))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
break;
case "double":
case "float":
if(!Miscellaneous.isNumericDecimal(etParameterValue.getText().toString()))
{
Toast.makeText(ActivityManageActionSendBroadcast.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
break;
default:
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
intentPairList.add(param);
@ -201,8 +224,10 @@ public class ActivityManageActionSendBroadcast extends Activity
@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"))
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
else
ActivityManageActionSendBroadcast.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}

View File

@ -153,6 +153,29 @@ public class ActivityManageActionStartActivity extends Activity
return;
}
switch(supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()])
{
case "int":
case "long":
case "short":
if(!Miscellaneous.isNumeric(etParameterValue.getText().toString()))
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
break;
case "double":
case "float":
if(!Miscellaneous.isNumericDecimal(etParameterValue.getText().toString()))
{
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enter_a_number), Toast.LENGTH_LONG).show();
return;
}
break;
default:
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeparator + etParameterName.getText().toString() + Action.intentPairSeparator + etParameterValue.getText().toString();
intentPairList.add(param);
@ -240,8 +263,10 @@ public class ActivityManageActionStartActivity extends Activity
@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"))
if(supportedIntentTypes[arg2].equals("int") || supportedIntentTypes[arg2].equals("long") || supportedIntentTypes[arg2].equals("short"))
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
else if(supportedIntentTypes[arg2].equals("double") || supportedIntentTypes[arg2].equals("float"))
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
else
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
}

View File

@ -0,0 +1,99 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
public class ActivityManageActionWakeLock extends Activity
{
RadioButton rbWakeLockActivate, rbWakeLockDeactivate;
CheckBox chkWakeLockTimeout;
EditText etWakeLockDuration;
Button bSaveWakelock;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_action_wakelock);
rbWakeLockActivate = (RadioButton)findViewById(R.id.rbWakeLockActivate);
rbWakeLockDeactivate = (RadioButton)findViewById(R.id.rbWakeLockDeactivate);
chkWakeLockTimeout = (CheckBox)findViewById(R.id.chkWakeLockTimeout);
etWakeLockDuration = (EditText)findViewById(R.id.etWakeLockDuration);
bSaveWakelock = (Button)findViewById(R.id.bSaveWakelock);
etWakeLockDuration.setEnabled(chkWakeLockTimeout.isChecked());
chkWakeLockTimeout.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean wakeLockTimeoutSet)
{
etWakeLockDuration.setEnabled(wakeLockTimeoutSet);
if(wakeLockTimeoutSet)
etWakeLockDuration.setText(String.valueOf(Actions.wakeLockTimeoutDisabled));
}
});
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter1))
{
rbWakeLockActivate.setChecked(getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, true));
rbWakeLockDeactivate.setChecked(!getIntent().getBooleanExtra(ActivityManageRule.intentNameActionParameter1, false));
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
{
if(Miscellaneous.isNumeric(getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2)))
{
long timeout = Long.parseLong((getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2)));
chkWakeLockTimeout.setChecked(timeout != Actions.wakeLockTimeoutDisabled);
etWakeLockDuration.setText(String.valueOf(timeout));
}
else
{
chkWakeLockTimeout.setChecked(false);
etWakeLockDuration.setText(String.valueOf(Actions.wakeLockTimeoutDisabled));
}
}
}
bSaveWakelock.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if(chkWakeLockTimeout.isChecked())
{
if((StringUtils.isEmpty(etWakeLockDuration.getText().toString()) || Integer.parseInt(etWakeLockDuration.getText().toString()) <= 0))
{
Toast.makeText(ActivityManageActionWakeLock.this, getResources().getString(R.string.enterAPositiveValidNonDecimalNumber), Toast.LENGTH_LONG).show();
return;
}
}
Intent response = new Intent();
response.putExtra(ActivityManageRule.intentNameActionParameter1, rbWakeLockActivate.isChecked());
if(chkWakeLockTimeout.isChecked())
response.putExtra(ActivityManageRule.intentNameActionParameter2, etWakeLockDuration.getText().toString());
else
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Actions.wakeLockTimeoutDisabled));
setResult(RESULT_OK, response);
finish();
}
});
}
}

View File

@ -129,6 +129,8 @@ public class ActivityManageRule extends Activity
final static int requestCodeActionSetWifiEdit = 816;
final static int requestCodeTriggerTetheringAdd = 817;
final static int requestCodeTriggerTetheringEdit = 818;
final static int requestCodeActionWakeLockAdd = 819;
final static int requestCodeActionWakeLockEdit = 820;
public static ActivityManageRule getInstance()
{
@ -393,6 +395,12 @@ public class ActivityManageRule extends Activity
activityEditSendBroadcastIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditSendBroadcastIntent, requestCodeActionSendBroadcastEdit);
break;
case wakelock:
Intent activityEditWakeLockIntent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
activityEditWakeLockIntent.putExtra(intentNameActionParameter1, a.getParameter1());
activityEditWakeLockIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(activityEditWakeLockIntent, requestCodeActionWakeLockEdit);
break;
case runExecutable:
Intent activityEditRunExecutableIntent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
activityEditRunExecutableIntent.putExtra(intentNameActionParameter1, a.getParameter1());
@ -876,6 +884,7 @@ public class ActivityManageRule extends Activity
return alertDialog;
}
private AlertDialog getTriggerBatteryDialog(final Context myContext, final String[] choices)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
@ -890,6 +899,7 @@ public class ActivityManageRule extends Activity
triggerBattery = (which+1);
newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
newTrigger.setBatteryLevel(triggerBattery);
newTrigger.setTriggerParameter2(String.valueOf(triggerBattery));
// Log.i("test", newTrigger.toString());
// Log.i("test", String.valueOf(newTrigger.getBatteryLevel()));
ruleToEdit.getTriggerSet().add(newTrigger);
@ -1551,6 +1561,17 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionWakeLockAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionControlMediaAdd)
{
if(resultCode == RESULT_OK)
@ -1620,6 +1641,21 @@ public class ActivityManageRule extends Activity
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionWakeLockEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
if(data.hasExtra(intentNameActionParameter1))
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, true));
if(data.hasExtra(intentNameActionParameter2))
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionRunExecutableEdit)
{
if(resultCode == RESULT_OK)
@ -1884,6 +1920,8 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Action_Enum.sendBroadcast.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.megaphone));
else if(types[i].toString().equals(Action_Enum.wakelock.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.coffee));
else if(types[i].toString().equals(Action_Enum.runExecutable.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.script));
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
@ -2058,6 +2096,12 @@ public class ActivityManageRule extends Activity
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionRunExecutable.class);
startActivityForResult(intent, requestCodeActionRunExecutableAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.wakelock.toString()))
{
newAction.setAction(Action_Enum.wakelock);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionWakeLock.class);
startActivityForResult(intent, requestCodeActionWakeLockAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.controlMediaPlayback.toString()))
{
newAction.setAction(Action_Enum.controlMediaPlayback);

View File

@ -20,15 +20,13 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import com.jens.automation2.receivers.BluetoothReceiver;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -41,10 +39,11 @@ public class ActivityManageTriggerWifi extends Activity
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
EditText etTriggerWifiName;
Spinner spinnerWifiList;
Button btriggerWifiSave, bLoadWifiList;
Button bTriggerWifiSave, bLoadWifiList;
List<String> wifiList = new ArrayList<>();
ArrayAdapter<String> wifiSpinnerAdapter;
private final static int requestCodeLocationPermission = 124;
TextView tvWifiTriggerNameLocationNotice;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
@ -56,13 +55,21 @@ public class ActivityManageTriggerWifi extends Activity
rbTriggerWifiDisconnected = (RadioButton) findViewById(R.id.rbTriggerWifiDisconnected);
etTriggerWifiName = (EditText) findViewById(R.id.etTriggerWifiName);
spinnerWifiList = (Spinner) findViewById(R.id.spinnerWifiList);
btriggerWifiSave = (Button) findViewById(R.id.btriggerWifiSave);
bTriggerWifiSave = (Button) findViewById(R.id.bTriggerWifiSave);
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
tvWifiTriggerNameLocationNotice = (TextView)findViewById(R.id.tvWifiTriggerNameLocationNotice);
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
spinnerWifiList.setEnabled(false); // bug in Android; this only works when done in code, not in xml
if(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
&&
!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
tvWifiTriggerNameLocationNotice.setVisibility(View.VISIBLE);
if (getIntent().hasExtra("edit"))
{
boolean connected = getIntent().getBooleanExtra("wifiState", false);
@ -74,7 +81,7 @@ public class ActivityManageTriggerWifi extends Activity
etTriggerWifiName.setText(wifiName);
}
btriggerWifiSave.setOnClickListener(new View.OnClickListener()
bTriggerWifiSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)

View File

@ -509,6 +509,12 @@ public class ActivityPermissions extends Activity
case wifiConnection:
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, requiredPermissions);
if(
Miscellaneous.getTargetSDK(Miscellaneous.getAnyContext()) >= 29
&&
isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, requiredPermissions);
break;
case notification:
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);

View File

@ -476,6 +476,9 @@ public class Miscellaneous extends Service
switch(direction)
{
case Trigger.directionEquals:
if(Miscellaneous.isRegularExpression(needle))
return haystack.matches(needle);
else
return haystack.equalsIgnoreCase(needle);
case Trigger.directionNotEquals:
return !haystack.equalsIgnoreCase(needle);
@ -788,6 +791,22 @@ public class Miscellaneous extends Service
return executedSuccesfully;
}
public static boolean isNumericDecimal(String strNum)
{
if (strNum == null)
{
return false;
}
try
{
double d = Double.parseDouble(strNum);
}
catch (NumberFormatException nfe)
{
return false;
}
return true;
}
public static boolean isNumeric(String str)
{
@ -1753,13 +1772,12 @@ public class Miscellaneous extends Service
public static boolean comparePhoneNumbers(String number1, String number2)
{
/* To be activated when Android S SDK comes out
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
{
TelephonyManager tm = (TelephonyManager)Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
}
else*/
else
return PhoneNumberUtils.compare(number1, number2);
}
@ -1893,4 +1911,9 @@ public class Miscellaneous extends Service
return null;
}
public static int getTargetSDK(Context context)
{
return context.getApplicationContext().getApplicationInfo().targetSdkVersion;
}
}

View File

@ -1,6 +1,7 @@
package com.jens.automation2;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.os.Build;
import android.service.notification.StatusBarNotification;
@ -728,7 +729,8 @@ public class Trigger
if(this.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format("Wifi name specified, checking that.", this.getParentRule().getName()), 4);
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()))
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(this.getTriggerParameter2()) && !(Miscellaneous.isRegularExpression(this.getTriggerParameter2()) && WifiBroadcastReceiver.getLastWifiSsid().matches(this.getTriggerParameter2())))
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), getParentRule().getName(), this.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()),this.getParentRule().getName()), 3);
return false;
@ -794,9 +796,15 @@ public class Trigger
boolean checkBatteryLevel()
{
/*
-1 means value is not known, yet.
*/
if(BatteryReceiver.getBatteryLevel() == -1)
return false;
if(this.getTriggerParameter())
{
if(BatteryReceiver.getBatteryLevel() <= this.getBatteryLevel())
if(BatteryReceiver.getBatteryLevel() < this.getBatteryLevel())
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(this.getBatteryLevel()), this.getParentRule().getName()), 3);
return false;
@ -804,7 +812,7 @@ public class Trigger
}
else
{
if(this.getBatteryLevel() >= this.getBatteryLevel())
if(BatteryReceiver.getBatteryLevel() >= this.getBatteryLevel())
{
Miscellaneous.logEvent("i", Miscellaneous.getAnyContext().getResources().getString(R.string.ruleCheckOf), String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(this.getBatteryLevel()), this.getParentRule().getName()), 3);
return false;

View File

@ -63,7 +63,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
// int state = -1;
NetworkInfo myWifi = null;
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) //gefeuert bei Trennung
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) // fired upon disconnection
{
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));

View File

@ -2,6 +2,7 @@ package com.jens.automation2.receivers;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.IntentFilter;
import android.os.Build;
@ -149,51 +150,6 @@ public class NotificationListener extends NotificationListenerService// implemen
return returnNotification;
}
/*@Override
public void startListener(AutomationService automationService)
{
if(instance == null)
instance = new NotificationListener();
if(notificationReceiverIntentFilter == null)
{
notificationReceiverIntentFilter = new IntentFilter();
notificationReceiverIntentFilter.addAction("android.service.notification.NotificationListenerService");
}
try
{
if(!listenerRunning)
{
Miscellaneous.logEvent("i", "NotificationListener", "Starting NotificationListener", 4);
listenerRunning = true;
AutomationService.getInstance().registerReceiver(instance, notificationReceiverIntentFilter);
}
}
catch(Exception ex)
{
Miscellaneous.logEvent("e", "BluetoothReceiver", "Error starting BluetoothReceiver: " + Log.getStackTraceString(ex), 3);
}
}
@Override
public void stopListener(AutomationService automationService)
{
}
@Override
public boolean isListenerRunning()
{
return false;
}
@Override
public Trigger.Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger.Trigger_Enum[0];
}*/
public static class SimpleNotification
{
boolean created;
@ -283,4 +239,32 @@ public class NotificationListener extends NotificationListenerService// implemen
cancelNotification(sbn.getKey());
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void clickNotificationButton(StatusBarNotification sbn, String buttonText)
{
boolean buttonFound = false;
for (Notification.Action a : sbn.getNotification().actions)
{
if(a.toString().equalsIgnoreCase(buttonText))
{
if(!buttonFound)
buttonFound = true;
try
{
Miscellaneous.logEvent("w", "clickNotificationButton()", "Pressing button with text \"" + a.title.toString() + "\".", 2);
a.actionIntent.send();
}
catch (PendingIntent.CanceledException e)
{
Miscellaneous.logEvent("w", "clickNotificationButton()", Log.getStackTraceString(e), 2);
}
}
}
if(!buttonFound)
Miscellaneous.logEvent("w", "clickNotificationButton()", "Button with text \n" + buttonText + "\n could not found.", 2);
}
}

View File

@ -22,8 +22,6 @@ import java.util.ArrayList;
public class PhoneStatusListener implements AutomationListenerInterface
{
// protected static int currentStateIncoming = -1;
// protected static int currentStateOutgoing = -1;
protected static String lastPhoneNumber="";
protected static int lastPhoneDirection = -1; //0=incoming, 1=outgoing
protected static int currentState = -1;
@ -120,8 +118,6 @@ public class PhoneStatusListener implements AutomationListenerInterface
}
else
{
// state != TelephonyManager.CALL_STATE_IDLE &&
setCurrentState(state);
setLastPhoneDirection(1);
@ -175,7 +171,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
for(int i=0; i<ruleCandidates.size(); i++)
for(int i = 0; i < ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 679 B

After

Width:  |  Height:  |  Size: 679 B

View File

@ -100,6 +100,7 @@
android:id="@+id/bSendEmailToDev"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/sendEmailToDev" />
<TextView

View File

@ -76,6 +76,14 @@
android:text="@string/comparisonCaseInsensitive"
android:layout_marginBottom="@dimen/default_margin"/>
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/regularExpressionsIfEquals"
android:layout_marginBottom="@dimen/default_margin"/>
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">

View File

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

View File

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

View File

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

View File

@ -688,7 +688,7 @@
<string name="screenIs">Bildschirm ist %1$s</string>
<string name="sendEmailToDev">Email an Entwickler schicken</string>
<string name="controlCenter">Steuerungszentrale</string>
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.</string>
<string name="emailContactNotice">Email ist mein bevorzugtes Kommunikationsmittel, um Fehler zu melden, Fragen zu stellen or Vorschläge zu machen. Bitte gehen Sie für weitere Infos in die Steuerungszentrale.\nViele Fragen können nicht einfach gleich beantwortet werden, sondern erfordern eine technische Prüfung. Haben Sie also bitte etwas Geduld.</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Aufgrund Google\'s unendlicher Weisheit, ist die letzte Android Version, mit der diese Funktion noch funktioniert, die Version %1$s. Sie können es hier einrichten, aber vermutlich wird es keine Auswirkung haben.</string>
<string name="musicPlaying">Musik läuft</string>
<string name="selectParameters">Wählen Sie die Parameter</string>
@ -737,4 +737,9 @@
<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>
<string name="regularExpressionsIfEquals">Falls \"ist gleich\" ausgewählt ist, können Sie reguläre Ausdrücke eingeben.</string>
<string name="enter_a_number">Geben Sie eine Zahl ein.</string>
<string name="duration">Dauer [ms]</string>
<string name="keepDeviceAwake">Gerät wach halten</string>
<string name="wakeLockTimeout">Zeitlimit angeben</string>
</resources>

View File

@ -687,7 +687,7 @@
<string name="screenIs">pantalla esta %1$s</string>
<string name="sendEmailToDev">Enviar email al desrollador</string>
<string name="featureCeasedToWorkLastWorkingAndroidVersion">Debido a la infinita sabiduría de Google, la última versión de Android en la que se sabe que funciona esta función es %1$s. Puede configurarlo, pero probablemente no tendrá ningún efecto.</string>
<string name="emailContactNotice">El correo electrónico es mi método preferido de contacto para informar errores, hacer preguntas o hacer propuestas. Vaya al centro de control para obtener más información.</string>
<string name="emailContactNotice">El correo electrónico es mi método preferido de contacto para informar errores, hacer preguntas o hacer propuestas. Vaya al centro de control para obtener más información.\nMuchas preguntas no se pueden responder de inmediato, pero requieren cierta investigación técnica. Así que, por favor, tengan un poco de paciencia.</string>
<string name="actionMediaControlNotice">Ten en cuenta que esta acción puede no funcionar con TODOS los jugadores. E incluso si lo hace, no todos los botones funcionan necesariamente.</string>
<string name="musicPlaying">Musica esta reproduciendo</string>
<string name="selectParameters">Elije parametros</string>
@ -722,4 +722,9 @@
<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>
<string name="enter_a_number">Introduzca un número.</string>
<string name="regularExpressionsIfEquals">Si se selecciona \"igual\", puede introducir una expresión regular.</string>
<string name="duration">Duración [ms]</string>
<string name="keepDeviceAwake">Mantenga el dispositivo despierto</string>
<string name="wakeLockTimeout">Especificar el tiempo de espera</string>
</resources>

View File

@ -689,7 +689,7 @@
<string name="screenIs">lo schermo è %1$s</string>
<string name="sendEmailToDev">Invia email allo sviluppatore</string>
<string name="controlCenter">Centro di controllo</string>
<string name="emailContactNotice">L\'e-mail è il mio metodo di contatto preferito per segnalare bug, porre domande o fare proposte. Vai al centro di controllo per saperne di più.</string>
<string name="emailContactNotice">L\'e-mail è il mio metodo di contatto preferito per segnalare bug, porre domande o fare proposte. Vai al centro di controllo per saperne di più.\nMolte domande non possono essere risolte immediatamente, ma richiedono alcune ricerche tecniche. Quindi, per favore, abbiate un po\' di pazienza.</string>
<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>
@ -737,4 +737,9 @@
<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>
<string name="enter_a_number">Inserisci un numero.</string>
<string name="regularExpressionsIfEquals">Se è selezionato \"uguale\", è possibile immettere un\'espressione regolare.</string>
<string name="duration">Durata [ms]</string>
<string name="keepDeviceAwake">Mantieni il dispositivo attivo</string>
<string name="wakeLockTimeout">Specificare il timeout</string>
</resources>

View File

@ -667,7 +667,7 @@
<string name="comparisonCaseInsensitive">Vergelijkingen worden gedaan case-INsensitief</string>
<string name="profileWarning">De instellingen die je hier maakt kunnen ervoor zorgen dat je bepaalde dingen niet meer van je telefoon merkt. Ze kunnen zelfs je wekker dempen. Dus wat je ook doet - het wordt aanbevolen om het te testen - ook na Android upgrades.</string>
<string name="ifString">als</string>
<string name="emailContactNotice">E-mail is mijn favoriete contactmethode om bugs te melden, vragen te stellen of voorstellen te doen. Ga naar het controlecentrum voor meer informatie.</string>
<string name="emailContactNotice">E-mail is mijn favoriete contactmethode om bugs te melden, vragen te stellen of voorstellen te doen. Ga naar het controlecentrum voor meer informatie.\nVeel vragen kunnen niet meteen worden beantwoord, maar vereisen wel wat technisch onderzoek. Dus heb alsjeblieft wat geduld.</string>
<string name="controlCenter">Controlecentrum</string>
<string name="sendEmailToDev">Stuur een e-mail naar de ontwikkelaar</string>
<string name="screenIs">scherm is %1$s</string>
@ -735,5 +735,10 @@
<string name="tetheringActive">tethering is actief</string>
<string name="tetheringNotActive">tethering is niet actief</string>
<string name="tetheringState">Tethering-status</string>
<string name="enter_a_number">Voer een getal in.</string>
<string name="regularExpressionsIfEquals">Als \'gelijk aan\' is geselecteerd, kunt u een reguliere expressie invoeren.</string>
<string name="duration">Duur [ms]</string>
<string name="keepDeviceAwake">Houd het apparaat wakker</string>
<string name="wakeLockTimeout">Time-out opgeven</string>
</resources>

View File

@ -671,7 +671,6 @@
<string name="from">от</string>
<string name="to">к</string>
<string name="matching">совпадает</string>
<string name="urlRegex" translatable="false">https://regex101.com/</string>
<string name="loadWifiList">Загрузить список Wi-Fi</string>
<string name="needLocationPermForWifiList">Список Wi-Fi, к которому было подключено ваше устройство. Можно использовать для определения того, в каких местах вы были. Вот почему для загрузки списка Wi-Fi требуется разрешение на доступ к местоположению. Если вы хотите выбрать один из из списка, вам необходимо предоставить это разрешение. Если вы этого не хотите, вы все равно можете ввести свое имя Wi-Fi вручную.</string>
<string name="noKnownWifis">На вашем устройстве нет известных Wi-Fi.</string>
@ -765,7 +764,7 @@
<string name="comparisonCaseInsensitive">Сравнения проводятся без учета регистра</string>
<string name="profileWarning">Настройки, которые вы можете изменить здесь, могут привести к тому, что вы больше не заметите определенных вещей с вашего телефона. Они могут даже отключить будильник. Так что что бы вы ни делали - рекомендуется это проверять.</string>
<string name="ifString">если</string>
<string name="emailContactNotice">Электронная почта - мой предпочтительный способ связи, для сообщений об ошибках, вопросов или предложений. Перейдите в центр управления, чтобы узнать больше.</string>
<string name="emailContactNotice">Электронная почта - мой предпочтительный способ связи, для сообщений об ошибках, вопросов или предложений. Перейдите в центр управления, чтобы узнать больше.\nМногие вопросы не могут быть решены сразу, но требуют некоторых технических исследований. Поэтому, пожалуйста, наберитесь терпения.</string>
<string name="controlCenter">Центр управления</string>
<string name="sendEmailToDev">Отправить электронное письмо разработчику</string>
<string name="screenIs">экран %1$s</string>
@ -833,4 +832,9 @@
<string name="tetheringActive">раздача интернета активна</string>
<string name="tetheringNotActive">раздача интернета не активна</string>
<string name="tetheringState">Раздача интернета</string>
<string name="enter_a_number">Введите число.</string>
<string name="regularExpressionsIfEquals">Если выбрано значение \"равно\", можно ввести регулярное выражение.</string>
<string name="duration">продолжительность [мс]</string>
<string name="keepDeviceAwake">Держите устройство в режиме сна</string>
<string name="wakeLockTimeout">указать время ожидания</string>
</resources>

View File

@ -766,7 +766,7 @@
<string name="comparisonCaseInsensitive">Comparisons are done case-INsensitive</string>
<string name="profileWarning">The settings you can adjust here, can cause that you don\'t notice certain things from your phone anymore. They may even silence your wakeup alarm. So whatever you do - it is highly recommended that you test it - also after Android updates.</string>
<string name="ifString">if</string>
<string name="emailContactNotice">Email is my preferred method of contact to report bugs, ask questions or make proposals. Go to control center to learn more.</string>
<string name="emailContactNotice">Email is my preferred method of contact to report bugs, ask questions or make proposals. Go to control center to learn more.\nMany questions cannot be answered straight away, but require some technical research. So please have some patience.</string>
<string name="controlCenter">Control center</string>
<string name="sendEmailToDev">Send email to developer</string>
<string name="screenIs">screen is %1$s</string>
@ -834,4 +834,12 @@
<string name="tetheringActive">tethering is active</string>
<string name="tetheringNotActive">tethering is not active</string>
<string name="tetheringState">Tethering state</string>
<string name="regularExpressionsIfEquals">If \"equals\" is selected, you may enter a regular expression.</string>
<string name="enter_a_number">Enter a number.</string>
<string name="duration">Duration [ms]</string>
<string name="keepDeviceAwake">Keep device awake</string>
<string name="wakeLockTimeout">Specify timeout</string>
<string name="wakeLockExplanation">Activate will keep the screen on while deactivate will let it turn off. For keeping it on you can either enter a duration after which it may turn off again or you can keep it on indefinitely. In the latter case you would need to create another keep-awake action (in this or another rule) in which you select deactivate.</string>
<string name="mayUseRegularExpressions">You may also enter a regular expression here.</string>
<string name="locationRequiredToDetermineWifiName">To get the wifi SSID, the app requires location permissions. Because the Google version cannot get that, you can only use this trigger if you do not specify an SSID. So it can only be used to detect if wifi is connected or not.</string>
</resources>

View File

@ -54,7 +54,7 @@ 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).
* 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.
* Außerdem ist immer Hilfe bei der Übersetzung willkommen. Englisch, Spanisch und Deutsch kann ich selbst, Italienisch und Russisch sind 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.

View File

@ -0,0 +1,5 @@
* New action: Keep phone turned on
* New: Regular expressions enabled where comparisons apply (one has to use "equals")
* Fixed: Changed input type for decimal numbers when adding intent data
* Fixed: Battery level trigger not working when using direction falling-below
* New: Wifi trigger can now use Regex for SSID

View File

@ -54,7 +54,7 @@ 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).
* 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.
* Furthermore I can always use help in translating the app. English, German and some Spanish are among my own skills. Italiano e russo sono già coperti. 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.

View File

@ -54,7 +54,7 @@ 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).
* 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.
* Además siempre necesito ayuda en traduciendo la app. Ingles, Aleman y Español estan en mis habilidades. Todavia tengo ayuda con Italiono y Ruso. 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.

View File

@ -57,7 +57,7 @@ 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 ).
* 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.
* Verder kan ik altijd hulp gebruiken bij het vertalen van de app. Engels, Duits en wat Spaans behoren tot mijn eigen vaardigheden. Italiaans en Russisch zijn al 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.