Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e6e89b38a | ||
|
|
cad2e9df9d | ||
|
|
b803df9685 | ||
|
|
14f525ec80 | ||
|
|
3a46e8918d |
No files matched your search
+7
-5
@@ -7,7 +7,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.jens.automation2"
|
applicationId "com.jens.automation2"
|
||||||
minSdkVersion 19
|
minSdkVersion 24
|
||||||
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,8 +77,6 @@ android {
|
|||||||
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 'org.simplejavamail:simple-java-mail:9.3.5'
|
|
||||||
|
|
||||||
//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'
|
||||||
@@ -86,4 +84,8 @@ android {
|
|||||||
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"
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,8 @@
|
|||||||
<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" />
|
||||||
@@ -274,6 +275,14 @@
|
|||||||
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>
|
||||||
|
|||||||
@@ -260,6 +260,14 @@
|
|||||||
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>
|
||||||
|
|||||||
@@ -60,9 +60,7 @@
|
|||||||
<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"/>
|
||||||
@@ -255,13 +253,20 @@
|
|||||||
android:value="@integer/google_play_services_version" />
|
android:value="@integer/google_play_services_version" />
|
||||||
<service android:name=".location.GeofenceIntentService"/>
|
<service android:name=".location.GeofenceIntentService"/>
|
||||||
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".FileShareProvider"
|
android:name=".FileShareProvider"
|
||||||
android:authorities="com.jens.automation2"
|
android:authorities="com.jens.automation2"
|
||||||
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" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -18,6 +18,7 @@ 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;
|
||||||
@@ -73,6 +74,8 @@ 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;
|
||||||
@@ -541,7 +544,7 @@ public class Actions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(Build.VERSION.SDK_INT < 36)
|
||||||
{
|
{
|
||||||
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback()
|
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback()
|
||||||
{
|
{
|
||||||
@@ -564,6 +567,13 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -1098,18 +1108,18 @@ public class Actions
|
|||||||
// {
|
// {
|
||||||
// ssf = new MySSLSocketFactory(ctx);
|
// ssf = new MySSLSocketFactory(ctx);
|
||||||
// ssf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
|
// ssf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
|
||||||
//
|
//
|
||||||
// char[] keystorePass="insecure".toCharArray(); //passphrase for keystore
|
// char[] keystorePass="insecure".toCharArray(); //passphrase for keystore
|
||||||
// KeyStore keyStore=KeyStore.getInstance("BKS");
|
// KeyStore keyStore=KeyStore.getInstance("BKS");
|
||||||
//
|
//
|
||||||
//// String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
//// String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||||
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
|
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
|
||||||
// tmf.init(keyStore);
|
// tmf.init(keyStore);
|
||||||
//
|
//
|
||||||
// Miscellaneous.logEvent("i", "SSL Keystore", context.getCacheDir().toString(), 4);
|
// Miscellaneous.logEvent("i", "SSL Keystore", context.getCacheDir().toString(), 4);
|
||||||
// InputStream is = context.getResources().openRawResource(R.raw.keystore);
|
// InputStream is = context.getResources().openRawResource(R.raw.keystore);
|
||||||
// keyStore.load(is,keystorePass);
|
// keyStore.load(is,keystorePass);
|
||||||
//
|
//
|
||||||
// ctx.init(null, tmf.getTrustManagers(), null);
|
// ctx.init(null, tmf.getTrustManagers(), null);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
@@ -1222,7 +1232,10 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -2674,33 +2687,71 @@ 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()
|
|
||||||
{
|
{
|
||||||
Properties props = new Properties();
|
private static final Executor EXECUTOR = Executors.newSingleThreadExecutor();
|
||||||
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");
|
|
||||||
|
|
||||||
Session session = Session.getInstance(props, new Authenticator() {
|
private WifiTethering()
|
||||||
@Override
|
{
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
// Utility class
|
||||||
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");
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
Message message = new MimeMessage(session);
|
TetheringManager tetheringManager = context.getSystemService(TetheringManager.class);
|
||||||
message.setFrom(new InternetAddress(fromAddress));
|
|
||||||
message.setRecipients(
|
|
||||||
Message.RecipientType.TO,
|
|
||||||
InternetAddress.parse(recipientAddress)
|
|
||||||
);
|
|
||||||
message.setSubject(subject);
|
|
||||||
message.setText(body);
|
|
||||||
|
|
||||||
Transport.send(message);
|
TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build();
|
||||||
|
|
||||||
|
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,9 +6,6 @@ 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;
|
||||||
@@ -30,13 +27,9 @@ 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
|
||||||
{
|
{
|
||||||
@@ -46,7 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
|
|||||||
CheckBox chkTriggerUrlUseAuthentication;
|
CheckBox chkTriggerUrlUseAuthentication;
|
||||||
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
|
RadioButton rbTriggerUrlMethodGet, rbTriggerUrlMethodPost;
|
||||||
TableLayout tlTriggerUrlAuthentication;
|
TableLayout tlTriggerUrlAuthentication;
|
||||||
TextView tvHttpParameterExplanation, tvUrlValidator;
|
TextView tvHttpParameterExplanation;
|
||||||
ArrayAdapter<String> httpParametersAdapter;
|
ArrayAdapter<String> httpParametersAdapter;
|
||||||
|
|
||||||
private ArrayList<String> httpParamsList = new ArrayList<>();
|
private ArrayList<String> httpParamsList = new ArrayList<>();
|
||||||
@@ -77,7 +70,6 @@ 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);
|
||||||
@@ -181,33 +173,6 @@ 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,12 +102,6 @@ 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");
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import rikka.shizuku.Shizuku;
|
||||||
|
|
||||||
public class ActivityPermissions extends Activity
|
public class ActivityPermissions extends Activity
|
||||||
{
|
{
|
||||||
static Map<String, String> mapGeneralPermissions = null;
|
static Map<String, String> mapGeneralPermissions = null;
|
||||||
@@ -58,6 +60,7 @@ public class ActivityPermissions extends Activity
|
|||||||
private static final int requestCodeForPermissionsManageOverlay = 12050;
|
private static final int requestCodeForPermissionsManageOverlay = 12050;
|
||||||
private static final int requestCodeForPermissionsAccessibility = 12051;
|
private static final int requestCodeForPermissionsAccessibility = 12051;
|
||||||
private static final int requestCodeForPermissionsScheduleExactAlarms = 12052;
|
private static final int requestCodeForPermissionsScheduleExactAlarms = 12052;
|
||||||
|
private static final int requestCodeForPermissionsShizuku = 12053;
|
||||||
protected String[] specificPermissionsToRequest = null;
|
protected String[] specificPermissionsToRequest = null;
|
||||||
|
|
||||||
public static String intentExtraName = "permissionsToBeRequested";
|
public static String intentExtraName = "permissionsToBeRequested";
|
||||||
@@ -70,6 +73,7 @@ public class ActivityPermissions extends Activity
|
|||||||
public final static String permissionNameGoogleActivityDetection = "com.google.android.gms.permission.ACTIVITY_RECOGNITION";
|
public final static String permissionNameGoogleActivityDetection = "com.google.android.gms.permission.ACTIVITY_RECOGNITION";
|
||||||
public final static String permissionNameSuperuser = "android.permission.ACCESS_SUPERUSER";
|
public final static String permissionNameSuperuser = "android.permission.ACCESS_SUPERUSER";
|
||||||
public final static String permissionNameProximity = "android.hardware.sensor.proximity";
|
public final static String permissionNameProximity = "android.hardware.sensor.proximity";
|
||||||
|
public final static String permissionNameShizuku = "android_permission_shizuku";
|
||||||
|
|
||||||
public static ActivityPermissions getInstance()
|
public static ActivityPermissions getInstance()
|
||||||
{
|
{
|
||||||
@@ -273,6 +277,11 @@ public class ActivityPermissions extends Activity
|
|||||||
if (!havePermission(s, context))
|
if (!havePermission(s, context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(s.equalsIgnoreCase(permissionNameShizuku))
|
||||||
|
{
|
||||||
|
if(!ShizukuAccess.isAuthorized())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (!havePermission(s, context))
|
else if (!havePermission(s, context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -529,6 +538,7 @@ public class ActivityPermissions extends Activity
|
|||||||
|
|
||||||
if (rule.isRuleActive())
|
if (rule.isRuleActive())
|
||||||
{
|
{
|
||||||
|
addToArrayListUnique(permissionNameShizuku, requiredPermissions);
|
||||||
for (Trigger trigger : rule.getTriggerSet())
|
for (Trigger trigger : rule.getTriggerSet())
|
||||||
{
|
{
|
||||||
switch (trigger.getTriggerType())
|
switch (trigger.getTriggerType())
|
||||||
@@ -1390,6 +1400,11 @@ public class ActivityPermissions extends Activity
|
|||||||
Linkify.addLinks((TextView) diaglog.findViewById(android.R.id.message), Linkify.ALL);
|
Linkify.addLinks((TextView) diaglog.findViewById(android.R.id.message), Linkify.ALL);
|
||||||
// return;
|
// return;
|
||||||
}
|
}
|
||||||
|
else if(s.equals(permissionNameShizuku))
|
||||||
|
{
|
||||||
|
ShizukuAccess.requestAuthorization();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1909,4 +1924,34 @@ public class ActivityPermissions extends Activity
|
|||||||
// have all
|
// have all
|
||||||
setHaveAllPermissions();
|
setHaveAllPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final static class ShizukuAccess
|
||||||
|
{
|
||||||
|
private ShizukuAccess()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAvailable()
|
||||||
|
{
|
||||||
|
return !Shizuku.isPreV11() && Shizuku.pingBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAuthorized()
|
||||||
|
{
|
||||||
|
return isAvailable() && Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void requestAuthorization()
|
||||||
|
{
|
||||||
|
if (!isAvailable())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Shizuku.checkSelfPermission() != PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
Shizuku.requestPermission(requestCodeForPermissionsShizuku);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,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, FLAG_IMMUTABLE);
|
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||||
|
|
||||||
Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
|
Miscellaneous.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
|
||||||
|
|
||||||
|
|||||||
@@ -105,8 +105,6 @@ 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;
|
||||||
@@ -135,9 +133,6 @@ 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");
|
||||||
@@ -2433,13 +2428,4 @@ 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,12 +35,6 @@
|
|||||||
|
|
||||||
</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"
|
||||||
|
|||||||
@@ -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$s 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 % endet, wird keine Codierung durchgeführt.</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -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 Wi-Fi 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 wifis 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,5 +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>
|
<string name="android_permission_shizuku" translatable="false">Shizuku</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,4 +1 @@
|
|||||||
* 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
|
|
||||||
Reference in new issue
Block a user