Compare commits

..
Author SHA1 Message Date
jens 41cfeb43fc send emails 2026-10-10 16:45:37 +02:00
jens 72040b54ae send emails 2026-10-03 18:08:22 +02:00
jens ab2b0ce34c Removed contacts permission from Google Play version 2026-10-03 17:00:11 +02:00
jens ce32502eaa URL checker 2026-10-01 18:29:17 +02:00
jens 81812eba1b Bug in German translation 2026-09-30 18:22:12 +02:00
13 changed files with 259 additions and 98 deletions

No files matched your search

+5 -7
View File
@@ -7,7 +7,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.jens.automation2" applicationId "com.jens.automation2"
minSdkVersion 24 minSdkVersion 19
compileSdkVersion 37 compileSdkVersion 37
buildToolsVersion '36.0.0' buildToolsVersion '36.0.0'
useLibrary 'org.apache.http.legacy' useLibrary 'org.apache.http.legacy'
@@ -61,12 +61,12 @@ android {
lint { lint {
abortOnError false abortOnError false
checkReleaseBuilds false checkReleaseBuilds false
} dependencies }
namespace 'com.jens.automation2' namespace 'com.jens.automation2'
buildToolsVersion '36.0.0' buildToolsVersion '36.0.0'
} }
dependencies { {
implementation 'org.jetbrains:annotations:26.1.0' implementation 'org.jetbrains:annotations:26.1.0'
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0' googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0' googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0'
@@ -77,6 +77,8 @@ dependencies {
implementation 'com.linkedin.dexmaker:dexmaker:2.28.6' implementation 'com.linkedin.dexmaker:dexmaker:2.28.6'
implementation 'org.apache.commons:commons-lang3:3.20.0' implementation 'org.apache.commons:commons-lang3:3.20.0'
implementation 'com.sun.mail:android-mail:1.6.4'
//implementation "androidx.security:security-crypto:1.0.0" //implementation "androidx.security:security-crypto:1.0.0"
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02" //implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.appcompat:appcompat:1.4.2'
@@ -84,8 +86,4 @@ dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
def shizuku_version = "13.1.5"
implementation "dev.rikka.shizuku:api:$shizuku_version"
implementation "dev.rikka.shizuku:provider:$shizuku_version"
} }
+1 -10
View File
@@ -82,8 +82,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
dev.shadoe.delta.action.START_SOFT_AP
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
android:required="false" /> android:required="false" />
@@ -275,14 +274,6 @@
android:exported="true" android:exported="true"
/> />
<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:enabled="true"
android:exported="true"
android:multiprocess="false"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
<service android:name=".MyAccessibilityService" <service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter> <intent-filter>
+3 -1
View File
@@ -60,7 +60,9 @@
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" /> <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" /> <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS"/> <!--
Removed due to latest threat mail from Google:
<uses-permission android:name="android.permission.READ_CONTACTS"/>-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/> <uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/> <uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
@@ -18,7 +18,6 @@ import android.content.Intent;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.TetheringManager;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build; import android.os.Build;
@@ -74,8 +73,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@@ -544,7 +541,7 @@ public class Actions
} }
} }
} }
else if(Build.VERSION.SDK_INT < 36) else
{ {
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback() MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback()
{ {
@@ -567,13 +564,6 @@ public class Actions
else else
mowm.stopTethering(); mowm.stopTethering();
} }
else // from Android 16 onwards
{
if(desiredState)
Actions.WifiTethering.enable(context);
else
Actions.WifiTethering.disable(context);
}
} }
return true; return true;
} }
@@ -1232,10 +1222,7 @@ public class Actions
else if (startupType.equals(ActivityManageActionStartActivity.startByForegroundServiceString) && Build.VERSION.SDK_INT >= 26) else if (startupType.equals(ActivityManageActionStartActivity.startByForegroundServiceString) && Build.VERSION.SDK_INT >= 26)
automationServerRef.startForegroundService(externalApplicationIntent); automationServerRef.startForegroundService(externalApplicationIntent);
else else
{
externalApplicationIntent.addCategory("");
automationServerRef.sendBroadcast(externalApplicationIntent); automationServerRef.sendBroadcast(externalApplicationIntent);
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -2687,71 +2674,33 @@ public class Actions
// } // }
android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState)); android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState));
} }
public static final class WifiTethering
/*public static sendEmail()
{ {
private static final Executor EXECUTOR = Executors.newSingleThreadExecutor(); Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.connectiontimeout", "10000");
props.put("mail.smtp.timeout", "10000");
private WifiTethering() Session session = Session.getInstance(props, new Authenticator() {
{ @Override
// Utility class protected PasswordAuthentication getPasswordAuthentication() {
} return new PasswordAuthentication(username, password);
public static void enable(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.BAKLAVA)
{
throw new UnsupportedOperationException("TetheringManager requires Android 16 / API 36");
} }
});
TetheringManager tetheringManager = context.getSystemService(TetheringManager.class); Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromAddress));
message.setRecipients(
Message.RecipientType.TO,
InternetAddress.parse(recipientAddress)
);
message.setSubject(subject);
message.setText(body);
TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build(); Transport.send(message);
}*/
tetheringManager.startTethering(request, EXECUTOR, new TetheringManager.StartTetheringCallback() {
@Override
public void onTetheringStarted()
{
// Wi-Fi hotspot enabled
Miscellaneous.logEvent("i", "Tethering start", "Success", 3);
}
@Override
public void onTetheringFailed(int error)
{
// Hotspot could not be enabled
Miscellaneous.logEvent("i", "Tethering start", "Failure. Error code: " + String.valueOf(error), 3);
}
}
);
}
public static void disable(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.BAKLAVA)
{
throw new UnsupportedOperationException("TetheringManager requires Android 16 / API 36");
}
TetheringManager tetheringManager = context.getSystemService(TetheringManager.class);
TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build();
// tetheringManager.stopTethering(TetheringManager.TETHERING_WIFI, EXECUTOR, new TetheringManager.StopTetheringCallback() {
tetheringManager.stopTethering(request, EXECUTOR, new TetheringManager.StopTetheringCallback() {
@Override
public void onStopTetheringSucceeded()
{
TetheringManager.StopTetheringCallback.super.onStopTetheringSucceeded();
Miscellaneous.logEvent("i", "Tethering stop", "Success", 3);
}
@Override
public void onStopTetheringFailed(int error)
{
// Hotspot could not be disabled
Miscellaneous.logEvent("i", "Tethering stop", "Failure. Error code: " + String.valueOf(error), 3);
}
}
);
}
}
} }
@@ -6,6 +6,9 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
@@ -27,9 +30,13 @@ import androidx.annotation.NonNull;
import com.jens.automation2.Action.Action_Enum; import com.jens.automation2.Action.Action_Enum;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Text;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
public class ActivityManageActionTriggerUrl extends Activity public class ActivityManageActionTriggerUrl extends Activity
{ {
@@ -39,7 +46,7 @@ public class ActivityManageActionTriggerUrl extends Activity
CheckBox chkTriggerUrlUseAuthentication; CheckBox chkTriggerUrlUseAuthentication;
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost; RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
TableLayout tlTriggerUrlAuthentication; TableLayout tlTriggerUrlAuthentication;
TextView tvHttpParameterExplanation; TextView tvHttpParameterExplanation, tvUrlValidator;
ArrayAdapter<String> httpParametersAdapter; ArrayAdapter<String> httpParametersAdapter;
private ArrayList<String> httpParamsList = new ArrayList<>(); private ArrayList<String> httpParamsList = new ArrayList<>();
@@ -70,6 +77,7 @@ public class ActivityManageActionTriggerUrl extends Activity
etParameterValue = (EditText)findViewById(R.id.etParameterValue); etParameterValue = (EditText)findViewById(R.id.etParameterValue);
bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam); bAddHttpParam = (Button)findViewById(R.id.bAddHttpParam);
tvHttpParameterExplanation = (TextView)findViewById(R.id.tvHttpParameterExplanation); tvHttpParameterExplanation = (TextView)findViewById(R.id.tvHttpParameterExplanation);
tvUrlValidator = (TextView)findViewById(R.id.tvUrlValidator);
etParameterName.setEnabled(false); etParameterName.setEnabled(false);
etParameterValue.setEnabled(false); etParameterValue.setEnabled(false);
@@ -173,6 +181,33 @@ public class ActivityManageActionTriggerUrl extends Activity
}); });
updateListView(); updateListView();
etTriggerUrl.addTextChangedListener(new TextWatcher()
{
@Override
public void afterTextChanged(Editable editable)
{
if(etTriggerUrl.getText() != null && etTriggerUrl.getText().length() > 0)
{
if(Miscellaneous.isValidUrl(etTriggerUrl.getText().toString()))
tvUrlValidator.setText("");
else
tvUrlValidator.setText(getResources().getString(R.string.enter_valid_url));
}
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
});
if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2)) if(getIntent().hasExtra(ActivityManageRule.intentNameActionParameter2))
{ {
// username,password,URL,etc. // username,password,URL,etc.
@@ -102,6 +102,12 @@ public class ActivityManageTriggerPhoneCall extends Activity
@Override @Override
public void onClick(View view) public void onClick(View view)
{ {
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
{
Miscellaneous.messageBox(getResources().getString(R.string.info), getResources().getString(R.string.featureNotInGooglePlayVersion), ActivityManageTriggerPhoneCall.this).show();
return;
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageTriggerPhoneCall.this)) if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageTriggerPhoneCall.this))
{ {
requestPermissions("android.permission.READ_CONTACTS"); requestPermissions("android.permission.READ_CONTACTS");
@@ -21,6 +21,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.os.StrictMode;
import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener; import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log; import android.util.Log;
@@ -36,11 +37,20 @@ import com.jens.automation2.receivers.DateTimeListener;
import com.jens.automation2.receivers.PackageReplacedReceiver; import com.jens.automation2.receivers.PackageReplacedReceiver;
import com.jens.automation2.receivers.PhoneStatusListener; import com.jens.automation2.receivers.PhoneStatusListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
@SuppressLint("NewApi") @SuppressLint("NewApi")
public class AutomationService extends Service implements OnInitListener public class AutomationService extends Service implements OnInitListener
{ {
@@ -429,6 +439,25 @@ public class AutomationService extends Service implements OnInitListener
Settings.writeSettings(Miscellaneous.getAnyContext()); Settings.writeSettings(Miscellaneous.getAnyContext());
} }
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
EmailService es = new EmailService(Settings.smtpServerName, Integer.parseInt(Settings.smtpServerPort));
List addresses = new ArrayList();
addresses.add(Settings.smtpFromAddress);
try
{
EmailService.Email em = new EmailService.Email(new EmailService.UserPassAuthenticator(Settings.smtpUsername, Settings.smtpPassword), addresses, new InternetAddress(String.valueOf(addresses.get(0))), "test", "testbody");
es.send(em);
}
catch (AddressException e)
{
throw new RuntimeException(e);
}
catch (MessagingException e)
{
throw new RuntimeException(e);
}
Settings.serviceStartDone = true; Settings.serviceStartDone = true;
Settings.deviceStartDone = true; Settings.deviceStartDone = true;
} }
@@ -469,7 +498,7 @@ public class AutomationService extends Service implements OnInitListener
if(displayNotification) if(displayNotification)
{ {
Intent intent = new Intent(AutomationService.this, ActivityPermissions.class); Intent intent = new Intent(AutomationService.this, ActivityPermissions.class);
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0); PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, FLAG_IMMUTABLE);
Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5); Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
@@ -0,0 +1,127 @@
package com.jens.automation2;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class EmailService
{
private final String server;
private final int port;
public static final String CLIENT_NAME = "Android StackOverflow programmatic email";
public EmailService(String server, int port)
{
this.server = server;
this.port = port;
}
public static class Email
{
private final Authenticator auth;
private final List<InternetAddress> toList;
private final Address from;
private final String subject;
private final String body;
public Email(Authenticator auth, List<InternetAddress> toList, Address from, String subject, String body)
{
this.auth = auth;
this.toList = toList;
this.from = from;
this.subject = subject;
this.body = body;
}
public Authenticator getAuth()
{
return auth;
}
public List<InternetAddress> getToList()
{
return toList;
}
public Address getFrom()
{
return from;
}
public String getSubject()
{
return subject;
}
public String getBody()
{
return body;
}
}
public static class UserPassAuthenticator extends Authenticator
{
private final String username;
private final String password;
public UserPassAuthenticator(String username, String password)
{
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(username, password);
}
}
public void send(Email email) throws MessagingException
{
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.user", email.getFrom().toString());
props.put("mail.smtp.host", server);
props.put("mail.smtp.port", String.valueOf(port));
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.trust", server);
props.put("mail.mime.charset", "UTF-8");
Session session = Session.getDefaultInstance(props, email.getAuth());
MimeMessage msg = new MimeMessage(session);
msg.setFrom(email.getFrom());
msg.setSentDate(Calendar.getInstance().getTime());
Address[] toarray = new Address[]{email.getFrom()};
msg.setRecipients(Message.RecipientType.TO, toarray);
// msg.setRecipients(Message.RecipientType.TO, email.getToList().toArray(new InternetAddress[0]));
msg.setReplyTo(new Address[]{email.getFrom()});
msg.addHeader("X-Mailer", CLIENT_NAME);
msg.addHeader("Precedence", "bulk");
msg.setSubject(email.getSubject());
MimeMultipart multipart = new MimeMultipart();
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setText(email.getBody(), "iso-8859-1");
multipart.addBodyPart(bodyPart);
msg.setContent(multipart);
Transport.send(msg);
}
}
@@ -105,6 +105,8 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
@@ -133,6 +135,9 @@ public class Miscellaneous extends Service
protected final static String httpMainData = "httpMainData"; protected final static String httpMainData = "httpMainData";
protected final static String doNoEncodingString = "NoEncoding"; protected final static String doNoEncodingString = "NoEncoding";
protected final static String httpEncoding = "UTF-8"; protected final static String httpEncoding = "UTF-8";
protected final static String URL_REGEX = "^(https?):\\/\\/([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*)(:[0-9]{1,5})?([\\/\\?#].*)?$";
// protected final static String URL_REGEX = "^(https?|ftp):\\/\\/([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*)(:[0-9]{1,5})?([\\/\\?#].*)?$";
protected final static Pattern URL_PATTERN = Pattern.compile(URL_REGEX, Pattern.CASE_INSENSITIVE);
public static Context startupContext; public static Context startupContext;
public static final String lineSeparator = System.getProperty("line.separator"); public static final String lineSeparator = System.getProperty("line.separator");
@@ -2428,4 +2433,13 @@ public class Miscellaneous extends Service
StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4]; StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
return callingFrame.getMethodName(); return callingFrame.getMethodName();
} }
public static boolean isValidUrl(String input)
{
if (input == null || input.length() == 0)
return false;
Matcher matcher = URL_PATTERN.matcher(input);
return matcher.matches(); // Returns true if the entire string matches
}
} }
@@ -35,6 +35,12 @@
</EditText> </EditText>
<TextView
android:id="@+id/tvUrlValidator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
+1 -1
View File
@@ -887,5 +887,5 @@
<string name="enterAvalue">Geben Sie einen Wert ein.</string> <string name="enterAvalue">Geben Sie einen Wert ein.</string>
<string name="setSystemSettingCapital">Systemeinstellung setzen</string> <string name="setSystemSettingCapital">Systemeinstellung setzen</string>
<string name="examplesWriteSecureSettings">Ich führe keine Liste möglicher Einstellungen. Bitte finden Sie diese Einstellungen selbst. Siehe <a href="https://developer.android.com/reference/android/provider/Settings.Secure">hier</a> für einige (unvollständige) Beispiele.</string> <string name="examplesWriteSecureSettings">Ich führe keine Liste möglicher Einstellungen. Bitte finden Sie diese Einstellungen selbst. Siehe <a href="https://developer.android.com/reference/android/provider/Settings.Secure">hier</a> für einige (unvollständige) Beispiele.</string>
<string name="httpParametersExplanation">Beginnt ein Parametername mit %1$s, während die Methode POST ist, wird er nicht wie die anderen Parameter (mit Schlüssel=Wert) übertragen, sondern als Hauptdaten übertragen. Wenn der Parameter mit 2 % endet, wird keine Codierung durchgeführt.</string> <string name="httpParametersExplanation">Beginnt ein Parametername mit %1$s, während die Methode POST ist, wird er nicht wie die anderen Parameter (mit Schlüssel=Wert) übertragen, sondern als Hauptdaten übertragen. Wenn der Parameter mit %2$s endet, wird keine Codierung durchgeführt.</string>
</resources> </resources>
+2 -1
View File
@@ -698,7 +698,7 @@
<string name="bottom">Bottom</string> <string name="bottom">Bottom</string>
<string name="tabsPlacement">Position of tab bar</string> <string name="tabsPlacement">Position of tab bar</string>
<string name="tabsPlacementSummary">Choose where the tabs bar should be placed.</string> <string name="tabsPlacementSummary">Choose where the tabs bar should be placed.</string>
<string name="wifiApi30">Because Google screwed up yet another part of Android, starting with API 30 only the currently visible wifis can be displayed, not all the ones your device has connected to anymore.</string> <string name="wifiApi30">Because Google screwed up yet another part of Android, starting with API 30 only the currently visible Wi-Fi can be displayed, not all the ones your device has connected to anymore.</string>
<string name="silentTriggersDnd">REMARK: The silent mode often triggers Do-Not-Disturb on newer devices. If that happens on your device, I recommend using the normal mode instead and lowering all volumes to zero.</string> <string name="silentTriggersDnd">REMARK: The silent mode often triggers Do-Not-Disturb on newer devices. If that happens on your device, I recommend using the normal mode instead and lowering all volumes to zero.</string>
<string name="tones">Tones</string> <string name="tones">Tones</string>
<string name="miscellaneous">Miscellaneous</string> <string name="miscellaneous">Miscellaneous</string>
@@ -979,4 +979,5 @@
<string name="examplesWriteSecureSettings">I do not keep a list of possible settings. Please find those settings on your own. See <a href="https://developer.android.com/reference/android/provider/Settings.Secure">here</a> for some (incomplete) examples.</string> <string name="examplesWriteSecureSettings">I do not keep a list of possible settings. Please find those settings on your own. See <a href="https://developer.android.com/reference/android/provider/Settings.Secure">here</a> for some (incomplete) examples.</string>
<string name="httpParametersExplanation">If any parameter name starts with %1$s while method is POST, it will not be transmitted like the other parameters (with key=value), but transferred as main data. If the parameter ends with %2$s, no encoding will be performed.</string> <string name="httpParametersExplanation">If any parameter name starts with %1$s while method is POST, it will not be transmitted like the other parameters (with key=value), but transferred as main data. If the parameter ends with %2$s, no encoding will be performed.</string>
<string name="target">Target</string> <string name="target">Target</string>
<string name="enter_valid_url">Enter a valid URL.</string>
</resources> </resources>
@@ -1 +1,4 @@
* Added: Triggers and actions can now be cloned * Added: Triggers and actions can now be cloned
* Added: URL checker for triggerUrl action
* Fixed: Crash when starting to add/edit a triggerURL action while the app or the system are set to the German language
* Fixed: Crash when starting service in Google Play version