17 Commits

Author SHA1 Message Date
a21f90acb5 Wifi receiver 2023-12-21 23:16:21 +01:00
5f8ed5765a TriggerUrl result stored in variable 2023-12-21 16:40:11 +01:00
605f85d215 Howto for write_secure_settings linked and translations updated 2023-12-21 15:37:55 +01:00
21f4a7fd5c Set location service 2023-12-20 23:54:36 +01:00
2219164869 Set location service 2023-12-19 23:52:28 +01:00
a8646ef61d Merge branch 'accessibility_api' into development
# Conflicts:
#	app/src/main/java/com/jens/automation2/Actions.java
2023-12-19 16:54:52 +01:00
f641de9893 Take screenshot action added 2023-12-19 16:54:10 +01:00
bca8b44ad6 Bugfix for Android 14 for auto dialing mmi codes 2023-12-18 23:13:18 +01:00
c34dfa4af4 Bugfix for Android 14 for auto dialing mmi codes 2023-12-18 22:55:18 +01:00
38644cee28 Take screenshot action added 2023-12-16 13:52:18 +01:00
47898e84ea Comment added 2023-12-14 17:46:55 +01:00
ac74b52aed Accessibility API 2023-12-14 00:15:59 +01:00
3f76813e80 Http method selectable 2023-12-12 23:40:12 +01:00
1b8dc5de5f Http method selectable 2023-12-11 22:50:07 +01:00
3c8c0f14f2 Fixed bug in broadcast receiver trigger 2023-12-06 23:44:40 +01:00
9ead47bdf7 Permissions for startActivity() reduced 2023-12-03 23:24:58 +01:00
e4828a9720 Fixes for Google Play version 2023-11-30 00:00:34 +01:00
40 changed files with 919 additions and 127 deletions

View File

@ -11,8 +11,8 @@ android {
compileSdkVersion 31
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 136
versionName "1.7.19"
versionCode 138
versionName "1.7.21"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<supports-screens
android:anyDensity="true"
@ -50,7 +52,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@ -70,6 +71,10 @@
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-feature
android:name="android.hardware.telephony"
@ -179,6 +184,7 @@
<activity android:name=".ActivityManageActionSetVariable" />
<activity android:name=".ActivityManageTriggerCheckVariable" />
<activity android:name=".ActivityManageActionCopyToClipboard" />
<activity android:name=".ActivityManageActionLocationService" />
<activity
android:name=".ActivityMainTabLayout"
@ -261,6 +267,17 @@
android:exported="true"
/>
<service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/config_accessibility_service" />
</service>
</application>
</manifest>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<supports-screens
android:anyDensity="true"
@ -50,7 +52,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@ -68,6 +69,9 @@
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-feature
android:name="android.hardware.telephony"
@ -177,6 +181,8 @@
<activity android:name=".ActivityManageActionSetVariable" />
<activity android:name=".ActivityManageTriggerCheckVariable" />
<activity android:name=".ActivityManageActionCopyToClipboard" />
<activity android:name=".ActivityManageActionLocationService" />
<activity
android:name=".ActivityMainTabLayout"
android:launchMode="singleTask">
@ -246,6 +252,17 @@
android:exported="true"
/>
<service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/config_accessibility_service" />
</service>
</application>
</manifest>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<supports-screens
android:anyDensity="true"
@ -49,7 +51,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.NFC" />
@ -65,6 +66,9 @@
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
@ -162,6 +166,8 @@
<activity android:name=".ActivityManageActionSetVariable" />
<activity android:name=".ActivityManageTriggerCheckVariable" />
<activity android:name=".ActivityManageActionCopyToClipboard" />
<activity android:name=".ActivityManageActionLocationService" />
<activity
android:name=".ActivityMainTabLayout"
android:exported="true"
@ -245,6 +251,17 @@
android:exported="true"
/>
<service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/config_accessibility_service" />
</service>
</application>
</manifest>

View File

@ -7,7 +7,6 @@ import android.util.Log;
import android.widget.Toast;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import java.util.ArrayList;
import java.util.Locale;
@ -56,6 +55,8 @@ public class Action
startPhoneCall,
stopPhoneCall,
copyToClipboard,
takeScreenshot,
setLocationService,
sendTextMessage;
public String getFullName(Context context)
@ -140,6 +141,10 @@ public class Action
return context.getResources().getString(R.string.endPhoneCall);
case copyToClipboard:
return context.getResources().getString(R.string.copyTextToClipboard);
case takeScreenshot:
return context.getResources().getString(R.string.takeScreenshot);
case setLocationService:
return context.getResources().getString(R.string.setLocationService);
default:
return "Unknown";
}
@ -307,6 +312,28 @@ public class Action
break;
case copyToClipboard:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.copyTextToClipboard));
break;
case takeScreenshot:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.takeScreenshot));
break;
case setLocationService:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.setLocationService) + ": " );
switch(Integer.parseInt(getParameter2()))
{
case android.provider.Settings.Secure.LOCATION_MODE_OFF:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.off));
break;
case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_SENSOR_ONLY));
break;
case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_BATTERY_SAVING));
break;
case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.LOCATION_MODE_HIGH_ACCURACY));
break;
}
break;
default:
returnString.append(action.toString());
}
@ -414,7 +441,7 @@ public class Action
{
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; ").replace(Action.intentPairSeparator, "/"));
}
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard))
else if(this.getAction().equals(Action_Enum.setVariable) || this.getAction().equals(Action_Enum.copyToClipboard) || this.getAction().equals(Action_Enum.setLocationService))
; // it's completed further above already
else if (parameter2 != null && parameter2.length() > 0)
returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; "));
@ -632,6 +659,12 @@ public class Action
case copyToClipboard:
Actions.copyToClipboard(context, Miscellaneous.replaceVariablesInText(this.getParameter2(), context));
break;
case takeScreenshot:
Actions.takeScreenshot();
break;
case setLocationService:
Actions.setLocationService(Integer.parseInt(this.getParameter2()), AutomationService.getInstance());
break;
default:
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
break;
@ -648,6 +681,7 @@ public class Action
{
String username = null;
String password = null;
String method = ActivityManageActionTriggerUrl.methodGet;
String url;
String[] components = getParameter2().split(";");
@ -657,6 +691,9 @@ public class Action
username = components[0];
password = components[1];
url = components[2];
if(components.length >= 4)
method = components[3];
}
else // compatibility for very old versions which haven't upgraded, yet.
url = components[0];
@ -670,7 +707,7 @@ public class Action
Miscellaneous.logEvent("i", "HTTP", "Attempting download of " + url, 4); //getResources().getString("attemptingDownloadOf");
if(this.getParameter1()) // use authentication
new DownloadTask().execute(url, username, password);
new DownloadTask().execute(url, username, password, method);
else
new DownloadTask().execute(url, null, null);
}
@ -692,16 +729,19 @@ public class Action
String urlUsername = null;
String urlPassword = null;
String method = ActivityManageActionTriggerUrl.methodGet;
if(parameters.length >= 3)
{
urlUsername=parameters[1];
urlPassword=parameters[2];
urlUsername = parameters[1];
urlPassword = parameters[2];
if(parameters.length >= 4)
method = parameters[3];
}
String response = "httpError";
HttpGet post;
if(Settings.httpAttempts < 1)
String response = "HTTP_ERROR";
if(Settings.httpAttempts < 1)
Miscellaneous.logEvent("w", "HTTP Request", Miscellaneous.getAnyContext().getResources().getString(R.string.cantDownloadTooFewRequestsInSettings), 3);
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
@ -710,9 +750,9 @@ public class Action
// Either thorough checking or no encryption
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method);
else
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword, method);
try
{

View File

@ -1,6 +1,7 @@
package com.jens.automation2;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.NotificationManager;
@ -985,6 +986,7 @@ public class Actions
public void useDownloadedWebpage(String result)
{
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
Actions.setVariable("LAST_TRIGGERURL_RESULT" + Action.actionParameter2Split + result);
}
public static HttpClient getInsecureSslClient(HttpClient client)
@ -1043,7 +1045,12 @@ public class Actions
{
Miscellaneous.logEvent("i", "StartOtherActivity", "Starting other Activity...", 4);
String params[] = param.split(";");
String params[];
if(param.contains(Action.actionParameter2Split))
params = param.split(Action.actionParameter2Split);
else
params = param.split(";");
try
{
@ -2281,7 +2288,18 @@ public class Actions
public static void startPhoneCall(Context context, String phoneNumber)
{
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
Intent intent;
/*
Bug in Android 14 makes it necessary to add double quotes around MMI code.
More precisely it's required for codes containing the # character.
*/
if(Build.VERSION.SDK_INT >= 34)
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode("\"" + phoneNumber + "\"")));
else
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
// intent.setClassName("com.android.phone","com.android.phone.OutgoingCallBroadcaster");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
@ -2334,4 +2352,26 @@ public class Actions
clipboard.setPrimaryClip(clip);
}
}
public static void takeScreenshot()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
{
MyAccessibilityService.getInstance().performGlobalAction(AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
}
}
public static void setLocationService(int desiredState, Context context)
{
// if(desiredState)
// {
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY).toString());
// }
// else
// {
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_OFF).toString());
// }
android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState));
}
}

View File

@ -0,0 +1,75 @@
package com.jens.automation2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import androidx.annotation.Nullable;
public class ActivityManageActionLocationService extends Activity
{
RadioButton rbActionLocationServiceOff, rbActionLocationServiceSensorsOnly, rbActionLocationServiceBatterySaving, rbActionLocationServiceHighAccuracy;
Button bActionSetLocationServiceSave;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Miscellaneous.setDisplayLanguage(this);
setContentView(R.layout.activity_manage_action_location_service);
rbActionLocationServiceOff = (RadioButton) findViewById(R.id.rbActionLocationServiceOff);
rbActionLocationServiceSensorsOnly = (RadioButton)findViewById(R.id.rbActionLocationServiceSensorsOnly);
rbActionLocationServiceBatterySaving = (RadioButton)findViewById(R.id.rbActionLocationServiceBatterySaving);
rbActionLocationServiceHighAccuracy = (RadioButton)findViewById(R.id.rbActionLocationServiceHighAccuracy);
bActionSetLocationServiceSave = (Button) findViewById(R.id.bActionSetLocationServiceSave);
Intent input = getIntent();
if(input.hasExtra(ActivityManageRule.intentNameActionParameter2))
{
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(Action.actionParameter2Split);
int desiredState = Integer.parseInt(params[0]);
switch(desiredState)
{
case Settings.Secure.LOCATION_MODE_OFF:
rbActionLocationServiceOff.setChecked(true);
break;
case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
rbActionLocationServiceSensorsOnly.setChecked(true);
break;
case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
rbActionLocationServiceBatterySaving.setChecked(true);
break;
case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
rbActionLocationServiceHighAccuracy.setChecked(true);
break;
}
}
bActionSetLocationServiceSave.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent response = new Intent();
if(rbActionLocationServiceOff.isChecked())
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_OFF));
else if(rbActionLocationServiceSensorsOnly.isChecked())
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_SENSORS_ONLY));
else if(rbActionLocationServiceBatterySaving.isChecked())
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_BATTERY_SAVING));
else
response.putExtra(ActivityManageRule.intentNameActionParameter2, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
setResult(RESULT_OK, response);
finish();
}
});
}
}

View File

@ -58,10 +58,10 @@ public class ActivityManageActionStartActivity extends Activity
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast, rbStartAppByService, rbStartAppByForegroundService;
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
final static String startByActivityString = "0";
final static String startByBroadcastString = "1";
final static String startByServiceString = "2";
final static String startByForegroundServiceString = "3";
public final static String startByActivityString = "0";
public final static String startByBroadcastString = "1";
public final static String startByServiceString = "2";
public final static String startByForegroundServiceString = "3";
final static int requestCodeForRequestQueryAllPackagesPermission = 4711;
@ -234,29 +234,29 @@ public class ActivityManageActionStartActivity extends Activity
String parameter2 = "";
if (rbStartAppSelectByActivity.isChecked())
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
else
{
if (etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
parameter2 += etPackageName.getText().toString() + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
else
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
parameter2 += Actions.dummyPackageString + Action.actionParameter2Split + etActivityOrActionPath.getText().toString();
// if(etClassName.getText().toString().length() > 0)
parameter2 += ";" + etClassName.getText().toString();
parameter2 += Action.actionParameter2Split + etClassName.getText().toString();
}
if (rbStartAppByActivity.isChecked())
parameter2 += ";" + startByActivityString;
parameter2 += Action.actionParameter2Split + startByActivityString;
else if(rbStartAppByService.isChecked())
parameter2 += ";" + startByServiceString;
parameter2 += Action.actionParameter2Split + startByServiceString;
else if(rbStartAppByForegroundService.isChecked())
parameter2 += ";" + startByForegroundServiceString;
parameter2 += Action.actionParameter2Split + startByForegroundServiceString;
else
parameter2 += ";" + startByBroadcastString;
parameter2 += Action.actionParameter2Split + startByBroadcastString;
for (String s : intentPairList)
parameter2 += ";" + s;
parameter2 += Action.actionParameter2Split + s;
returnData.putExtra(ActivityManageRule.intentNameActionParameter2, parameter2);
@ -628,7 +628,13 @@ public class ActivityManageActionStartActivity extends Activity
rbStartAppSelectByActivity.setChecked(!selectionByAction);
rbStartAppSelectByAction.setChecked(selectionByAction);
String[] params = input.getStringExtra(ActivityManageRule.intentNameActionParameter2).split(";");
String[] params;
String partsString = input.getStringExtra(ActivityManageRule.intentNameActionParameter2);
if(partsString.contains(Action.actionParameter2Split))
params = partsString.split(Action.actionParameter2Split);
else
params = partsString.split(";");
if(Miscellaneous.isNumeric(params[2])) // old configuration file
{

View File

@ -13,6 +13,7 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TableLayout;
import android.widget.Toast;
@ -26,11 +27,15 @@ public class ActivityManageActionTriggerUrl extends Activity
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
ListView lvTriggerUrlPostParameters;
CheckBox chkTriggerUrlUseAuthentication;
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
TableLayout tlTriggerUrlAuthentication;
ArrayAdapter<Map<String,String>> lvTriggerUrlPostParametersAdapter;
// private String existingUrl = "";
public static final String methodGet = "GET";
public static final String methodPost = "POST";
public static boolean edit = false;
public static Action resultingAction = null;
@ -49,6 +54,9 @@ public class ActivityManageActionTriggerUrl extends Activity
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveSpeakText);
rbTriggerUrlMethodGet = (RadioButton) findViewById(R.id.rbTriggerUrlMethodGet);
rbTriggerUrlMethodPost = (RadioButton) findViewById(R.id.rbTriggerUrlMethodPost);
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
{
@Override
@ -59,6 +67,8 @@ public class ActivityManageActionTriggerUrl extends Activity
if(resultingAction == null)
{
resultingAction = new Action();
}
resultingAction.setAction(Action_Enum.triggerUrl);
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
@ -70,13 +80,18 @@ public class ActivityManageActionTriggerUrl extends Activity
if(password == null)
password = "";
String method = methodGet;
if(rbTriggerUrlMethodPost.isChecked())
method = methodPost;
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
username + ";" +
password + ";" +
etTriggerUrl.getText().toString().trim()
etTriggerUrl.getText().toString().trim() + ";" +
method
);
}
backToRuleManager();
}
else
@ -84,16 +99,25 @@ public class ActivityManageActionTriggerUrl extends Activity
}
});
chkTriggerUrlUseAuthentication.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
{
tlTriggerUrlAuthentication.setVisibility(View.VISIBLE);
rbTriggerUrlMethodGet.setChecked(false);
rbTriggerUrlMethodPost.setChecked(true);
rbTriggerUrlMethodGet.setEnabled(false);
rbTriggerUrlMethodPost.setEnabled(false);
}
else
{
tlTriggerUrlAuthentication.setVisibility(View.GONE);
rbTriggerUrlMethodGet.setEnabled(true);
rbTriggerUrlMethodPost.setEnabled(true);
}
etTriggerUrlUsername.setEnabled(isChecked);
etTriggerUrlPassword.setEnabled(isChecked);
@ -109,7 +133,6 @@ public class ActivityManageActionTriggerUrl extends Activity
}
});
updateListView();
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
if(edit)
@ -123,6 +146,20 @@ public class ActivityManageActionTriggerUrl extends Activity
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
etTriggerUrlUsername.setText(components[0]);
etTriggerUrlPassword.setText(components[1]);
if(components.length >= 4)
{
switch(components[3])
{
case methodPost:
rbTriggerUrlMethodPost.setChecked(true);
break;
case methodGet:
default:
rbTriggerUrlMethodGet.setChecked(true);
break;
}
}
}
else
etTriggerUrl.setText(components[0]);
@ -141,13 +178,18 @@ public class ActivityManageActionTriggerUrl extends Activity
if(password == null)
password = "";
String method = methodGet;
if(rbTriggerUrlMethodPost.isChecked())
method = methodPost;
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
username + ";" +
password + ";" +
etTriggerUrl.getText().toString()
etTriggerUrl.getText().toString() + ";" +
method
);
}

View File

@ -141,6 +141,8 @@ public class ActivityManageRule extends Activity
final static int requestCodeTriggerCheckVariableEdit = 828;
final static int requestCodeActionCopyTextToClipboardAdd = 829;
final static int requestCodeActionCopyTextToClipboardEdit = 830;
final static int requestCodeActionSetLocationServiceAdd = 831;
final static int requestCodeActionSetLocationServiceEdit = 832;
public static ActivityManageRule getInstance()
{
@ -478,6 +480,12 @@ public class ActivityManageRule extends Activity
actionCopyToClipboardIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionCopyToClipboardIntent, requestCodeActionCopyTextToClipboardEdit);
break;
case setLocationService:
Intent actionSetLocationServiceIntent = new Intent(context, ActivityManageActionLocationService.class);
// actionSetLocationServiceIntent.putExtra(intentNameActionParameter1, a.getParameter1());
actionSetLocationServiceIntent.putExtra(intentNameActionParameter2, a.getParameter2());
startActivityForResult(actionSetLocationServiceIntent, requestCodeActionSetLocationServiceEdit);
break;
default:
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
break;
@ -2047,6 +2055,32 @@ public class ActivityManageRule extends Activity
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetLocationServiceAdd)
{
if(resultCode == RESULT_OK)
{
newAction.setParentRule(ruleToEdit);
// newAction.setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
newAction.setParameter2(data.getStringExtra(intentNameActionParameter2));
ruleToEdit.getActionSet().add(newAction);
this.refreshActionList();
}
}
else if(requestCode == requestCodeActionSetLocationServiceEdit)
{
if(resultCode == RESULT_OK)
{
ruleToEdit.getActionSet().get(editIndex).setParentRule(ruleToEdit);
// ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra(intentNameActionParameter1, false));
if(data.hasExtra(intentNameActionParameter2))
{
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra(intentNameActionParameter2));
}
this.refreshActionList();
}
}
@ -2126,6 +2160,10 @@ public class ActivityManageRule extends Activity
}
else if(types[i].toString().equals(Action_Enum.copyToClipboard.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.clipboard));
else if(types[i].toString().equals(Action_Enum.takeScreenshot.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.copier));
else if(types[i].toString().equals(Action_Enum.setLocationService.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.compass_small));
else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
}
@ -2352,6 +2390,18 @@ public class ActivityManageRule extends Activity
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionCopyToClipboard.class);
startActivityForResult(intent, requestCodeActionCopyTextToClipboardAdd);
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.takeScreenshot.toString()))
{
newAction.setAction(Action_Enum.takeScreenshot);
ruleToEdit.getActionSet().add(newAction);
refreshActionList();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setLocationService.toString()))
{
newAction.setAction(Action_Enum.setLocationService);
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionLocationService.class);
startActivityForResult(intent, requestCodeActionSetLocationServiceAdd);
}
}
});

View File

@ -18,6 +18,8 @@ import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.text.Html;
import android.text.TextUtils;
import android.text.util.Linkify;
import android.util.Log;
import android.view.View;
import android.widget.Button;
@ -51,12 +53,13 @@ public class ActivityPermissions extends Activity
private static final int requestCodeForPermissionsBatteryOptimization = 12048;
private static final int requestCodeForPermissionNotificationAccessAndroid13 = 12049;
private static final int requestCodeForPermissionsManageOverlay = 12050;
private static final int requestCodeForPermissionsAccessibility = 12051;
protected String[] specificPermissionsToRequest = null;
public static String intentExtraName = "permissionsToBeRequested";
Button bCancelPermissions, bRequestPermissions;
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong;
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong, tvRestrictionPermissionsNotice;
static ActivityPermissions instance = null;
public final static String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
@ -87,6 +90,7 @@ public class ActivityPermissions extends Activity
tvPermissionsExplanation = (TextView)findViewById(R.id.tvPermissionsExplanation);
tvPermissionsExplanationSystemSettings = (TextView)findViewById(R.id.tvPermissionsExplanationSystemSettings);
tvPermissionsExplanationLong = (TextView)findViewById(R.id.tvPermissionsExplanationLong);
tvRestrictionPermissionsNotice = (TextView)findViewById(R.id.tvRestrictionPermissionsNotice);
bCancelPermissions.setOnClickListener(new View.OnClickListener()
{
@ -161,7 +165,7 @@ public class ActivityPermissions extends Activity
/*
Filter location permission and only name it once
*/
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) | s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) || s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
{
if(!locationPermissionExplained)
{
@ -305,6 +309,10 @@ public class ActivityPermissions extends Activity
{
return android.provider.Settings.canDrawOverlays(Miscellaneous.getAnyContext());
}
else if(s.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
{
return haveAccessibilityAccess(Miscellaneous.getAnyContext());
}
else
{
int res = context.checkCallingOrSelfPermission(s);
@ -323,11 +331,59 @@ public class ActivityPermissions extends Activity
return active;
}
public static boolean haveAccessibilityAccess(Context mContext)
{
int accessibilityEnabled = 0;
final String service = mContext.getPackageName() + "/" + BuildConfig.APPLICATION_ID + ".MyAccessibilityService";
boolean accessibilityFound = false;
try
{
accessibilityEnabled = Settings.Secure.getInt(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
// Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled);
}
catch (Settings.SettingNotFoundException e)
{
// Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage());
}
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
if (accessibilityEnabled == 1)
{
String settingValue = Settings.Secure.getString(mContext.getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null)
{
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
splitter.setString(settingValue);
while (splitter.hasNext())
{
String accessibilityService = splitter.next();
if (accessibilityService.equalsIgnoreCase(service))
{
return true;
}
}
}
}
return accessibilityFound;
}
public static void requestOverlay()
{
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsManageOverlay);
}
public static void requestBindAccessibilityService()
{
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityPermissions.getInstance().startActivityForResult(intent, requestCodeForPermissionsAccessibility);
}
public static void requestDeviceAdmin()
{
if(!haveDeviceAdmin())
@ -370,10 +426,13 @@ public class ActivityPermissions extends Activity
if(!havePermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, workingContext))
addToArrayListUnique(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, requiredPermissions);
for(Profile p : Profile.getProfileCollection())
if(!havePermission(Manifest.permission.READ_EXTERNAL_STORAGE, workingContext))
{
if(p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
for (Profile p : Profile.getProfileCollection())
{
if (p.changeIncomingCallsRingtone || p.changeNotificationRingtone)
addToArrayListUnique(Manifest.permission.READ_EXTERNAL_STORAGE, requiredPermissions);
}
}
if (!onlyGeneral)
@ -407,27 +466,6 @@ public class ActivityPermissions extends Activity
}
}
}
/*
Not all permissions need to be asked for.
*/
/*if(shouldShowRequestPermissionRationale("android.permission.RECORD_AUDIO"))
Toast.makeText(ActivityMainScreen.this, "shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();
else
Toast.makeText(ActivityMainScreen.this, "not shouldShowRequestPermissionRationale", Toast.LENGTH_LONG).show();*/
// addToArrayListUnique("Manifest.permission.RECORD_AUDIO", requiredPermissions);
/*int hasPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
if (hasPermission == PackageManager.PERMISSION_DENIED)
{
Toast.makeText(ActivityMainScreen.this, "Don't have record_audio. Requesting...", Toast.LENGTH_LONG).show();
// requestPermissions(new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
ActivityCompat.requestPermissions(ActivityMainScreen.this, new String[]{"Manifest.permission.CAMERA"}, requestCodeForPermissions);
}
else
Toast.makeText(ActivityMainScreen.this, "Have record_audio.", Toast.LENGTH_LONG).show();*/
}
return requiredPermissions.toArray(new String[requiredPermissions.size()]);
@ -650,7 +688,18 @@ public class ActivityPermissions extends Activity
// )
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
if(Build.VERSION.SDK_INT >= 29)
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
{
String parts[];
if(action.getParameter2().contains(Action.actionParameter2Split))
parts = action.getParameter2().split(Action.actionParameter2Split);
else
parts = action.getParameter2().split(";");
// Permission only required for starts of activity, not broadcasts or services
if(parts[2].equals(ActivityManageActionStartActivity.startByActivityString))
addToArrayListUnique(Manifest.permission.SYSTEM_ALERT_WINDOW, requiredPermissions);
}
break;
case triggerUrl:
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
@ -711,6 +760,12 @@ public class ActivityPermissions extends Activity
case stopPhoneCall:
addToArrayListUnique(Manifest.permission.ANSWER_PHONE_CALLS, requiredPermissions);
break;
case takeScreenshot:
addToArrayListUnique(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, requiredPermissions);
break;
case setLocationService:
addToArrayListUnique(Manifest.permission.WRITE_SECURE_SETTINGS, requiredPermissions);
break;
default:
break;
}
@ -960,6 +1015,14 @@ public class ActivityPermissions extends Activity
case Manifest.permission.QUERY_ALL_PACKAGES:
usingElements.add(getResources().getString(R.string.queryAllPackages));
break;
case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
for(String ruleName : getRulesUsing(Action.Action_Enum.takeScreenshot))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case Manifest.permission.WRITE_SECURE_SETTINGS:
for(String ruleName : getRulesUsing(Action.Action_Enum.setLocationService))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
}
return usingElements;
@ -968,6 +1031,15 @@ public class ActivityPermissions extends Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
/*
All of the following permissions need to be "manually" activated by the user in some
buried system menu.
In my opinion by mistake the function will be called when the user has just landed
on one of those screens, not when he exits it again. To compensate for that onResume()
is overridden. This enables the permission screen to automatically close after all
required permissions have been granted.
*/
super.onActivityResult(requestCode, resultCode, data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
@ -1015,6 +1087,10 @@ public class ActivityPermissions extends Activity
if (requestCode == requestCodeForPermissionsManageOverlay)
if(havePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
if (requestCode == requestCodeForPermissionsAccessibility)
if(havePermission(Manifest.permission.BIND_ACCESSIBILITY_SERVICE, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
}
}
@ -1074,10 +1150,14 @@ public class ActivityPermissions extends Activity
}
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
{
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.noticeRestrictedPermissions), ActivityPermissions.this).show();
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.SYSTEM_ALERT_WINDOW))
@ -1096,6 +1176,22 @@ public class ActivityPermissions extends Activity
diag.show();
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
{
AlertDialog diag = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.accessibilityApiPermissionHint), ActivityPermissions.this);
diag.setOnDismissListener(new DialogInterface.OnDismissListener()
{
@Override
public void onDismiss(DialogInterface dialogInterface)
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
requestBindAccessibilityService();
}
});
diag.show();
return;
}
else if (s.equalsIgnoreCase(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
{
if(Build.VERSION.SDK_INT >= 33)
@ -1151,6 +1247,13 @@ public class ActivityPermissions extends Activity
return;
}
else if(s.equalsIgnoreCase(Manifest.permission.WRITE_SECURE_SETTINGS))
{
AlertDialog diaglog = Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.writeSecureSettingsNotice), ActivityPermissions.this);
diaglog.show();
Linkify.addLinks((TextView) diaglog.findViewById(android.R.id.message), Linkify.ALL);
// return;
}
}
}
@ -1578,4 +1681,47 @@ public class ActivityPermissions extends Activity
return false;
}
}
@Override
protected void onResume()
{
super.onResume();
if(Build.VERSION.SDK_INT >= 33 && BuildConfig.FLAVOR.equals(AutomationService.flavor_name_apk))
{
for (String p : getRequiredPermissions(false))
{
if (p.equals(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE) || p.equals(Manifest.permission.BIND_ACCESSIBILITY_SERVICE))
{
tvRestrictionPermissionsNotice.setText(getResources().getString(R.string.noticeRestrictedPermissions));
/*
Opening the app's settings directly does not work because the
mentioned 3 dots are only displayed when you went there the hard way.
*/
/*
tvRestrictionPermissionsNotice.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
})*/;
break;
}
}
}
for(String p : getRequiredPermissions(false))
{
if(!havePermission(p, this))
return;
}
// have all
setHaveAllPermissions();
}
}

View File

@ -22,7 +22,7 @@ public class AsyncTasks
try
{
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null).trim();
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null, ActivityManageActionTriggerUrl.methodGet).trim();
int latestVersion = Integer.parseInt(result);
// At this point the update check itself has already been successful.

View File

@ -223,7 +223,10 @@ public class AutomationService extends Service implements OnInitListener
startUpRoutine();
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
if(getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_MUTABLE);
else
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
notificationBuilder = createServiceNotificationBuilder();
updateNotification();

View File

@ -44,7 +44,11 @@ import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
@ -120,7 +124,7 @@ public class Miscellaneous extends Service
public static final String lineSeparator = System.getProperty("line.separator");
public static String downloadURL(String url, String username, String password)
public static String downloadURL(String url, String username, String password, String method)
{
HttpClient httpclient = new DefaultHttpClient();
StringBuilder responseBody = new StringBuilder();
@ -148,6 +152,8 @@ public class Miscellaneous extends Service
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic " + encodedCredentials);
}
else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
connection.setRequestMethod("POST");
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in = new BufferedReader (new InputStreamReader (content));
@ -174,33 +180,42 @@ public class Miscellaneous extends Service
}
}
public static String downloadURLwithoutCertificateChecking(String url, String username, String password)
public static String downloadURLwithoutCertificateChecking(String url, String username, String password, String method)
{
// HttpClient httpclient = new DefaultHttpClient();
// StringBuilder responseBody = new StringBuilder();
boolean errorFound = false;
try
try
{
HttpParams params = new BasicHttpParams();
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient httpclient = new DefaultHttpClient(params);
httpclient = Actions.getInsecureSslClient(httpclient);
HttpPost httppost = new HttpPost(url);
HttpRequestBase httpRequest;
if(
method.equals(ActivityManageActionTriggerUrl.methodPost)
||
(username != null && password != null)
)
httpRequest = new HttpPost(url);
else
httpRequest = new HttpGet(url);
/*httpRequest = new HttpEntityEnclosingRequestBase()
{
@Override
public String getMethod()
{
return "GET";
}
};*/
// Add http simple authentication if specified
if(username != null && password != null)
{
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
// List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
httppost.addHeader("Authorization", "Basic " + encodedCredentials);
// nameValuePairs.add(new BasicNameValuePair("Authorization", "Basic " + encodedCredentials));
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
httpRequest.addHeader("Authorization", "Basic " + encodedCredentials);
}
HttpResponse response = httpclient.execute(httppost);
HttpResponse response = httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
if (entity != null)
{
@ -211,8 +226,7 @@ public class Miscellaneous extends Service
catch(Exception e)
{
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
errorFound = true;
return "httpError";
return "httpError";
}
// finally
// {

View File

@ -0,0 +1,51 @@
package com.jens.automation2;
import android.accessibilityservice.AccessibilityService;
import android.os.Build;
import android.util.Log;
import android.view.Display;
import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
public class MyAccessibilityService extends AccessibilityService
{
static MyAccessibilityService instance;
public static MyAccessibilityService getInstance()
{
if(instance == null)
{
instance = new MyAccessibilityService();
}
return instance;
}
@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent)
{
}
@Override
public void onInterrupt()
{
}
@Override
public void onCreate()
{
super.onCreate();
instance = this;
}
@Override
protected void onServiceConnected()
{
super.onServiceConnected();
Miscellaneous.logEvent("i", "Accessibility service", "Service started.", 4);
}
}

View File

@ -79,7 +79,7 @@ public class News
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
{
String newsUrl = "https://server47.de/automation/appNews.php";
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
newsContent = Miscellaneous.downloadURL(newsUrl, null, null, ActivityManageActionTriggerUrl.methodGet);
// Cache content to local storage
if(Miscellaneous.writeStringToFile(filePath, newsContent))

View File

@ -145,7 +145,8 @@ public class ReceiverCoordinator
}
// startPhoneStateListener
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
PhoneStatusListener.startPhoneStatusListener(AutomationService.getInstance()); // also used to mute anouncements during calls
// startConnectivityReceiver
ConnectivityReceiver.startConnectivityReceiver(AutomationService.getInstance());

View File

@ -217,7 +217,7 @@ public class XmlFileInterface
}
serializer.endTag(null, "ProfileCollection");
serializer.startTag(null, "RuleCollection");
for(int i=0; i<Rule.getRuleCollection().size(); i++)
{
@ -1286,20 +1286,24 @@ public class XmlFileInterface
else
newTag = tag.replace("/", Action.intentPairSeparator);
String[] newTagPieces = newTag.split(";");
String[] newTagPieces = new String[0];
if(newTag.contains(Action.actionParameter2Split))
newTagPieces = newTag.split(Action.actionParameter2Split);
else
newTag.split(";");
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeparator)))
{
newTag = Actions.dummyPackageString + ";" + newTag;
newTagPieces = newTag.split(";");
newTag = Actions.dummyPackageString + Action.actionParameter2Split + newTag;
newTagPieces = newTag.split(Action.actionParameter2Split);
}
if(newTagPieces.length < 3)
newTag += ";" + ActivityManageActionStartActivity.startByActivityString;
newTag += Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString;
else if(newTagPieces.length >= 3)
{
if(newTagPieces[2].contains(Action.intentPairSeparator))
newTag = newTagPieces[0] + ";" + newTagPieces[1] + ";" + ActivityManageActionStartActivity.startByActivityString + ";" + newTagPieces[2];
newTag = newTagPieces[0] + Action.actionParameter2Split + newTagPieces[1] + Action.actionParameter2Split + ActivityManageActionStartActivity.startByActivityString + Action.actionParameter2Split + newTagPieces[2];
}
newAction.setParameter2(newTag);

View File

@ -11,6 +11,7 @@ import android.util.Log;
import com.jens.automation2.ActivityMainScreen;
import com.jens.automation2.AutomationService;
import com.jens.automation2.BuildConfig;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.PointOfInterest;
import com.jens.automation2.R;
@ -232,6 +233,7 @@ public class LocationProvider
public void startLocationService()
{
// startPhoneStateListener
if(!BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
PhoneStatusListener.startPhoneStatusListener(parentService); // also used to mute anouncements during calls
// startConnectivityReceiver

View File

@ -1,6 +1,5 @@
package com.jens.automation2.location;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@ -30,7 +29,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
protected static boolean mayCellLocationChangedReceiverBeActivatedFromWifiPointOfView = true;
protected static WifiBroadcastReceiver wifiBrInstance;
protected static IntentFilter wifiListenerIntentFilter;
protected static boolean wifiListenerActive=false;
protected static boolean wifiListenerActive = false;
final static String unknownSsidName = "<unknown ssid>";
@ -46,13 +45,16 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
public static void setLastWifiSsid(String newWifiSsid)
{
// Remove double quotes
if(newWifiSsid.startsWith("\"") && newWifiSsid.endsWith("\""))
newWifiSsid = newWifiSsid.substring(1, newWifiSsid.length()-1);
// If it's a real name, not an empty string, it's stored as the last ssid
if(newWifiSsid.length() > 0)
{
if(newWifiSsid.equals(unknownSsidName))
WifiBroadcastReceiver.lastWifiSsidReal = lastWifiSsid;
WifiBroadcastReceiver.lastWifiSsid = newWifiSsid;
}
}
@ -72,24 +74,15 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
try
{
// int state = -1;
NetworkInfo myWifi = null;
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) // fired upon disconnection
{
// state = intent.getIntExtra(WifiManager.NETWORK_STATE_CHANGED_ACTION, -1);
// Miscellaneous.logEvent("i", "WifiReceiver", "NETWORK_STATE_CHANGED_ACTION: " + String.valueOf(state));
myWifi = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
}
WifiManager myWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
// ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
// myWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
// myWifi = state
// WifiInfo wifiInfo = myWifiManager.getConnectionInfo();
// SupplicantState supState = wifiInfo.getSupplicantState();
if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) // fired upon connection
{
String ssid = myWifiManager.getConnectionInfo().getSSID();
@ -132,7 +125,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
}
else if(!myWifi.isConnectedOrConnecting()) // really disconnected? because sometimes also fires on connect
{
if(wasConnected) // wir könnten einfach noch nicht daheim sein
if(wasConnected) // we could simply not be home yet
{
try
{
@ -226,17 +219,16 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
{
try
{
if(wifiListenerActive)
if (wifiListenerActive)
{
Miscellaneous.logEvent("i", "Wifi Listener", "Stopping wifiListener", 4);
wifiListenerActive = false;
parentLocationProvider.getParentService().unregisterReceiver(wifiBrInstance);
}
}
catch(Exception ex)
catch (Exception ex)
{
Miscellaneous.logEvent("e", "Wifi Listener", "Error stopping wifiListener: " + Log.getStackTraceString(ex), 3);
}
}
}

View File

@ -134,7 +134,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
{
case BatteryManager.BATTERY_STATUS_CHARGING:
case BatteryManager.BATTERY_STATUS_FULL:
Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
// Miscellaneous.logEvent("i", "BatteryReceiver", "Device has been fully charged.", 5);
this.actionCharging(context);
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:

View File

@ -52,9 +52,13 @@ public class BroadcastListener extends android.content.BroadcastReceiver impleme
{
broadcastsCollection.add(new EventOccurrence(Calendar.getInstance(), intent.getAction()));
for(String key : intent.getExtras().keySet())
Miscellaneous.logEvent("i", "Broadcast received", "Broadcast " + intent.getAction() + " received.", 4);
if(intent.getExtras() != null && intent.getExtras().size() > 0)
{
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
for (String key : intent.getExtras().keySet())
{
Miscellaneous.logEvent("i", "Broadcast extra", "Broadcast " + intent.getAction() + " has extra " + key + " and type " + intent.getExtras().get(key).getClass().getName(), 4);
}
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.broadcastReceived);

View File

@ -11,6 +11,7 @@ import android.util.Log;
import androidx.annotation.RequiresApi;
import com.jens.automation2.AutomationService;
import com.jens.automation2.BuildConfig;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.Rule;
import com.jens.automation2.TimeFrame;
@ -243,7 +244,12 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
}
Intent alarmIntent = new Intent(automationServiceRef, DateTimeListener.class);
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if(Miscellaneous.getAnyContext().getApplicationContext().getApplicationInfo().targetSdkVersion >= 31)
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
else
alarmPendingIntent = PendingIntent.getBroadcast(automationServiceRef, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
centralAlarmManagerInstance.set(AlarmManager.RTC_WAKEUP, scheduleCandidate.time.getTimeInMillis(), alarmPendingIntent);
SimpleDateFormat sdf = new SimpleDateFormat("E dd.MM.yyyy HH:mm:ss");

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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/actionSetLocationService"/>
<TextView
android:id="@+id/tvWifiExplanation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wifiExplanation1" />
<TextView
android:id="@+id/tvWifiExplanation2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/wifiExplanation2" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:stretchColumns="1"
android:shrinkColumns="1" >
<TableRow
android:layout_marginTop="@dimen/default_margin">
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/default_margin"
android:text="@string/state" />
<RadioGroup
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbActionLocationServiceOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/off" />
<RadioButton
android:id="@+id/rbActionLocationServiceSensorsOnly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/LOCATION_MODE_SENSOR_ONLY" />
<RadioButton
android:id="@+id/rbActionLocationServiceBatterySaving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/LOCATION_MODE_BATTERY_SAVING" />
<RadioButton
android:id="@+id/rbActionLocationServiceHighAccuracy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/LOCATION_MODE_HIGH_ACCURACY" />
</RadioGroup>
</TableRow>
</TableLayout>
<Button
android:id="@+id/bActionSetLocationServiceSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</LinearLayout>
</ScrollView>

View File

@ -90,6 +90,34 @@
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/method"
android:layout_marginTop="@dimen/fab_margin"
android:textStyle="bold" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rbTriggerUrlMethodGet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/methodGet" />
<RadioButton
android:id="@+id/rbTriggerUrlMethodPost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/default_margin"
android:text="@string/methodPost" />
</RadioGroup>
<ListView
android:id="@+id/lvTriggerUrlPostParameters"
android:layout_width="match_parent"
@ -109,6 +137,12 @@
</ScrollView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/triggerUrlVariableHint" />
<Button
android:id="@+id/bSaveSpeakText"
android:layout_marginTop="15dp"

View File

@ -66,6 +66,12 @@
</LinearLayout>
<TextView
android:id="@+id/tvRestrictionPermissionsNotice"
android:textColor="@color/red"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -65,7 +65,7 @@
<string name="end">Ende</string>
<string name="save">Speichern</string>
<string name="urlToTrigger">URL, die ausgelöst werden soll:</string>
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (&lt; Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
<string name="urlLegend">Variablen:\nSie können die folgenden Variablen verwenden. Vor dem Auslösen werden sie mit dem entsprechenden Wert Ihres Geräts ersetzt. Die Klammern müssen in den Text mit aufgenommen werden.\n\n[uniqueid] - Die Unique ID Ihres Geräts\n[serialnr] - Die Seriennummer Ihres Geräts (&lt; Android 9)\n[latitude] - Ihr gegenwärtiger Breitengrad\n[longitude] - Ihr gegenwärtiger Längengrad\n[phonenr] - Nummer des letzten ein- oder ausgehenden Anrufs\n[d] - Tag des Monats, 2-stellig mit führender Null\n[m] - Monat als Zahl, mit führenden Nullen\n[Y] - Vierstellige Jahreszahl\n[h] - Stunde im 12-Stunden-Format, mit führenden Nullen\n[H] - Stunde im 24-Stunden-Format, mit führenden Nullen\n[i] - Minuten, mit führenden Nullen\n[s] - Sekunden, mit führenden Nullen\n[ms] - milliseconds\n[notificationTitle] - Titel der letzten Benachrichtigung\n[notificationText] - Text der letzten Benachrichtigung\n[LAST_TRIGGERURL_RESULT] - Das Ergebnis der letzten Ausführung der triggerUrl-Aktion\n[variable-VARIABLENAME] - Der Wert Ihrer selbst definitierten Variable</string>
<string name="wifi">WLAN</string>
<string name="activating">Aktiviere</string>
<string name="deactivating">Deaktiviere</string>
@ -802,4 +802,15 @@
<string name="wifiTriggerDisconnectionHint">Dieser Auslöser ist gültig, wenn Sie gerade die Verbindung zu dem oben angegebenen WLAN getrennt haben ODER während der Dienst noch gestartet wird und wenn Sie mit keinem WLAN verbunden sind. Wenn Sie möchten, dass der Auslöser nur ausgelöst wird, wenn Sie die Verbindung zu einem bestimmten WLAN explizit trennen, fügen Sie einen weiteren Auslöser hinzu: \"Der Dienst wird nicht gestartet\".</string>
<string name="className">Klassenname</string>
<string name="startAppByStartForegroundService">per startForegroundService()</string>
<string name="method">Methode</string>
<string name="takeScreenshot">Screenshot erstellen</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">An den Barrierefreiheitsdienst anbinden</string>
<string name="bindAccessibilityService">An den Barrierefreiheitsdienst anbinden</string>
<string name="accessibilityApiPermissionHint">Nachdem Sie auf OK geklickt haben, werden Sie zu einem Systemdialog weitergeleitet. Bitte wählen Sie dort Automatisierung aus und erlauben Sie die Barrierefreiheits-API.</string>
<string name="accessibility_service_explanation">Erforderlich für bestimmte Aktionen.</string>
<string name="noticeRestrictedPermissions">Wenn Sie eine der folgenden Berechtigungen nicht erteilen und eine Systemmeldung wie \"Eingeschränkte Berechtigung\" erhalten, müssen Sie zuerst zu den Android-Einstellungen und dann zu den Anwendungen gehen und Automatisierung auswählen. Nun sollten sich 3 Punkte in der oberen rechten Ecke befinden. Klicken Sie auf \"Eingeschränkte Einstellungen zulassen\". Danach sollte die erforderliche Erlaubnis erteilt werden können. Dies sollte nur für die APK-Version der App gelten, nicht für die von F-Droid oder dem Play Store.</string>
<string name="setLocationService">Ortungsdienst festlegen</string>
<string name="writeSecureSettingsNotice">Leider kann die Erlaubnis WRITE_SECURE_SETTINGS nicht direkt auf Ihrem Android-Gerät erteilt werden. Stattdessen müssen Sie Ihr Gerät an einen Computer anschließen und die Berechtigung über ADB erteilen. Klicken Sie hier, um zu erfahren, wie Sie es gewähren können: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Ortungsdienst</string>
<string name="triggerUrlVariableHint">Das Ergebnis dieser Anfrage wird in der Variablen LAST_TRIGGERURL_RESULT gespeichert, wenn Sie es von einer anderen Regel aus überprüfen möchten. Im Falle von HTTP-Fehlern wie 404 ist der Wert \"HTTP_ERROR\".</string>
</resources>

View File

@ -43,7 +43,7 @@
<string name="enterAname">Inserte un nombre.</string>
<string name="username">Nombre de usuario</string>
<string name="ok">Ok</string>
<string name="continueText">continuar</string>
<string name="continueText">Continuar</string>
<string name="rule">Regla</string>
<string name="android.permission.SEND_SMS">Enviar mensajes SMS</string>
<string name="android.permission.READ_CONTACTS">Leer directorio</string>
@ -197,7 +197,7 @@
<string name="android.permission.RECORD_AUDIO">Grabar audio</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Detectar llamadas salientes</string>
<string name="android.permission.READ_PHONE_STATE">Detectar el estado del dispositivo</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer la almacenamiento</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer el almacenamiento</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Escribir en el almacenamiento</string>
<string name="android.permission.WRITE_SETTINGS">Modificar la configuración del dispositivo</string>
<string name="android.permission.BATTERY_STATS">Determinar el estado de la bateria</string>
@ -367,7 +367,7 @@
<string name="networkAccuracy">Red exactitud [m]</string>
<string name="minimumTimeForLocationUpdates">Tiempo mínimo para cambio en milisegundos para actualizar posición</string>
<string name="timeForUpdate">Tiempo para actualizar [milisegundos]</string>
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (&lt; Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[variable-VARIABLENAME] - El valor de la variable definida personalizada</string>
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo. Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo (&lt; Android 9)\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación\n[LAST_TRIGGERURL_RESULT] - El resultado de la última ejecución de la acción triggerUrl\n[variable-VARIABLENAME] - El valor de la variable definida personalizada</string>
<string name="screenRotationAlreadyEnabled">Rotación del monitor todavia esta activado.</string>
<string name="screenRotationAlreadyDisabled">Rotación del monitor todavia esta desactivado.</string>
<string name="needLocationPermForWifiList">Se puede usar la lista de wifis conocidos para determinar los sitios en los cuales estuvo. Por eso el permiso de localización es necesario para cargar la lista de wifis. Si quiere elegir uno de la lista tiene que conceder el permiso. En caso contrario todavia puede introducir un nombre wifi manualmente.</string>
@ -801,4 +801,15 @@
<string name="wifiTriggerDisconnectionHint">Este activador será válido si acabas de desconectarte del wifi especificado anteriormente O mientras el servicio aún se está iniciando y si no estás conectado a ningún wifi. Si desea que el activador se active solo cuando se desconecte explícitamente de una determinada red WiFi, agregue otro activador \"el servicio no se está iniciando\".</string>
<string name="className">Nombre de la clase</string>
<string name="startAppByStartForegroundService">a través de startForegroundService((</string>
<string name="method">Método</string>
<string name="takeScreenshot">Tomar captura de pantalla</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Enlazar al servicio de accesibilidad</string>
<string name="bindAccessibilityService">Enlazar al servicio de accesibilidad</string>
<string name="accessibilityApiPermissionHint">Después de hacer clic en Aceptar, se le enviará a un cuadro de diálogo del sistema. Seleccione Automatización allí y permita Permitir API de accesibilidad.</string>
<string name="accessibility_service_explanation">Requerido para ciertas acciones.</string>
<string name="noticeRestrictedPermissions">Si no le otorga a uno el siguiente permiso y un mensaje del sistema como \"Ajuste restringido\", primero debe ir a la configuración de Android, luego a las aplicaciones, elija Automatización. Ahora debería haber 3 puntos en la esquina superior derecha. Haga clic en \"Permitir configuraciones restringidas\". Después de eso, el permiso necesario debería poder otorgarse. Esto solo debería aplicarse a la versión APK de la aplicación, no a las de F-Droid o Play Store.</string>
<string name="setLocationService">Encender/desactivar el servicio de ubicación</string>
<string name="writeSecureSettingsNotice">Desafortunadamente, el permiso WRITE_SECURE_SETTINGS no se puede otorgar directamente en su dispositivo Android. En su lugar, debe conectar su dispositivo a una computadora y otorgar el permiso a través de ADB. Haga clic aquí para saber cómo otorgarlo: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Servicio de localización</string>
<string name="triggerUrlVariableHint">El resultado de esta solicitud se almacenará en la variable LAST_TRIGGERURL_RESULT si desea verificarlo desde otra regla. En caso de errores HTTP como 404, el valor será \"HTTP_ERROR\".</string>
</resources>

View File

@ -801,4 +801,15 @@
<string name="wifiTriggerDisconnectionHint">Ce déclencheur sera valide si vous venez de vous déconnecter du wifi spécifié ci-dessus OU alors que le service est encore en cours de démarrage et si vous n\'êtes connecté à aucun wifi. Si vous souhaitez que le déclencheur ne se déclenche que lorsque vous vous déconnectez explicitement d\'un certain wifi, ajoutez un autre déclencheur « le service ne démarre pas ».</string>
<string name="className">Nom de la classe</string>
<string name="startAppByStartForegroundService">par startForegroundService()</string>
<string name="method">Méthode</string>
<string name="takeScreenshot">Prendre une capture d\'écran</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Se lier au service d\'accessibilité</string>
<string name="bindAccessibilityService">Se lier au service d\'accessibilité</string>
<string name="accessibilityApiPermissionHint">Après avoir cliqué sur OK, vous serez redirigé vers une boîte de dialogue système. Sélectionnez Automatisation et autorisez l\'option Autoriser l\'API d\'accessibilité.</string>
<string name="accessibility_service_explanation">Obligatoire pour certaines actions.</string>
<string name="noticeRestrictedPermissions">Si vous ne parvenez pas à accorder à l\'un d\'entre eux l\'autorisation suivante et un message système tel que « Autorisation restreinte », vous devez d\'abord accéder aux paramètres Android, puis aux applications, puis choisir Automatisation. Maintenant, il devrait y avoir 3 points dans le coin supérieur droit. Cliquez sur « Autoriser les paramètres restreints ». Après cela, l\'autorisation nécessaire devrait pouvoir être accordée. Cela ne devrait s\'appliquer qu\'à la version APK de l\'application, pas à celles de F-Droid ou du Play Store.</string>
<string name="setLocationService">Définir le service de localisation</string>
<string name="writeSecureSettingsNotice">Malheureusement, l\'autorisation WRITE_SECURE_SETTINGS ne peut pas être donnée directement sur votre appareil Android. Au lieu de cela, vous devez connecter votre appareil à un ordinateur et accorder l\'autorisation via ADB. Cliquez ici pour savoir comment l\'accorder : https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Service de localisation</string>
<string name="triggerUrlVariableHint">Le résultat de cette requête sera stocké dans la variable LAST_TRIGGERURL_RESULT si vous souhaitez le vérifier à partir d\'une autre règle. En cas d\'erreurs HTTP comme 404, la valeur sera « HTTP_ERROR ».</string>
</resources>

View File

@ -542,7 +542,7 @@
<string name="tuesday">Martedì</string>
<string name="unknownError">Errore indeterminato.</string>
<string name="until">finchè</string>
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. Quando attivate, saranno sostituite con il valore corrispondente sul tuo dispositivo. Includi le parentesi nel tuo testo.\n\n[uniqueid] - L\'ID unico del tuo dispositivo\n[serialnr] - Il numero di serie del tuo dispositivio (&lt; Android 9)\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Numero dell\'ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre con zero iniziale \n[m] - Mese in formato numerico, sempre 2 cifre con zero iniziale \n[Y] - L\anno, sempre con 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre\n[notificationTitle] - titolo dell\'ultima notifica\n[notificationText] - testo dell\'ultima notifica\n[variable-VARIABLENAME] - Il valore della variabile definita in modo personalizzato</string>
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. Quando attivate, saranno sostituite con il valore corrispondente sul tuo dispositivo. Includi le parentesi nel tuo testo.\n\n[uniqueid] - L\'ID unico del tuo dispositivo\n[serialnr] - Il numero di serie del tuo dispositivio (&lt; Android 9)\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Numero dell\'ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre con zero iniziale \n[m] - Mese in formato numerico, sempre 2 cifre con zero iniziale \n[Y] - L\anno, sempre con 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre\n[notificationTitle] - titolo dell\'ultima notifica\n[notificationText] - testo dell\'ultima notifica\n[LAST_TRIGGERURL_RESULT] - Risultato dell\'esecuzione dell\'ultima azione triggerUrl\n[variable-VARIABLENAME] - Il valore della variabile definita in modo personalizzato</string>
<string name="urlToTrigger">URL da caricare:</string>
<string name="urlTooShort">L\'url deve avere almeno 10 caratteri.</string>
<string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funzionerà dato che sei su una versione superiore ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola.</string>
@ -802,4 +802,15 @@
<string name="wifiTriggerDisconnectionHint">Questo trigger sarà valido se ti sei appena disconnesso dal Wi-Fi specificato sopra OPPURE mentre il servizio è ancora in fase di avvio e se non sei connesso a nessuna rete Wi-Fi. Se vuoi che il trigger si attivi solo quando ti stai disconnettendo esplicitamente da una determinata rete Wi-Fi, aggiungi un altro trigger \"il servizio non si avvia\".</string>
<string name="className">Nome della classe</string>
<string name="startAppByStartForegroundService">di startForegroundService()</string>
<string name="method">Metodo</string>
<string name="takeScreenshot">Fai uno screenshot</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Associare al servizio di accessibilità</string>
<string name="bindAccessibilityService">Associare al servizio di accessibilità</string>
<string name="accessibilityApiPermissionHint">Dopo aver fatto clic su OK, verrà visualizzata una finestra di dialogo di sistema. Seleziona Automazione e consenti Consenti API di accessibilità.</string>
<string name="accessibility_service_explanation">Obbligatorio per determinate azioni.</string>
<string name="noticeRestrictedPermissions">Se non riesci a concedere una delle seguenti autorizzazioni e un messaggio di sistema come \"Autorizzazione limitata\", devi prima andare alle impostazioni di Android, quindi alle applicazioni, scegli Automazione. Ora dovrebbero esserci 3 punti nell\'angolo in alto a destra. Fai clic su \"Consenti impostazioni limitate\". Dopodiché dovrebbe essere concessa l\'autorizzazione necessaria. Questo dovrebbe valere solo per la versione APK dell\'app, non per quelle di F-Droid o Play Store.</string>
<string name="setLocationService">Impostare il servizio di localizzazione</string>
<string name="writeSecureSettingsNotice">Purtroppo l\'autorizzazione WRITE_SECURE_SETTINGS non può essere data direttamente sul tuo dispositivo Android. Invece, devi collegare il tuo dispositivo a un computer e concedere l\'autorizzazione tramite ADB. Clicca qui per scoprire come concederlo: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Servizio di localizzazione</string>
<string name="triggerUrlVariableHint">Il risultato di questa richiesta verrà memorizzato nella variabile LAST_TRIGGERURL_RESULT se si desidera controllarlo da un\'altra regola. In caso di errori HTTP come 404 il valore sarà \"HTTP_ERROR\".</string>
</resources>

View File

@ -800,5 +800,16 @@
<string name="wifiTriggerDisconnectionHint">Deze trigger is geldig als je net de verbinding met de hierboven gespecificeerde wifi hebt verbroken OF terwijl de service nog aan het starten is en als je niet verbonden bent met wifi. Als je wilt dat de trigger alleen wordt geactiveerd wanneer je expliciet de verbinding met een bepaalde wifi verbreekt, voeg dan nog een trigger toe \"service start niet\".</string>
<string name="className">Naam van de klasse</string>
<string name="startAppByStartForegroundService">door startForegroundService()</string>
<string name="method">Methode</string>
<string name="takeScreenshot">Screenshot maken</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Binden aan toegankelijkheidsservice</string>
<string name="bindAccessibilityService">Binden aan toegankelijkheidsservice</string>
<string name="accessibilityApiPermissionHint">Nadat u op OK hebt geklikt, wordt u naar een systeemdialoogvenster gestuurd. Selecteer daar Automatisering en sta Toegankelijkheids-API toestaan toe.</string>
<string name="accessibility_service_explanation">Vereist voor bepaalde acties.</string>
<string name="noticeRestrictedPermissions">Als u er niet in slaagt om een van de volgende machtigingen en een systeembericht zoals \"Beperkte toestemming\" te verlenen, moet u eerst naar Android-instellingen gaan en vervolgens naar toepassingen en Automatisering kiezen. Nu zouden er 3 stippen in de rechterbovenhoek moeten zijn. Klik op \"Beperkte instellingen toestaan\". Daarna moet de benodigde toestemming aanvaardbaar zijn. Dit zou alleen van toepassing moeten zijn op de APK-versie van de app, niet die van F-Droid of Play Store.</string>
<string name="setLocationService">Locatieservice instellen</string>
<string name="writeSecureSettingsNotice">Helaas kan de toestemming WRITE_SECURE_SETTINGS niet rechtstreeks op uw Android-apparaat worden gegeven. In plaats daarvan moet u uw apparaat op een computer aansluiten en de toestemming verlenen via ADB. Klik hier om te weten te komen hoe u het kunt toekennen: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Locatie service</string>
<string name="triggerUrlVariableHint">Het resultaat van dit verzoek wordt opgeslagen in de variabele LAST_TRIGGERURL_RESULT als u het vanuit een andere regel wilt controleren. In het geval van HTTP-fouten zoals 404 is de waarde \"HTTP_ERROR\".</string>
</resources>

View File

@ -70,7 +70,7 @@
<string name="end">Koniec</string>
<string name="save">Zapisz</string>
<string name="urlToTrigger">Adres URL do uruchomienia:</string>
<string name="urlLegend">Zmienne:\nMożesz użyć następujących zmiennych. Po uruchomieniu zostaną one zastąpione odpowiednią wartością na Twoim urządzeniu. Umieść nawiasy w tekście.\n\n[uniqueid] unikalny identyfikator Twojego urządzenia\n[serialnr] numer seryjny Twojego urządzenia (&lt; Android 9)\n[latitude] Twoje urządzenie\ szerokość geograficzna użytkownika\n[longitude] długość geograficzna Twojego urządzenia\n[phonenr] numer ostatniego połączenia przychodzącego lub wychodzącego\n[d] dzień miesiąca, 2 cyfry z zerami na początku\n[m] Numeryczna reprezentacja miesiąca z zerami na początku\n[Y] — pełna cyfrowa reprezentacja roku, 4 cyfry\n[h] — godzina w formacie 12-godzinnym z zerami na początku\n[H] — format 24-godzinny format godziny z wiodącymi zerami\n[i] - minuty z wiodącymi zerami\n[s] - sekundy z wiodącymi zerami\n[ms] - milisekundy\n[notificationTitle] - tytuł ostatniego powiadomienia\n[notificationText] - tekst ostatniego powiadomienia\n[variable-VARIABLENAME] - Wartość niestandardowej zmiennej zdefiniowanej przez Ciebie</string>
<string name="urlLegend">Zmienne:\nMożesz użyć następujących zmiennych. Po uruchomieniu zostaną one zastąpione odpowiednią wartością na Twoim urządzeniu. Umieść nawiasy w tekście.\n\n[uniqueid] unikalny identyfikator Twojego urządzenia\n[serialnr] numer seryjny Twojego urządzenia (&lt; Android 9)\n[latitude] Twoje urządzenie\ szerokość geograficzna użytkownika\n[longitude] długość geograficzna Twojego urządzenia\n[phonenr] numer ostatniego połączenia przychodzącego lub wychodzącego\n[d] dzień miesiąca, 2 cyfry z zerami na początku\n[m] Numeryczna reprezentacja miesiąca z zerami na początku\n[Y] — pełna cyfrowa reprezentacja roku, 4 cyfry\n[h] — godzina w formacie 12-godzinnym z zerami na początku\n[H] — format 24-godzinny format godziny z wiodącymi zerami\n[i] - minuty z wiodącymi zerami\n[s] - sekundy z wiodącymi zerami\n[ms] - milisekundy\n[notificationTitle] - tytuł ostatniego powiadomienia\n[notificationText] - tekst ostatniego powiadomienia\n[LAST_TRIGGERURL_RESULT] - Wynik ostatniego wykonania akcji triggerUrl\n[variable-VARIABLENAME] - Wartość niestandardowej zmiennej zdefiniowanej przez Ciebie</string>
<string name="wifi">wifi</string>
<string name="activating">Aktywowanie</string>
<string name="deactivating">Dezaktywowanie</string>
@ -899,4 +899,15 @@
<string name="wifiTriggerDisconnectionHint">Ten wyzwalacz będzie prawidłowy, jeśli właśnie rozłączyłeś się z Wi-Fi określonym powyżej LUB gdy usługa jest nadal uruchomiona i jeśli nie masz połączenia z żadną siecią Wi-Fi. Jeśli chcesz, aby wyzwalacz uruchamiał się tylko wtedy, gdy jawnie rozłączasz się z określoną siecią Wi-Fi, dodaj kolejny wyzwalacz \"usługa nie uruchamia się\".</string>
<string name="className">nazwa klasy</string>
<string name="startAppByStartForegroundService">przez startForegroundService()</string>
<string name="method">Metoda</string>
<string name="takeScreenshot">Zrób zrzut ekranu</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Powiąż z usługą ułatwień dostępu</string>
<string name="bindAccessibilityService">Powiąż z usługą ułatwień dostępu</string>
<string name="accessibilityApiPermissionHint">Po kliknięciu OK zostaniesz przekierowany do systemowego okna dialogowego. Wybierz tam Automatyzację i zezwól na Zezwalaj na interfejs API ułatwień dostępu.</string>
<string name="accessibility_service_explanation">Wymagane w przypadku niektórych działań.</string>
<string name="noticeRestrictedPermissions">Jeśli nie uda Ci się przyznać następującego uprawnienia i komunikatu systemowego, takiego jak \"Ograniczone uprawnienia\", musisz najpierw przejść do ustawień Androida, a następnie aplikacji, wybrać Automatyzacja. Teraz w prawym górnym rogu powinny znajdować się 3 kropki. Kliknij \"Zezwól na ustawienia z ograniczeniami\". Następnie powinno być możliwe udzielenie niezbędnego pozwolenia. Powinno to dotyczyć tylko wersji APK aplikacji, a nie tych z F-Droid lub Sklepu Play.</string>
<string name="setLocationService">Ustawianie usługi lokalizacyjnej</string>
<string name="writeSecureSettingsNotice">Niestety WRITE_SECURE_SETTINGS uprawnień nie można nadać bezpośrednio na urządzeniu z Androidem. Zamiast tego musisz podłączyć urządzenie do komputera i przyznać uprawnienia przez ADB. Kliknij tutaj, aby dowiedzieć się, jak go przyznać: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Usługa lokalizacyjna</string>
<string name="triggerUrlVariableHint">Wynik tego żądania zostanie zapisany w zmiennej LAST_TRIGGERURL_RESULT, jeśli chcesz go sprawdzić z innej reguły. W przypadku błędów HTTP, takich jak 404, wartość będzie wynosić \"HTTP_ERROR\".</string>
</resources>

View File

@ -65,7 +65,7 @@
<string name="end">Конец</string>
<string name="save">Сохранить</string>
<string name="urlToTrigger">URL для вызова:</string>
<string name="urlLegend">Переменные:\nВы можете использовать следующие переменные. При срабатывании они будут заменены соответствующим значением на вашем устройстве. Скобки- часть переменной.\n\n[uniqueid] - уникальный идентификатор\n[serialnr] - серийный номер(&lt; Android 9)\n[latitude] - широта\n[longitude] - долгота\n[phonenr] - Номер последнего входящего или исходящего вызова\n[d] - День месяца, 2 цифры с начальными нулями\n[m] Месяц, 2 цифры с начальными нулями\n[Y] - Год, 4 цифры\n[h] - 12-часовой формат часа с начальными нулями\n[H] - 24-часовой формат часа с начальными нулями\n[i] - Минуты с начальными нулями\n[s] - Секунды с начальными нулями\n[ms] - миллисекунды\n[notificationTitle] - заголовок последнего уведомления\n[notificationText] - текст последнего уведомления\n[variable-VARIABLENAME] - Значение переменной, определенной пользователем</string>
<string name="urlLegend">Переменные:\nВы можете использовать следующие переменные. При срабатывании они будут заменены соответствующим значением на вашем устройстве. Скобки- часть переменной.\n\n[uniqueid] - уникальный идентификатор\n[serialnr] - серийный номер(&lt; Android 9)\n[latitude] - широта\n[longitude] - долгота\n[phonenr] - Номер последнего входящего или исходящего вызова\n[d] - День месяца, 2 цифры с начальными нулями\n[m] Месяц, 2 цифры с начальными нулями\n[Y] - Год, 4 цифры\n[h] - 12-часовой формат часа с начальными нулями\n[H] - 24-часовой формат часа с начальными нулями\n[i] - Минуты с начальными нулями\n[s] - Секунды с начальными нулями\n[ms] - миллисекунды\n[notificationTitle] - заголовок последнего уведомления\n[notificationText] - текст последнего уведомления\n[LAST_TRIGGERURL_RESULT] - Результат последнего выполнения действия triggerUrl\n[variable-VARIABLENAME] - Значение переменной, определенной пользователем</string>
<string name="wifi">Wi-Fi</string>
<string name="activating">Активация</string>
<string name="deactivating">Деактивация</string>
@ -859,4 +859,15 @@
<string name="wifiTriggerDisconnectionHint">Этот триггер будет действителен, если вы только что отключились от Wi-Fi, указанного выше, ИЛИ во время запуска службы и если вы не подключены ни к одному Wi-Fi. Если вы хотите, чтобы триггер срабатывал только тогда, когда вы явно отключаетесь от определенного Wi-Fi, добавьте еще один триггер «сервис не запускается».</string>
<string name="className">Имя класса</string>
<string name="startAppByStartForegroundService">no startForegroundService()</string>
<string name="method">Метод</string>
<string name="takeScreenshot">Сделать снимок экрана</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Привязка к службе специальных возможностей</string>
<string name="bindAccessibilityService">Привязка к службе специальных возможностей</string>
<string name="accessibilityApiPermissionHint">После нажатия кнопки «ОК» вы попадете в системное диалоговое окно. Выберите там «Автоматизация» и разрешите «Разрешить API специальных возможностей».</string>
<string name="accessibility_service_explanation">Required for certain actions.</string>
<string name="noticeRestrictedPermissions">Если вы не можете предоставить одно из следующих разрешений и системное сообщение типа «Ограниченное разрешение», вам нужно сначала перейти в настройки Android, затем в приложения, выбрать «Автоматизация». Теперь в правом верхнем углу должно быть 3 точки. Нажмите «Разрешить ограниченные настройки». После этого необходимо получить необходимое разрешение. Это должно относиться только к APK-версии приложения, а не к версии из F-Droid или Play Store.</string>
<string name="setLocationService">Настройка службы определения местоположения</string>
<string name="writeSecureSettingsNotice">К сожалению, разрешение WRITE_SECURE_SETTINGS не может быть дано непосредственно на вашем Android-устройстве. Вместо этого вам нужно подключить устройство к компьютеру и предоставить разрешение через ADB. Нажмите здесь, чтобы узнать, как его получить: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Служба определения местоположения</string>
<string name="triggerUrlVariableHint">Результат этого запроса будет сохранен в переменной LAST_TRIGGERURL_RESULT если вы захотите проверить его из другого правила. В случае ошибок HTTP, таких как 404, значение будет \"HTTP_ERROR\".</string>
</resources>

View File

@ -56,7 +56,7 @@
<string name="end">结束</string>
<string name="save">保存</string>
<string name="urlToTrigger">触发网址:</string>
<string name="urlLegend">变量:\n您可以使用以下变量。触发后它们将替换为您设备上的对应值。文本中要包含方括号。\n\n[uniqueid] - 您设备的唯一 ID\n[serialnr] - 您设备的序列号(&lt; Android 9\n[latitude] - 您设备的纬度\n[longitude] - 您设备的经度\n[phonenr] - 最后来电或去电的号码\n[d] - 日2 位数字,带前导零\n[m] - 月,数字表示,带前导零\n[Y] - 年完整数字表示4 位数字\n[h] - 时12 小时制,带前导零\n[H] - 时24 小时制,带前导零\n[i] - 分,带前导零\n[s] - 秒,带前导零\n[ms] - 毫秒\n[notificationTitle] - 最后通知的标题\n[notificationText] - 最后通知的文本\n[variable-变量名] - 自定义变量的值</string>
<string name="urlLegend">变量:\n您可以使用以下变量。触发后它们将替换为您设备上的对应值。文本中要包含方括号。\n\n[uniqueid] - 您设备的唯一 ID\n[serialnr] - 您设备的序列号(&lt; Android 9\n[latitude] - 您设备的纬度\n[longitude] - 您设备的经度\n[phonenr] - 最后来电或去电的号码\n[d] - 日2 位数字,带前导零\n[m] - 月,数字表示,带前导零\n[Y] - 年完整数字表示4 位数字\n[h] - 时12 小时制,带前导零\n[H] - 时24 小时制,带前导零\n[i] - 分,带前导零\n[s] - 秒,带前导零\n[ms] - 毫秒\n[notificationTitle] - 最后通知的标题\n[notificationText] - 最后通知的文本\n[LAST_TRIGGERURL_RESULT] - 上次 triggerUrl 操作执行的结果\n[variable-变量名] - 自定义变量的值</string>
<string name="wifi">WLAN</string>
<string name="activating">启用</string>
<string name="deactivating">停用</string>
@ -800,4 +800,15 @@
<string name="wifiTriggerDisconnectionHint">如果您刚刚断开了与上面指定的 wifi 的连接,或者在服务仍在启动并且您没有连接到任何 wifi则此触发器将有效。 如果您希望触发器仅在您明确断开与某个 wifi 的连接时触发,请添加另一个触发器\"服务未启动\"。</string>
<string name="className">类名</string>
<string name="startAppByStartForegroundService">来自 startForegroundService()</string>
<string name="method">方法</string>
<string name="takeScreenshot">截屏</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">绑定到辅助功能服务</string>
<string name="bindAccessibilityService">绑定到辅助功能服务</string>
<string name="accessibilityApiPermissionHint">单击\"确定\"后,您将被发送到系统对话框。请在此处选择\"自动化\",并允许\"允许辅助功能 API\"。</string>
<string name="accessibility_service_explanation">对于某些操作是必需的。</string>
<string name="noticeRestrictedPermissions">如果您未能授予以下权限和\"受限权限\"之类的系统消息,则需要先转到 Android 设置,然后转到应用程序,选择自动化。现在右上角应该有 3 个点。单击\"允许受限设置\"。之后,应该可以授予必要的权限。这应该仅适用于应用的 APK 版本,而不适用于 F-Droid 或 Play 商店中的版本。</string>
<string name="setLocationService">设置位置服务</string>
<string name="writeSecureSettingsNotice">不幸的是WRITE_SECURE_SETTINGS无法直接在您的 Android 设备上授予权限。相反,您需要将设备连接到计算机并通过 ADB 授予权限。单击此处了解如何授予它: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">定位服务</string>
<string name="triggerUrlVariableHint">此请求的结果将存储在变量 LAST_TRIGGERURL_RESULT 中,如果您希望从其他规则中检查它。如果出现像 404 这样的 HTTP 错误,则该值将为\"HTTP_ERROR\"。</string>
</resources>

View File

@ -70,7 +70,7 @@
<string name="end">End</string>
<string name="save">Save</string>
<string name="urlToTrigger">URL to trigger:</string>
<string name="urlLegend">Variables:\nYou can use the following variables. Upon triggering they will be replaced with the corresponding value on your device. Include the brackets in your text.\n\n[uniqueid] - Your device\'s unique id\n[serialnr] - Your device\'s serial number (&lt; Android 9)\n[latitude] - Your device\'s latitude\n[longitude] - Your device\'s longitude\n[phonenr] - Number of last incoming or outgoing call\n[d] - Day of the month, 2 digits with leading zeros\n[m] - Numeric representation of a month, with leading zeros\n[Y] - A full numeric representation of a year, 4 digits\n[h] - 12-hour format of an hour with leading zeros\n[H] - 24-hour format of an hour with leading zeros\n[i] - Minutes with leading zeros\n[s] - Seconds, with leading zeros\n[ms] - milliseconds\n[notificationTitle] - title of last notification\n[notificationText] - text of last notification\n[variable-VARIABLENAME] - The value of your custom defined variable</string>
<string name="urlLegend">Variables:\nYou can use the following variables. Upon triggering they will be replaced with the corresponding value on your device. Include the brackets in your text.\n\n[uniqueid] - Your device\'s unique id\n[serialnr] - Your device\'s serial number (&lt; Android 9)\n[latitude] - Your device\'s latitude\n[longitude] - Your device\'s longitude\n[phonenr] - Number of last incoming or outgoing call\n[d] - Day of the month, 2 digits with leading zeros\n[m] - Numeric representation of a month, with leading zeros\n[Y] - A full numeric representation of a year, 4 digits\n[h] - 12-hour format of an hour with leading zeros\n[H] - 24-hour format of an hour with leading zeros\n[i] - Minutes with leading zeros\n[s] - Seconds, with leading zeros\n[ms] - milliseconds\n[notificationTitle] - title of last notification\n[notificationText] - text of last notification\n[LAST_TRIGGERURL_RESULT] - The result of the last triggerUrl action execution\n[variable-VARIABLENAME] - The value of your custom defined variable</string>
<string name="wifi">wifi</string>
<string name="activating">Activating</string>
<string name="deactivating">Deactivating</string>
@ -522,7 +522,7 @@
<string name="ok">Ok</string>
<string name="disabledFeatures">Disabled features</string>
<string name="theFollowingPermissionsHaveBeenDenied">The following permissions have been denied:</string>
<string name="permissionsExplanationGeneric">The app is current running in limited mode and has deactivated some features. To fully function it requires permissions. If you want to use all functionality you have to grant the permissions in the following rights dialogues. If you do not certain rules can not be executed. In the following you are given an explanation for the requested permissions. Click "continue", when you are ready to proceed.</string>
<string name="permissionsExplanationGeneric">The app is current running in limited mode and has deactivated some features. To fully function it requires permissions. If you want to use all functionality you have to grant the permissions in the following rights dialogues. If you do, not certain rules can not be executed. In the following you are given an explanation for the requested permissions. Click "continue", when you are ready to proceed.</string>
<string name="permissionsExplanationSmall">To enable the feature you just tried to use more permissions are required. Click continue to request them.</string>
<string name="continueText">continue</string>
<string name="rule">Rule</string>
@ -560,7 +560,7 @@
<string name="android.permission.GET_TASKS">Detect running processes</string>
<string name="android.permission.WRITE_SETTINGS">Change device settings</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Detect device reboot</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Change device settings</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Change secure device settings</string>
<string name="android.permission.BATTERY_STATS">Read battery state</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Change data connection</string>
<string name="android.permission.SEND_SMS">Send text messages</string>
@ -889,4 +889,20 @@
<string name="wifiTriggerDisconnectionHint">This trigger will be valid if you just disconnected from the wifi specified above OR while the service is still starting and if you\'re not connected to any wifi. If you want the trigger to fire only when you\'re explicitly disconnecting from a certain wifi, add another trigger \"service is not starting\".</string>
<string name="className">Class full name</string>
<string name="startAppByStartForegroundService">by startForegroundService()</string>
<string name="method">Method</string>
<string name="methodGet" translatable="false">GET</string>
<string name="methodPost" translatable="false">POST</string>
<string name="takeScreenshot">Take screenshot</string>
<string name="android.permission.BIND_ACCESSIBILITY_SERVICE">Bind to accessibility service</string>
<string name="bindAccessibilityService">Bind to accessibility service</string>
<string name="accessibilityApiPermissionHint">After clicking OK you\'ll be sent to a system dialog. Please select Automation there and allow "Allow accessibility API".</string>
<string name="accessibility_service_explanation">Required for certain actions.</string>
<string name="noticeRestrictedPermissions">If you fail to grant one the following permission and a system message like \"Restricted permission\" you need to go to Android settings first, then applications, choose Automation. Now there should be 3 dots in the upper right corner. Click \"Allow restricted settings\". After that the necessary permission should be grantable. This should only apply to the APK version of the app, not the ones from F-Droid or Play Store.</string>
<string name="setLocationService">set location service</string>
<string name="writeSecureSettingsNotice">Unfortunately the permission WRITE_SECURE_SETTINGS cannot be given directly on your Android device. Instead you need to connect your device to a computer and grant the permission via ADB. Click here to find out how to grant it: https://server47.de/automation/adb_hack.php</string>
<string name="actionSetLocationService">Location service</string>
<string name="LOCATION_MODE_SENSOR_ONLY" translatable="false">SENSOR_ONLY</string>
<string name="LOCATION_MODE_BATTERY_SAVING" translatable="false">BATTERY_SAVING</string>
<string name="LOCATION_MODE_HIGH_ACCURACY" translatable="false">HIGH_ACCURACY</string>
<string name="triggerUrlVariableHint">The result of this request will be stored in the variable LAST_TRIGGERURL_RESULT if you wish to check it from another rule. In case of HTTP errors like 404 the value will be \"HTTP_ERROR\".</string>
</resources>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackSpoken"
android:canPerformGestures="false"
android:canRequestFilterKeyEvents="false"
android:canRequestFingerprintGestures="false"
android:canRetrieveWindowContent="false"
android:canTakeScreenshot="true"
android:notificationTimeout="0"
android:description="@string/accessibility_service_explanation" />

View File

@ -0,0 +1 @@
* Fixed: Crashes at service start that only affected the Google Play version because of a higher targetSdk

View File

@ -0,0 +1,8 @@
* Fixed: Overlay permission for start other program action only required if startByActivity() is selected
* Fixed: Broadcast receiver trigger would not trigger anything, but crash
* Fixed: Bug in Android 14 (not in Automation!!!) required a change when dialing MMI codes containing a # character.
* Fixed: Storage permission might be displayed as not granted even if it was
* Added: One can now choose between GET and POST when using triggerURL action
* Added: new action -> take screenshot
* Added: Location service (GPS) can be toggled between states if WRITE_SECURE_SETTINGS has been granted from a computer
* Added: Result of triggerUrl action is now stored in a variable if you wish to check it