10 Commits

Author SHA1 Message Date
7e72dfd19a Version 1.8.7 2026-03-06 22:22:34 +01:00
23223480e5 Version 1.8.6 2026-03-06 22:05:01 +01:00
e3e2a87b5e Http request action streamlined to also cover the insecure setting in the same function. 2026-03-01 00:20:53 +01:00
4cea4391eb Libraries updated 2026-02-28 22:52:42 +01:00
63150ed8f6 Libraries updated 2026-02-27 23:56:04 +01:00
d986fcdf4d Upgraded to Gradle 8.13.2 2026-02-27 23:09:30 +01:00
ea57dd01e5 Upgraded to Gradle 8.4.2 2026-02-27 23:07:22 +01:00
6f1f112d98 Further actions for trigger url action 2026-02-27 22:46:31 +01:00
549c4f109e Merge remote-tracking branch 'origin/development' into development 2026-02-25 23:02:02 +01:00
d63841dd27 Further actions for trigger url action 2026-02-25 23:01:45 +01:00
38 changed files with 191 additions and 53 deletions

View File

@@ -3,16 +3,16 @@ plugins {
} }
android { android {
compileSdkVersion 34 compileSdkVersion 36
defaultConfig { defaultConfig {
applicationId "com.jens.automation2" applicationId "com.jens.automation2"
minSdkVersion 16 minSdkVersion 19
compileSdkVersion 34 compileSdkVersion 36
buildToolsVersion '34.0.0' buildToolsVersion '36.0.0'
useLibrary 'org.apache.http.legacy' useLibrary 'org.apache.http.legacy'
versionCode 146 versionCode 148
versionName "1.8.5" versionName "1.8.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -36,7 +36,7 @@ android {
{ {
dimension "version" dimension "version"
versionNameSuffix "-googlePlay" versionNameSuffix "-googlePlay"
targetSdkVersion 35 targetSdkVersion 36
} }
/* /*
@@ -63,25 +63,25 @@ android {
checkReleaseBuilds false checkReleaseBuilds false
} }
namespace 'com.jens.automation2' namespace 'com.jens.automation2'
buildToolsVersion '34.0.0' buildToolsVersion '36.0.0'
} }
dependencies { dependencies {
implementation 'org.jetbrains:annotations:15.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:18.0.0' googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0'
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0' apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0' apkFlavorImplementation 'com.google.android.gms:play-services-location:20.0.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.28.1' implementation 'com.linkedin.dexmaker:dexmaker:2.28.6'
implementation 'org.apache.commons:commons-lang3:3.0' implementation 'org.apache.commons:commons-lang3:3.20.0'
//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'
implementation 'com.google.android.material:material:1.6.1' implementation 'com.google.android.material:material:1.6.1'
testImplementation 'junit:junit:4' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3' 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'
} }

View File

@@ -8,6 +8,7 @@ import android.widget.Toast;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@@ -689,8 +690,8 @@ public class Action
try try
{ {
url = Miscellaneous.replaceVariablesInText(url, context); url = Miscellaneous.replaceVariablesInText(url, context);
if(!StringUtils.isEmpty(params)) // if(!StringUtils.isEmpty(params))
params = Miscellaneous.replaceVariablesInText(params, context); // params = URLEncoder.encode(Miscellaneous.replaceVariablesInText(params, context), "UTF-8");
Actions myAction = new Actions(); Actions myAction = new Actions();
@@ -738,14 +739,24 @@ public class Action
{ {
// has params // has params
String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter); String[] paramPairs = parameters[4].split(Action.actionParameters2SeparatorOuter);
String value = "";
for(String pair : paramPairs) for(String pair : paramPairs)
{ {
String[] pieces = pair.split(Action.actionParameters2SeparatorInner); String[] pieces = pair.split(Action.actionParameters2SeparatorInner);
if(pieces.length == 2)
httpParams.put(pieces[0], pieces[1]); try
{
value = Miscellaneous.replaceVariablesInText(pieces[1], Miscellaneous.getAnyContext());
} }
catch (Exception e)
{
value = "error";
} }
if(pieces.length == 2)
httpParams.put(pieces[0], value);
}
}
} }
String response = httpErrorDefaultText; String response = httpErrorDefaultText;
@@ -758,10 +769,10 @@ public class Action
Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3); Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
// Either thorough checking or no encryption // Either thorough checking or no encryption
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https")) // if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams); response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword, method, httpParams);
else // else
response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams); // response = Miscellaneous.downloadUrlWithoutCertificateChecking(urlString, urlUsername, urlPassword, method, httpParams);
try try
{ {

View File

@@ -5,6 +5,7 @@ import android.app.TabActivity;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.nfc.NfcAdapter;
import android.os.Bundle; import android.os.Bundle;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.widget.TabHost; import android.widget.TabHost;
@@ -61,22 +62,24 @@ public class ActivityMainTabLayout extends TabActivity
tabHost.setCurrentTab(Settings.startScreen); tabHost.setCurrentTab(Settings.startScreen);
} }
@Override @Override
protected void onResume() protected void onResume()
{ {
super.onResume(); super.onResume();
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5); // Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
if(!(getIntent().getAction().isEmpty()) && getIntent().getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
{
NfcReceiver.checkIntentForNFC(this, getIntent()); NfcReceiver.checkIntentForNFC(this, getIntent());
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass())); moveTaskToBack(true);
}
} }
@Override @Override
protected void onNewIntent(Intent intent) protected void onNewIntent(Intent intent)
{ {
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5); // Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5);
// setIntent(intent);
NfcReceiver.checkIntentForNFC(this, intent); NfcReceiver.checkIntentForNFC(this, intent);
} }
} }

View File

@@ -19,6 +19,7 @@ import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.TableLayout; import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -38,6 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
CheckBox chkTriggerUrlUseAuthentication; CheckBox chkTriggerUrlUseAuthentication;
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost; RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
TableLayout tlTriggerUrlAuthentication; TableLayout tlTriggerUrlAuthentication;
TextView tvHttpParameterExplanation;
ArrayAdapter<String> httpParametersAdapter; ArrayAdapter<String> httpParametersAdapter;
private ArrayList<String> httpParamsList = new ArrayList<>(); private ArrayList<String> httpParamsList = new ArrayList<>();
@@ -67,6 +69,7 @@ public class ActivityManageActionTriggerUrl extends Activity
etParameterName = (EditText) findViewById(R.id.etParameterName); etParameterName = (EditText) findViewById(R.id.etParameterName);
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);
etParameterName.setEnabled(false); etParameterName.setEnabled(false);
etParameterValue.setEnabled(false); etParameterValue.setEnabled(false);
@@ -85,6 +88,8 @@ public class ActivityManageActionTriggerUrl extends Activity
} }
}); });
tvHttpParameterExplanation.setText(String.format(getResources().getString(R.string.httpParametersExplanation), Miscellaneous.httpMainData, Miscellaneous.doNoEncodingString));
httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList); httpParametersAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, httpParamsList);
bSaveTriggerUrl.setOnClickListener(new OnClickListener() bSaveTriggerUrl.setOnClickListener(new OnClickListener()

View File

@@ -92,6 +92,7 @@ import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.text.DateFormat; import java.text.DateFormat;
@@ -128,10 +129,34 @@ public class Miscellaneous extends Service
protected static String writeableFolderStringCache = null; protected static String writeableFolderStringCache = null;
protected final static String http_error_string = "HTTP_ERROR"; protected final static String http_error_string = "HTTP_ERROR";
protected final static String last_trigger_url_result_string = "last_trigger_url_result"; protected final static String last_trigger_url_result_string = "last_trigger_url_result";
protected final static String httpMainData = "httpMainData";
protected final static String doNoEncodingString = "NoEncoding";
protected final static String httpEncoding = "UTF-8";
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");
public static class TrustAllCertificates implements X509TrustManager
{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
{
// Do nothing (trust all clients)
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
{
// Do nothing (trust all servers)
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0]; // No accepted issuers
}
}
public static String downloadURL(String url, String username, String password, String method, Map<String, String> httpParams) public static String downloadURL(String url, String username, String password, String method, Map<String, String> httpParams)
{ {
HttpClient httpclient = new DefaultHttpClient(); HttpClient httpclient = new DefaultHttpClient();
@@ -148,6 +173,18 @@ public class Miscellaneous extends Service
if(url.toLowerCase().contains("https")) if(url.toLowerCase().contains("https"))
{ {
connection = (HttpsURLConnection) urlObject.openConnection(); connection = (HttpsURLConnection) urlObject.openConnection();
if(Settings.httpAcceptAllCertificates)
{
SSLContext sslContext = SSLContext.getInstance("TLS"); // Use "TLS" (not "SSL" which is outdated)
sslContext.init(
null, // No KeyManager (client authentication not needed)
new TrustManager[]{new TrustAllCertificates()}, // Use our trust manager
new SecureRandom() // Secure random number generator
);
((HttpsURLConnection)connection).setSSLSocketFactory(sslContext.getSocketFactory());
((HttpsURLConnection)connection).setHostnameVerifier((hostname, session) -> true); // Trust all hostnames
}
} }
else else
connection = (HttpURLConnection) urlObject.openConnection(); connection = (HttpURLConnection) urlObject.openConnection();
@@ -166,6 +203,7 @@ public class Miscellaneous extends Service
if(httpParams.size() > 0) if(httpParams.size() > 0)
{ {
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoInput(true); connection.setDoInput(true);
connection.setDoOutput(true); connection.setDoOutput(true);
@@ -175,8 +213,8 @@ public class Miscellaneous extends Service
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key))); paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
OutputStream os = connection.getOutputStream(); OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, httpEncoding));
writer.write(getQuery(paramPairs)); writer.write(getQuery(paramPairs, method));
writer.flush(); writer.flush();
writer.close(); writer.close();
} }
@@ -206,21 +244,52 @@ public class Miscellaneous extends Service
} }
} }
private static String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException private static String getQuery(List<NameValuePair> params, String method) throws UnsupportedEncodingException
{ {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
boolean first = true; boolean first = true;
for (NameValuePair pair : params) for (NameValuePair pair : params)
{
if (method.equals(ActivityManageActionTriggerUrl.methodGet))
{ {
if (first) if (first)
first = false; first = false;
else else
result.append("&"); result.append("&");
}
else if (pair.getName().startsWith(httpMainData))
continue; // if post and main data skip lookup run
result.append(pair.getName());
result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
result.append("="); result.append("=");
result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
if (pair.getName().endsWith(doNoEncodingString))
result.append(URLEncoder.encode(pair.getValue(), httpEncoding));
else
result.append(pair.getValue());
}
/*
If method is POST and there's a httpMainData field, we transfer
this one at the end without parameter name and equals sign.
*/
if (method.equals(ActivityManageActionTriggerUrl.methodPost))
{
for (NameValuePair pair : params)
{
if (pair.getName().startsWith(httpMainData))
{
if (pair.getName().endsWith(doNoEncodingString))
result.append(pair.getValue());
else
result.append(URLEncoder.encode(pair.getValue(), httpEncoding));
return result.toString();
}
}
} }
return result.toString(); return result.toString();
@@ -819,7 +888,7 @@ public class Miscellaneous extends Service
String notificationTitle = NotificationListener.getLastNotification().getTitle(); String notificationTitle = NotificationListener.getLastNotification().getTitle();
if (notificationTitle != null && notificationTitle.length() > 0) if (notificationTitle != null && notificationTitle.length() > 0)
source = source.replace("[notificationTitle]", escapeStringForUrl(notificationTitle)); source = source.replace("[notificationTitle]", notificationTitle);
else else
{ {
source = source.replace("[notificationTitle]", "notificationTitle unknown"); source = source.replace("[notificationTitle]", "notificationTitle unknown");

View File

@@ -711,7 +711,7 @@ public class XmlFileInterface
private static Rule readRule(XmlPullParser parser) throws XmlPullParserException, IOException private static Rule readRule(XmlPullParser parser) throws XmlPullParserException, IOException
{ {
/* FILE EXAMPE: /* FILE EXAMPLE:
* ***************** * *****************
* <Automation> * <Automation>
* <PointOfInterestCollection> * <PointOfInterestCollection>
@@ -1095,7 +1095,7 @@ public class XmlFileInterface
private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException private static Action readAction(XmlPullParser parser) throws IOException, XmlPullParserException
{ {
/* FILE EXAMPE: /* FILE EXAMPLE:
* ***************** * *****************
* <Automation> * <Automation>
* <PointOfInterestCollection> * <PointOfInterestCollection>

View File

@@ -140,6 +140,17 @@
</TableRow> </TableRow>
<TableRow>
<TextView
android:id="@+id/tvHttpParameterExplanation"
android:layout_span="2"
android:layout_marginBottom="@dimen/default_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View File

@@ -887,4 +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>
</resources> </resources>

View File

@@ -886,4 +886,5 @@
<string name="enterAvalue">Introduce un valor.</string> <string name="enterAvalue">Introduce un valor.</string>
<string name="setSystemSettingCapital">Establecer configuración del sistema</string> <string name="setSystemSettingCapital">Establecer configuración del sistema</string>
<string name="examplesWriteSecureSettings">No llevo una lista de posibles configuraciones. Por favor, busca <a href="https://developer.android.com/reference/android/provider/Settings.Secure">esas</a> configuraciones por tu cuenta. Véase aquí algunos ejemplos (incompletos).</string> <string name="examplesWriteSecureSettings">No llevo una lista de posibles configuraciones. Por favor, busca <a href="https://developer.android.com/reference/android/provider/Settings.Secure">esas</a> configuraciones por tu cuenta. Véase aquí algunos ejemplos (incompletos).</string>
<string name="httpParametersExplanation">Si el nombre de algún parámetro comienza por %1$s mientras el método es POST, no se transmitirá como los otros parámetros (con clave=valor), sino que se transferirá como datos principales. Si el parámetro termina en %2$s, no se realizará ninguna codificación.</string>
</resources> </resources>

View File

@@ -886,4 +886,5 @@
<string name="far">loin</string> <string name="far">loin</string>
<string name="proximityText">La proximité se situe entre \"%1$s\" et \"%2$s\"</string> <string name="proximityText">La proximité se situe entre \"%1$s\" et \"%2$s\"</string>
<string name="examplesWriteSecureSettings">Je ne tiens pas de liste des réglages possibles. Veuillez trouver ces réglages vous-même. Voir <a href="https://developer.android.com/reference/android/provider/Settings.Secure">ici</a> pour quelques exemples (incomplets).</string> <string name="examplesWriteSecureSettings">Je ne tiens pas de liste des réglages possibles. Veuillez trouver ces réglages vous-même. Voir <a href="https://developer.android.com/reference/android/provider/Settings.Secure">ici</a> pour quelques exemples (incomplets).</string>
<string name="httpParametersExplanation">Si un nom de paramètre commence par %1$s alors que la méthode est POST, il ne sera pas transmis comme les autres paramètres (avec clé=valeur), mais transféré comme données principales. Si le paramètre se termine par %2$s, aucun codage ne sera effectué.</string>
</resources> </resources>

View File

@@ -887,4 +887,5 @@
<string name="uiThemeSummary">Il tema dell\'interfaccia grafica utente. Domanda necessaria.</string> <string name="uiThemeSummary">Il tema dell\'interfaccia grafica utente. Domanda necessaria.</string>
<string name="proximity">Vicinanza</string> <string name="proximity">Vicinanza</string>
<string name="examplesWriteSecureSettings">Non tengo una lista di possibili impostazioni. Per favore, trova queste impostazioni da solo. Vedi <a href="https://developer.android.com/reference/android/provider/Settings.Secure">qui</a> per alcuni esempi (incompleti).</string> <string name="examplesWriteSecureSettings">Non tengo una lista di possibili impostazioni. Per favore, trova queste impostazioni da solo. Vedi <a href="https://developer.android.com/reference/android/provider/Settings.Secure">qui</a> per alcuni esempi (incompleti).</string>
<string name="httpParametersExplanation">Se un nome di parametro inizia con %1$s mentre il metodo è POST, non verrà trasmesso come gli altri parametri (con chiave=valore), ma trasferito come dato principale. Se il parametro termina con %2$s, non verrà eseguita alcuna codifica.</string>
</resources> </resources>

View File

@@ -885,4 +885,5 @@
<string name="enterAvalue">Voer een waarde in.</string> <string name="enterAvalue">Voer een waarde in.</string>
<string name="setSystemSettingCapital">Setsysteeminstelling</string> <string name="setSystemSettingCapital">Setsysteeminstelling</string>
<string name="examplesWriteSecureSettings">Ik houd geen lijst bij met mogelijke instellingen. Zoek die instellingen zelf op. Zie <a href="https://developer.android.com/reference/android/provider/Settings.Secure">hier</a> voor enkele (onvolledige) voorbeelden.</string> <string name="examplesWriteSecureSettings">Ik houd geen lijst bij met mogelijke instellingen. Zoek die instellingen zelf op. Zie <a href="https://developer.android.com/reference/android/provider/Settings.Secure">hier</a> voor enkele (onvolledige) voorbeelden.</string>
<string name="httpParametersExplanation">Als een parameternaam begint met %1$s terwijl de methode POST is, wordt deze niet verzonden zoals de andere parameters (met sleutel=waarde), maar als hoofddata overgedragen. Als de parameter eindigt op %2 s, wordt er geen codering uitgevoerd.</string>
</resources> </resources>

View File

@@ -984,4 +984,5 @@
<string name="enterAvalue">Wprowadź wartość.</string> <string name="enterAvalue">Wprowadź wartość.</string>
<string name="setSystemSettingCapital">Ustawienia systemu zbiorów</string> <string name="setSystemSettingCapital">Ustawienia systemu zbiorów</string>
<string name="examplesWriteSecureSettings">Nie prowadzę listy możliwych ustawień wyboru. Proszę, znajdź te ustawienia samodzielnie. Zobacz <a href="https://developer.android.com/reference/android/provider/Settings.Secure">tutaj</a> dla niektórych (niepełnych) przykładów.</string> <string name="examplesWriteSecureSettings">Nie prowadzę listy możliwych ustawień wyboru. Proszę, znajdź te ustawienia samodzielnie. Zobacz <a href="https://developer.android.com/reference/android/provider/Settings.Secure">tutaj</a> dla niektórych (niepełnych) przykładów.</string>
<string name="httpParametersExplanation">Jeśli nazwa parametru zaczyna się od %1$s, a metoda to POST, nie zostanie przesłana jak pozostałe parametry (z klucz=wartością), lecz przeniesiona jako dane główne. Jeśli parametr kończy się na %2$s, nie zostanie wykonane kodowanie.</string>
</resources> </resources>

View File

@@ -944,4 +944,5 @@
<string name="enterAvalue">Введите значение.</string> <string name="enterAvalue">Введите значение.</string>
<string name="setSystemSettingCapital">Настройка системы множества</string> <string name="setSystemSettingCapital">Настройка системы множества</string>
<string name="examplesWriteSecureSettings">Я не веду список возможных настроек. Пожалуйста, найдите эти настройки сами. См. <a href="https://developer.android.com/reference/android/provider/Settings.Secure">здесь</a> некоторые (неполные) примеры.</string> <string name="examplesWriteSecureSettings">Я не веду список возможных настроек. Пожалуйста, найдите эти настройки сами. См. <a href="https://developer.android.com/reference/android/provider/Settings.Secure">здесь</a> некоторые (неполные) примеры.</string>
<string name="httpParametersExplanation">Если имя любого параметра начинается с %1$s, а метод — POST, оно не будет передаваться как другие параметры (с ключом =значением), а передаваться как основные данные. Если параметр заканчивается на %2$s, кодирование не выполняется.</string>
</resources> </resources>

View File

@@ -885,4 +885,5 @@
<string name="enterAvalue">输入一个数值。</string> <string name="enterAvalue">输入一个数值。</string>
<string name="setSystemSettingCapital">集合系统设置</string> <string name="setSystemSettingCapital">集合系统设置</string>
<string name="examplesWriteSecureSettings">我没有列出可能的设置。请自己找到这些设置。请参见(此处)一些 <a href="https://developer.android.com/reference/android/provider/Settings.Secure">不完整的</a> 示例。</string> <string name="examplesWriteSecureSettings">我没有列出可能的设置。请自己找到这些设置。请参见(此处)一些 <a href="https://developer.android.com/reference/android/provider/Settings.Secure">不完整的</a> 示例。</string>
<string name="httpParametersExplanation">如果参数名以 %1$s 开头且方法为 POST则不会像其他参数key=value那样传输而是作为主数据传输。如果参数以 %2$s 结尾,则不会进行编码。</string>
</resources> </resources>

View File

@@ -977,4 +977,5 @@
<string name="enterAvalue">Enter a value.</string> <string name="enterAvalue">Enter a value.</string>
<string name="setSystemSettingCapital">Set system setting</string> <string name="setSystemSettingCapital">Set system setting</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="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>
</resources> </resources>

View File

@@ -2,10 +2,10 @@
buildscript { buildscript {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.2.2' classpath 'com.android.tools.build:gradle:8.13.2'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@@ -15,7 +15,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }

View File

@@ -0,0 +1,2 @@
* Hinzugefügt: Weitere Optionen für die Trigger-URL-Aktion hinzugefügt.
* Hinzugefügt: Gradle und Bibliotheken aktualisiert.

View File

@@ -0,0 +1 @@
* Geändert: MinSdk auf 19 erhöht, benötigt mindestens Android 4.4

View File

@@ -0,0 +1,2 @@
* Added: Added further options to the trigger url action.
* Added: Gradle and libraries updated.

View File

@@ -0,0 +1 @@
* Changed: Raised minSdk to 19, requiring at minimum Android 4.4

View File

@@ -64,8 +64,8 @@ Supported actions:
* Change location setting * Change location setting
* Send text message * Send text message
It's quite hard to keep this app working across the many different hardwares as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs. It's quite hard to keep this app working across the many different devices as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs.
So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reasonably reported to me. But for that I'm dependend on your input. So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reasonably reported to me. But for that I'm dependent on your input.
If you have a problem and think about contacting me please If you have a problem and think about contacting me please
- update to the latest version first and see if your problem persists there, too. - update to the latest version first and see if your problem persists there, too.

View File

@@ -0,0 +1,2 @@
* Añadido: Se añadieron más opciones a la acción de disparar URL.
* Añadido: Gradle y bibliotecas actualizadas.

View File

@@ -0,0 +1 @@
* Cambiado: Subido minSdk a 19, requiriendo al mínimo Android 4.4

View File

@@ -0,0 +1,2 @@
* Ajouté : Ajout d'options supplémentaires à l'action de déclenchement de l'URL.
* Ajouté : Gradle et bibliothèques mises à jour.

View File

@@ -0,0 +1 @@
* Modifié : Portée du minSdk à 19, nécessitant au minimum Android 4.4

View File

@@ -0,0 +1,2 @@
* Aggiunto: Aggiunte ulteriori opzioni all'azione di trigger URL.
* Aggiunto: Gradle e biblioteche aggiornate.

View File

@@ -0,0 +1 @@
* Modificato: Aumentato il minSdk a 19, richiedendo almeno Android 4.4

View File

@@ -0,0 +1,2 @@
* Toegevoegd: Extra opties toegevoegd aan de trigger-urlactie.
* Toegevoegd: Gradle en bibliotheken bijgewerkt.

View File

@@ -0,0 +1 @@
* Gewijzigd: minSdk verhoogd naar 19, minimaal Android 4.4 vereist

View File

@@ -0,0 +1,2 @@
* Dodano: Dodano dodatkowe opcje akcji trigger url.
* Dodano: Zaktualizowano Gradle i biblioteki.

View File

@@ -0,0 +1 @@
* Zmieniono: Podniesiono minSdk do 19, wymagając co najmniej Androida 4.4

View File

@@ -0,0 +1,2 @@
* Добавлено: добавлены дополнительные опции к действию триггера URL.
* Добавлено: обновлены Gradle и библиотеки.

View File

@@ -0,0 +1 @@
* Изменено: minSdk повышен до 19, требуется минимум Android 4.4

View File

@@ -0,0 +1,2 @@
* 新增为触发URL动作增加了更多选项。
* 新增Gradle及图书馆更新。

View File

@@ -0,0 +1 @@
* 更改:将 minSDK 提升至 19至少要求 Android 4.4

View File

@@ -17,3 +17,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX # Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

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