2377 lines
79 KiB
Java
Raw Normal View History

2021-02-16 13:42:49 +01:00
package com.jens.automation2;
import android.Manifest;
2023-12-14 00:15:59 +01:00
import android.accessibilityservice.AccessibilityService;
2021-02-16 13:42:49 +01:00
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
2021-09-12 20:05:12 +02:00
import android.app.NotificationManager;
2021-02-16 13:42:49 +01:00
import android.app.PendingIntent;
2021-12-08 23:08:05 +01:00
import android.app.admin.DevicePolicyManager;
2021-02-16 13:42:49 +01:00
import android.bluetooth.BluetoothAdapter;
2021-11-13 01:00:36 +01:00
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
2021-02-16 13:42:49 +01:00
import android.content.ActivityNotFoundException;
2023-11-05 16:20:48 +01:00
import android.content.ComponentName;
2021-02-16 13:42:49 +01:00
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
2021-03-28 20:33:44 +02:00
import android.media.MediaPlayer;
2021-02-16 13:42:49 +01:00
import android.net.ConnectivityManager;
2021-03-29 16:36:21 +02:00
import android.net.Uri;
2021-02-16 13:42:49 +01:00
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
2021-07-04 15:53:24 +02:00
import android.os.VibrationEffect;
import android.os.Vibrator;
2021-02-16 13:42:49 +01:00
import android.provider.MediaStore;
2022-01-10 23:00:36 +01:00
import android.service.notification.StatusBarNotification;
2022-10-03 13:22:25 +02:00
import android.telecom.TelecomManager;
2021-02-16 13:42:49 +01:00
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
2022-01-25 23:10:37 +01:00
import android.view.KeyEvent;
2021-02-16 13:42:49 +01:00
import android.widget.Toast;
2021-09-12 20:05:12 +02:00
import androidx.annotation.RequiresApi;
import com.jens.automation2.actions.wifi_router.MyOnStartTetheringCallback;
import com.jens.automation2.actions.wifi_router.MyOreoWifiManager;
2021-02-16 13:42:49 +01:00
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver;
2022-01-11 16:04:04 +01:00
import com.jens.automation2.receivers.NotificationListener;
2021-02-16 13:42:49 +01:00
2022-01-11 16:04:04 +01:00
import org.apache.commons.lang3.StringUtils;
2021-02-16 13:42:49 +01:00
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient;
2022-06-01 22:36:30 +02:00
import java.io.BufferedReader;
2021-04-09 17:39:59 +02:00
import java.io.File;
2022-06-01 22:36:30 +02:00
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
2021-11-13 01:00:36 +01:00
import java.lang.reflect.Constructor;
2021-02-16 13:42:49 +01:00
import java.lang.reflect.Field;
2021-11-13 01:00:36 +01:00
import java.lang.reflect.InvocationTargetException;
2021-02-16 13:42:49 +01:00
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.KeyStore;
2022-01-09 22:42:47 +01:00
import java.util.Calendar;
2021-02-16 13:42:49 +01:00
import java.util.Collections;
2022-06-03 19:26:34 +02:00
import java.util.Enumeration;
2021-02-16 13:42:49 +01:00
import java.util.List;
2022-10-09 17:14:02 +02:00
import java.util.Map;
2022-11-16 22:42:25 +01:00
import java.util.Random;
2021-11-13 01:00:36 +01:00
import java.util.Set;
2022-06-01 22:36:30 +02:00
import java.util.concurrent.TimeUnit;
2021-02-16 13:42:49 +01:00
import javax.net.ssl.SSLContext;
import eu.chainfire.libsuperuser.Shell;
public class Actions
{
2022-01-26 21:40:29 +01:00
public static AutomationService automationServerRef;
2021-02-16 13:42:49 +01:00
public static Context context;
private static Intent playMusicIntent;
public final static String smsSeparator = "&sms&";
public final static String dummyPackageString = "dummyPkg239asd";
2021-02-16 13:42:49 +01:00
2021-05-07 23:11:43 +02:00
public static final String wireguard_tunnel_up = "com.wireguard.android.action.SET_TUNNEL_UP";
public static final String wireguard_tunnel_down = "com.wireguard.android.action.SET_TUNNEL_DOWN";
public static final String wireguard_tunnel_refresh = "com.wireguard.android.action.REFRESH_TUNNEL_STATES";
2022-01-09 22:42:47 +01:00
public static void createNotification(Action action)
{
String[] elements = action.getParameter2().split(Action.actionParameter2Split);
Miscellaneous.logEvent("w", "createNotification", "Creating notification with title " + elements[0] + " and text " + elements[1], 3);
2023-07-11 00:07:07 +02:00
// Create a new notification ID each time
2022-01-09 22:42:47 +01:00
int notificationId = Math.round(Calendar.getInstance().getTimeInMillis()/1000);
try
{
String title = Miscellaneous.replaceVariablesInText(elements[0], Miscellaneous.getAnyContext());
String text = Miscellaneous.replaceVariablesInText(elements[1], Miscellaneous.getAnyContext());
2022-01-10 19:32:44 +01:00
Miscellaneous.createDismissibleNotification(title, text, notificationId, false, AutomationService.NOTIFICATION_CHANNEL_ID_RULES, null);
2022-01-09 22:42:47 +01:00
}
catch (Exception e)
{
Miscellaneous.logEvent("w", "createNotification", "Error occurred while replacing vars: " + Log.getStackTraceString(e), 3);
}
}
2022-01-10 23:00:36 +01:00
@RequiresApi(api = Build.VERSION_CODES.M)
public static void closeNotification(Action action)
{
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
2023-05-08 23:21:44 +02:00
// for(StatusBarNotification n : nm.getActiveNotifications())
// {
2022-01-11 16:04:04 +01:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
String[] params = action.getParameter2().split(Action.actionParameter2Split);
String myApp = params[0];
String myTitleDir = params[1];
String requiredTitle = params[2];
String myTextDir = params[3];
2022-07-24 14:22:17 +02:00
String requiredText = "";
String method = ActivityManageActionCloseNotification.dismissRegularString;
if(params.length >= 5)
2022-01-11 16:04:04 +01:00
requiredText = params[4];
2022-07-24 14:22:17 +02:00
if(params.length >= 6 && !params[5].equals(ActivityManageActionCloseNotification.dismissRegularString))
method = params[5];
2022-01-11 16:04:04 +01:00
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
{
2022-01-15 13:47:39 +01:00
NotificationListener.SimpleNotification sn = NotificationListener.convertNotificationToSimpleNotification(true, sbn);
2022-01-11 16:04:04 +01:00
2022-01-15 13:47:39 +01:00
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Checking if this notification should be closed in the context of rule " + action.getParentRule().getName() + ": "+ sn.toString(), 5);
2022-01-11 16:04:04 +01:00
2022-01-15 13:47:39 +01:00
if (!myApp.equals(Trigger.anyAppString))
2022-01-11 16:04:04 +01:00
{
2022-01-15 13:47:39 +01:00
if (!myApp.equalsIgnoreCase(sn.getApp()))
2022-01-11 16:04:04 +01:00
{
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification app name does not match rule.", 5);
continue;
}
}
else
{
2022-01-15 13:47:39 +01:00
/*
Notifications from Automation are disregarded to avoid infinite loops.
*/
2022-01-11 16:04:04 +01:00
if(myApp.equals(BuildConfig.APPLICATION_ID))
{
continue;
}
}
/*
If there are multiple notifications ("stacked") title or text might be null:
https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications
*/
// T I T L E
if (!StringUtils.isEmpty(requiredTitle))
{
2022-01-15 13:47:39 +01:00
if (!Miscellaneous.compare(myTitleDir, requiredTitle, sn.getTitle()))
2022-01-11 16:04:04 +01:00
{
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification title does not match rule.", 5);
continue;
}
}
// T E X T
if (!StringUtils.isEmpty(requiredText))
{
2022-01-15 13:47:39 +01:00
if (!Miscellaneous.compare(myTextDir, requiredText, sn.getText()))
2022-01-11 16:04:04 +01:00
{
Miscellaneous.logEvent("i", "NotificationCloseCheck", "Notification text does not match rule.", 5);
continue;
}
}
Miscellaneous.logEvent("i", "NotificationCloseCheck", "All criteria matches. Closing notification: " + sbn.getNotification().toString(), 3);
if(NotificationListener.getInstance() != null)
2022-07-24 14:22:17 +02:00
{
if(method == ActivityManageActionCloseNotification.dismissRegularString)
NotificationListener.getInstance().dismissNotification(sbn);
else
NotificationListener.getInstance().clickNotificationButton(sbn, method);
}
2022-01-11 16:04:04 +01:00
else
Miscellaneous.logEvent("i", "NotificationCloseCheck", "NotificationListener instance is null. Can\'t close notification.", 3);
}
}
2023-05-08 23:21:44 +02:00
// }
2022-01-10 23:00:36 +01:00
}
2022-05-29 02:42:12 +02:00
public static void sendBroadcast(Context context, String action)
{
Miscellaneous.logEvent("i", "sendBroadcast", "Sending broadcast with action " + action, 5);
Intent broadcastIntent = new Intent();
2022-06-06 20:06:11 +02:00
if(action.contains(Action.actionParameter2Split))
{
String[] parts = action.split(Action.actionParameter2Split);
broadcastIntent.setAction(parts[0]);
2022-06-07 17:18:35 +02:00
String[] intentparts = parts[1].split(";");
broadcastIntent = packParametersIntoIntent(broadcastIntent, intentparts, 0);
2022-06-06 20:06:11 +02:00
}
else
broadcastIntent.setAction(action);
2022-05-29 02:42:12 +02:00
context.sendBroadcast(broadcastIntent);
}
2022-10-09 17:14:02 +02:00
public static void setVariable(String parameter2)
{
String[] parts = parameter2.split(Action.actionParameter2Split);
if(AutomationService.isMyServiceRunning(Miscellaneous.getAnyContext()))
{
Map<String,String> map = AutomationService.getInstance().getVariableMap();
if(parts.length > 1)
map.put(parts[0], parts[1]);
else
map.remove(parts[0]);
}
Miscellaneous.logEvent("i", "Variable", "Checking for applicable rules after variable has been set or deleted.", 2);
List<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.checkVariable);
for(int i=0; i<ruleCandidates.size(); i++)
{
if(ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).getsGreenLight(AutomationService.getInstance()))
{
Miscellaneous.logEvent("i", "Variable", "Rule " + ruleCandidates.get(i).getName() + " applies after variable has been set or deleted.", 2);
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
}
}
Miscellaneous.logEvent("i", "Variable", "Done checking for applicable rules after variable has been set or deleted.", 2);
}
public static class WifiStuff
2021-02-16 13:42:49 +01:00
{
2022-07-15 22:37:55 +02:00
public static Boolean setWifi(Context context, Boolean desiredState, String parameter2, boolean toggleActionIfPossible)
2021-10-03 15:09:07 +02:00
{
2022-07-15 22:37:55 +02:00
boolean forceUseRoot = false;
try
{
forceUseRoot = Boolean.parseBoolean(parameter2);
}
catch(Exception e)
{
}
if(context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q || forceUseRoot)
2021-10-03 15:09:07 +02:00
return setWifiWithRoot(context, desiredState, toggleActionIfPossible);
else
return setWifiOldFashioned(context, desiredState, toggleActionIfPossible);
}
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
public static Boolean setWifiWithRoot(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
2021-10-04 20:18:09 +02:00
Miscellaneous.logEvent("i", "Wifi", "Changing wifi to " + String.valueOf(desiredState) + ", but with root permissions.", 4);
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
String command = null;
int state = 0;
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
String desiredStateString;
if(desiredState)
desiredStateString = "enable";
else
desiredStateString = "disable";
try
{
command = "svc wifi " + desiredStateString;
2021-10-04 20:18:09 +02:00
Miscellaneous.logEvent("i", "setWifiWithRoot()", "Running command as root: " + command.toString(), 5);
2021-10-03 15:09:07 +02:00
return executeCommandViaSu(new String[]{command});
}
catch (Exception e)
{
// Oops! Something went wrong, so we throw the exception here.
throw e;
}
2021-02-16 13:42:49 +01:00
}
2021-10-03 15:09:07 +02:00
public static Boolean setWifiOldFashioned(Context context, Boolean desiredState, boolean toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
2021-10-03 15:09:07 +02:00
Miscellaneous.logEvent("i", "Wifi", "Changing wifi to " + String.valueOf(desiredState), 4);
2021-02-16 13:42:49 +01:00
2022-07-15 22:37:55 +02:00
try
{
if (desiredState && Settings.useWifiForPositioning)
WifiBroadcastReceiver.startWifiReceiver(automationServerRef.getLocationProvider());
}
catch(Exception e)
{
Miscellaneous.logEvent("w", "setWifiOldFashioned()", Log.getStackTraceString(e), 4);
}
2021-10-03 15:09:07 +02:00
WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// toggle
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
2021-10-03 15:09:07 +02:00
Toast.makeText(context, context.getResources().getString(R.string.toggling) + " " + context.getResources().getString(R.string.wifi), Toast.LENGTH_LONG).show();
desiredState = !myWifi.isWifiEnabled();
2021-02-16 13:42:49 +01:00
}
2021-10-03 15:09:07 +02:00
// Only perform action if necessary
if ((!myWifi.isWifiEnabled() && desiredState) | (myWifi.isWifiEnabled() && !desiredState))
2021-02-16 13:42:49 +01:00
{
2021-10-03 15:09:07 +02:00
String wifiString = "";
if (desiredState)
{
wifiString = context.getResources().getString(R.string.activating) + " " + context.getResources().getString(R.string.wifi);
}
else
{
wifiString = context.getResources().getString(R.string.deactivating) + " " + context.getResources().getString(R.string.wifi);
}
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
Toast.makeText(context, wifiString, Toast.LENGTH_LONG).show();
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
boolean returnValue = myWifi.setWifiEnabled(desiredState);
if (!returnValue)
Miscellaneous.logEvent("i", "Wifi", "Error changing Wifi to " + String.valueOf(desiredState), 2);
else
Miscellaneous.logEvent("i", "Wifi", "Wifi changed to " + String.valueOf(desiredState), 2);
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
return returnValue;
}
2021-02-16 13:42:49 +01:00
2021-10-03 15:09:07 +02:00
return true;
}
2021-02-16 13:42:49 +01:00
}
public static void setDisplayRotation(Context myContext, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "ScreenRotation", "Changing ScreenRotation to " + String.valueOf(desiredState), 4);
try
{
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.toggling), 2);
boolean currentStatus = android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0;
if (currentStatus)
2021-02-16 13:42:49 +01:00
desiredState = !currentStatus;
}
if (desiredState)
2021-02-16 13:42:49 +01:00
{
if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0)
2021-02-16 13:42:49 +01:00
{
android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 1);
2021-02-16 13:42:49 +01:00
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationEnabled), 2);
}
else
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationAlreadyEnabled), 2);
}
else
{
if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 1)
2021-02-16 13:42:49 +01:00
{
android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0);
2021-02-16 13:42:49 +01:00
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationDisabled), 2);
}
else
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationAlreadyDisabled), 2);
}
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "setScreenRotation", myContext.getResources().getString(R.string.errorChangingScreenRotation) + ": " + Log.getStackTraceString(e), 2);
}
}
private static boolean isWifiApEnabled(Context context)
{
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
2021-02-16 13:42:49 +01:00
boolean currentlyEnabled = false;
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for (Method method : methods)
2021-02-16 13:42:49 +01:00
{
if (method.getName().equals("isWifiApEnabled"))
2021-02-16 13:42:49 +01:00
{
try
{
Object returnObject = method.invoke(wifiManager);
currentlyEnabled = Boolean.valueOf(returnObject.toString());
if (currentlyEnabled)
2021-02-16 13:42:49 +01:00
Miscellaneous.logEvent("i", "isWifiApEnabled", "true", 5);
else
Miscellaneous.logEvent("i", "isWifiApEnabled", "false", 5);
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "isWifiApEnabled", context.getResources().getString(R.string.errorDeterminingWifiApState) + ": " + e.getMessage(), 4);
}
}
}
return currentlyEnabled;
}
2021-02-16 13:42:49 +01:00
public static Boolean setWifiTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "WifiTethering", "Changing WifiTethering to " + String.valueOf(desiredState), 4);
boolean state = Actions.isWifiApEnabled(context);
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "WifiAp", context.getResources().getString(R.string.toggling), 2);
desiredState = !state;
}
if (((state && !desiredState) || (!state && desiredState)))
2021-02-16 13:42:49 +01:00
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
2021-02-16 13:42:49 +01:00
{
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for (Method method : methods)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "WifiAp", "Trying to find appropriate method... " + method.getName(), 5);
if (method.getName().equals("setWifiApEnabled"))
2021-02-16 13:42:49 +01:00
{
try
2021-02-16 13:42:49 +01:00
{
String desiredString = "";
if (desiredState)
desiredString = "activate";
else
desiredString = "deactivate";
if (!toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "WifiAp", "Trying to " + desiredString + " wifi ap...", 2);
if (!method.isAccessible())
method.setAccessible(true);
method.invoke(wifiManager, null, desiredState);
}
else
{
Miscellaneous.logEvent("i", "WifiAp", "Trying to " + context.getResources().getString(R.string.toggle) + " wifi ap...", 2);
if (!method.isAccessible())
method.setAccessible(true);
method.invoke(wifiManager, null, !state);
}
Miscellaneous.logEvent("i", "WifiAp", "Wifi ap " + desiredString + "d.", 2);
2021-02-16 13:42:49 +01:00
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "WifiAp", context.getResources().getString(R.string.errorActivatingWifiAp) + ". " + e.getMessage(), 2);
2021-02-16 13:42:49 +01:00
}
}
}
}
else
{
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback()
{
@Override
public void onTetheringStarted()
2021-02-16 13:42:49 +01:00
{
Log.i("Tether", "Läuft");
2021-02-16 13:42:49 +01:00
}
@Override
public void onTetheringFailed()
{
Log.i("Tether", "Doof");
}
};
MyOreoWifiManager mowm = new MyOreoWifiManager(context);
if (desiredState)
mowm.startTethering(cb);
else
mowm.stopTethering();
2021-02-16 13:42:49 +01:00
}
}
return true;
}
2021-11-13 01:00:36 +01:00
public static class BluetoothTetheringClass
{
static Object instance = null;
static Method setTetheringOn = null;
static Method isTetheringOn = null;
static Object mutex = new Object();
public static Boolean setBluetoothTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "Bluetooth Tethering", "Changing Bluetooth Tethering to " + String.valueOf(desiredState), 4);
2021-11-13 14:48:56 +01:00
// boolean state = isTetheringOn(context);
2021-11-13 01:00:36 +01:00
2021-11-13 14:48:56 +01:00
// if (toggleActionIfPossible)
// {
// Miscellaneous.logEvent("i", "Bluetooth Tethering", context.getResources().getString(R.string.toggling), 2);
// desiredState = !state;
// }
2021-11-13 01:00:36 +01:00
2021-11-13 14:48:56 +01:00
// if (((state && !desiredState) || (!state && desiredState)))
// {
2021-11-15 20:28:38 +01:00
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Method mBTPanConnect = null;
2021-11-13 01:00:36 +01:00
2021-11-15 20:28:38 +01:00
String sClassName = "android.bluetooth.BluetoothPan";
try
{
classBluetoothPan = Class.forName(sClassName);
Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
ctor.setAccessible(true);
// Set Tethering ON
Class[] paramSet = new Class[1];
paramSet[0] = boolean.class;
synchronized (mutex)
2021-11-13 01:00:36 +01:00
{
2021-11-15 20:28:38 +01:00
setTetheringOn = classBluetoothPan.getDeclaredMethod("setBluetoothTethering", paramSet);
isTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", null);
instance = ctor.newInstance(context, new BTPanServiceListener(context));
2021-11-13 01:00:36 +01:00
}
2021-11-15 20:28:38 +01:00
classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
mBTPanConnect = classBluetoothPan.getDeclaredMethod("connect", BluetoothDevice.class);
BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
BTPanCtor.setAccessible(true);
BTSrvInstance = BTPanCtor.newInstance(context, new BTPanServiceListener(context));
2021-11-13 01:00:36 +01:00
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0)
{
// Loop through paired devices
for (BluetoothDevice device : pairedDevices)
{
try
{
mBTPanConnect.invoke(BTSrvInstance, device);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
}
2021-11-15 20:28:38 +01:00
return true;
}
catch (NoSuchMethodException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (ClassNotFoundException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
2021-11-17 21:46:56 +01:00
catch(InvocationTargetException e)
{
/*
Exact error message: "Bluetooth binder is null"
This means this device doesn't have bluetooth.
*/
Miscellaneous.logEvent("e", "Bluetooth Tethering", "Device probably doesn't have bluetooth. " + Log.getStackTraceString(e), 1);
Toast.makeText(context, context.getResources().getString(R.string.deviceDoesNotHaveBluetooth), Toast.LENGTH_SHORT).show();
}
2021-11-15 20:28:38 +01:00
catch (Exception e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
return false;
2021-11-13 01:00:36 +01:00
}
public static class BTPanServiceListener implements BluetoothProfile.ServiceListener
{
private final Context context;
public BTPanServiceListener(final Context context)
{
this.context = context;
}
@Override
public void onServiceConnected(final int profile, final BluetoothProfile proxy)
{
//Some code must be here or the compiler will optimize away this callback.
try
{
synchronized (mutex)
{
setTetheringOn.invoke(instance, true);
if ((Boolean) isTetheringOn.invoke(instance, null))
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is on", 1);
}
else
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", "BT Tethering is off", 1);
}
}
}
catch (InvocationTargetException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
catch (IllegalAccessException e)
{
Miscellaneous.logEvent("e", "Bluetooth Tethering", Log.getStackTraceString(e), 1);
}
}
@Override
public void onServiceDisconnected(final int profile)
{
}
}
}
2021-02-16 13:42:49 +01:00
public static boolean setUsbTethering(Context context2, Boolean desiredState, boolean toggleActionIfPossible)
{
//TODO:toggle not really implemented, yet
Miscellaneous.logEvent("i", "UsbTethering", "Changing UsbTethering to " + String.valueOf(desiredState), 4);
boolean state = false; //Actions.isWifiApEnabled(context);
Object connectivityServiceObject = null;
ConnectivityManager connMgr = null;
try
{
connectivityServiceObject = context.getSystemService(Context.CONNECTIVITY_SERVICE);
connMgr = (ConnectivityManager) connectivityServiceObject;
2021-02-16 13:42:49 +01:00
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "UsbTethering", context2.getResources().getString(R.string.logErrorGettingConnectionManagerService), 2);
return false;
}
try
{
if ((state && !desiredState) || (!state && desiredState))
2021-02-16 13:42:49 +01:00
{
try
{
Method method = connectivityServiceObject.getClass().getDeclaredMethod("getTetheredIfaces");
if (!method.isAccessible())
2021-02-16 13:42:49 +01:00
method.setAccessible(true);
String[] tetheredInterfaces = (String[]) method.invoke(connectivityServiceObject);
if (tetheredInterfaces.length > 0)
2021-02-16 13:42:49 +01:00
state = true;
}
catch (NoSuchMethodException e)
2021-02-16 13:42:49 +01:00
{
// System doesn't have that method, try another way
String ipAddr = getIPAddressUsb(true);
if (ipAddr.length() == 0)
state = false; // tethering not enabled
else
state = true; // tethering enabled
2021-02-16 13:42:49 +01:00
}
}
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.logErrorDeterminingCurrentUsbTetheringState), 3);
}
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.toggling), 3);
desiredState = !state;
}
if ((state && !desiredState) || (!state && desiredState))
2021-02-16 13:42:49 +01:00
{
String desiredString = "";
if (desiredState)
2021-02-16 13:42:49 +01:00
desiredString = "activate";
else
desiredString = "deactivate";
try
{
Method method = null;
for (Method m : connectivityServiceObject.getClass().getDeclaredMethods())
2021-02-16 13:42:49 +01:00
{
if (desiredState && m.getName().equals("tether"))
2021-02-16 13:42:49 +01:00
{
method = m;
break;
}
if (!desiredState && m.getName().equals("untether"))
2021-02-16 13:42:49 +01:00
{
method = m;
break;
}
}
if (method == null)
2021-02-16 13:42:49 +01:00
throw new NoSuchMethodException();
/*
* For some reason this doesn't work, throws NoSuchMethodExpection even if the method is present.
*/
// if(desiredState)
// method = connectivityServiceObject.getClass().getDeclaredMethod("tether");
// else
// method = connectivityServiceObject.getClass().getDeclaredMethod("untether");
// DETECT INTERFACE NAME
Miscellaneous.logEvent("i", "UsbTethering", context2.getResources().getString(R.string.logDetectingTetherableUsbInterface), 4);
String[] available = null;
Method[] wmMethods = connMgr.getClass().getDeclaredMethods();
for (Method getMethod : wmMethods)
{
if (getMethod.getName().equals("getTetherableUsbRegexs"))
2021-02-16 13:42:49 +01:00
{
try
{
if (!method.isAccessible())
2021-02-16 13:42:49 +01:00
method.setAccessible(true);
available = (String[]) getMethod.invoke(connMgr);
2021-02-16 13:42:49 +01:00
// break;
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
2021-02-16 13:42:49 +01:00
// DETECT INTERFACE NAME
if (available.length > 0)
{
for (String interfaceName : available)
{
Miscellaneous.logEvent("i", "UsbTethering", "Detected " + String.valueOf(available.length) + " tetherable usb interfaces.", 5);
2021-02-16 13:42:49 +01:00
Miscellaneous.logEvent("i", "UsbTethering", "Trying to " + desiredString + " UsbTethering on interface " + interfaceName + "...", 5);
if (!method.isAccessible())
2021-02-16 13:42:49 +01:00
method.setAccessible(true);
Integer returnCode = (Integer) method.invoke(connectivityServiceObject, interfaceName);
if (returnCode == 0)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "UsbTethering", "UsbTethering " + desiredString + "d.", 5);
return true;
}
else
{
Miscellaneous.logEvent("w", "UsbTethering", "Failed to " + desiredString + "Usb Tethering. ReturnCode of method " + method.getName() + ": " + String.valueOf(returnCode), 5);
}
}
}
2021-02-16 13:42:49 +01:00
}
catch (NoSuchMethodException e)
{
Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. This kind of error may indicate we are above Android 2.3: " + Log.getStackTraceString(e), 3);
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. " + Log.getStackTraceString(e), 3);
}
}
return false;
}
public static Boolean setBluetooth(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "Bluetooth", "Changing bluetooth to " + String.valueOf(desiredState), 4);
try
{
BluetoothAdapter myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// toggle
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.toggling), 2);
desiredState = !myBluetoothAdapter.isEnabled();
}
// activate
if (!myBluetoothAdapter.isEnabled() && desiredState)
2021-02-16 13:42:49 +01:00
{
Toast.makeText(context, context.getResources().getString(R.string.activating) + " Bluetooth.", Toast.LENGTH_LONG).show();
myBluetoothAdapter.enable();
return true;
}
// deactivate
if (myBluetoothAdapter.isEnabled() && !desiredState)
2021-02-16 13:42:49 +01:00
{
Toast.makeText(context, context.getResources().getString(R.string.deactivating) + " Bluetooth.", Toast.LENGTH_LONG).show();
myBluetoothAdapter.disable();
return true;
}
}
catch (NullPointerException e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.failedToTriggerBluetooth), 2);
Toast.makeText(context, context.getResources().getString(R.string.bluetoothFailed), Toast.LENGTH_LONG).show();
}
return false;
}
2022-06-11 13:59:15 +02:00
public static void setDoNotDisturb(Context context, int desiredDndMode)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
/*
if (!notificationManager.isNotificationPolicyAccessGranted())
--> done externally
*/
Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing DND to " + String.valueOf(desiredDndMode), 4);
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.setInterruptionFilter(desiredDndMode);
}
else
Miscellaneous.logEvent("w", context.getResources().getString(R.string.soundSettings), "Cannot change DND to " + String.valueOf(desiredDndMode) + ". This Android version is too and doesn\'t have that feature, yet.", 4);
}
2021-09-12 20:05:12 +02:00
@RequiresApi(api = Build.VERSION_CODES.M)
public static boolean isDoNotDisturbActive(Context context)
{
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int result = notificationManager.getCurrentInterruptionFilter();
return (notificationManager.getCurrentInterruptionFilter() != NotificationManager.INTERRUPTION_FILTER_ALL);
}
public static void setSound(Context context, int desiredSoundSetting)
{
Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing sound to " + String.valueOf(desiredSoundSetting), 4);
2021-02-16 13:42:49 +01:00
AudioManager myAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
2021-09-12 20:05:12 +02:00
2021-12-27 13:58:43 +01:00
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && desiredSoundSetting == AudioManager.RINGER_MODE_SILENT)
// {
// AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
// am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, 0, AudioManager.FLAG_PLAY_SOUND);
// am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
// }
// else
myAudioManager.setRingerMode(desiredSoundSetting);
2021-02-16 13:42:49 +01:00
}
private static String getIPAddressUsb(final boolean useIPv4)
{
try
{
final List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (final NetworkInterface intf : interfaces)
{
if (intf.getDisplayName().startsWith("usb")) // ro "rndis0"
{
final List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (final InetAddress addr : addrs)
{
final String sAddr = addr.getHostAddress().toUpperCase();
final boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
if (useIPv4)
{
if (isIPv4)
{
return sAddr;
}
}
else
{
if (!isIPv4)
{
final int delim = sAddr.indexOf('%');
return delim < 0 ? sAddr : sAddr.substring(0, delim);
}
}
}
}
}
}
catch (final Exception ex)
{
// for now eat exceptions
}
return "";
2021-02-16 13:42:49 +01:00
}
2021-03-28 20:33:44 +02:00
public static void playSound(boolean alwaysPlay, String soundFileLocation)
{
if (alwaysPlay || ((AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE)).getRingerMode() == AudioManager.RINGER_MODE_NORMAL)
2021-03-28 20:33:44 +02:00
{
MediaPlayer mp = new MediaPlayer();
try
{
2021-04-09 17:39:59 +02:00
File file = new File(soundFileLocation);
if (file.exists())
2021-03-29 16:36:21 +02:00
{
2021-04-09 17:39:59 +02:00
Uri fileUri = Uri.parse(soundFileLocation);
mp.setLooping(false);
mp.setDataSource(Miscellaneous.getAnyContext(), fileUri);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
2021-03-29 16:36:21 +02:00
{
2021-04-09 17:39:59 +02:00
@Override
public void onCompletion(MediaPlayer mp)
{
mp.release();
}
});
mp.prepare();
mp.start();
}
else
{
Miscellaneous.logEvent("w", "Play sound file", "Sound file " + soundFileLocation + " does not exist. Can't play it.", 2);
Toast.makeText(context, String.format(context.getResources().getString(R.string.cantFindSoundFile), soundFileLocation), Toast.LENGTH_SHORT).show();
}
2021-03-28 20:33:44 +02:00
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "Play sound file", "Error playing sound: " + Log.getStackTraceString(e), 2);
}
}
else
Miscellaneous.logEvent("i", "Play sound file", "Not playing sound file because phone is on some kind of mute state.", 2);
}
2021-07-04 15:53:24 +02:00
public static void vibrate(boolean parameter1, String parameter2)
{
String vibrateDurations[] = parameter2.split(Action.vibrateSeparator);
int counter = 1;
for(String vibrate : vibrateDurations)
{
if(counter % 2 != 0)
{
Vibrator vibrator = (Vibrator) Miscellaneous.getAnyContext().getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
vibrator.vibrate(VibrationEffect.createOneShot(Long.parseLong(vibrate), VibrationEffect.DEFAULT_AMPLITUDE));
else
vibrator.vibrate(Long.parseLong(vibrate));
}
else
{
try
{
Thread.sleep(Long.parseLong(vibrate));
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "VibrateSleep", Log.getStackTraceString(e), 5);
}
}
counter++;
}
}
2021-09-26 19:54:17 +02:00
public void useDownloadedWebpage(String result)
2021-02-16 13:42:49 +01:00
{
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
2023-12-21 16:40:11 +01:00
Actions.setVariable("LAST_TRIGGERURL_RESULT" + Action.actionParameter2Split + result);
2021-02-16 13:42:49 +01:00
}
public static HttpClient getInsecureSslClient(HttpClient client)
{
try
{
SSLContext ctx = SSLContext.getInstance("TLS");
SSLSocketFactory ssf = null;
2021-02-16 13:42:49 +01:00
// MySSLSocketFactoryInsecure ssfI = null;
// if(!Settings.httpAcceptAllCertificates)
// {
// ssf = new MySSLSocketFactory(ctx);
// ssf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
//
// char[] keystorePass="insecure".toCharArray(); //passphrase for keystore
// KeyStore keyStore=KeyStore.getInstance("BKS");
//
//// String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
// tmf.init(keyStore);
//
// Miscellaneous.logEvent("i", "SSL Keystore", context.getCacheDir().toString(), 4);
// InputStream is = context.getResources().openRawResource(R.raw.keystore);
// keyStore.load(is,keystorePass);
//
// ctx.init(null, tmf.getTrustManagers(), null);
// }
// else
// {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
ssf = new MySSLSocketFactoryInsecure(trustStore);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ctx.init(null, null, null);
2021-02-16 13:42:49 +01:00
// }
ClientConnectionManager ccm = client.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
2021-02-16 13:42:49 +01:00
// if(!Settings.httpAcceptAllCertificates)
sr.register(new Scheme("https", ssf, 443));
2021-02-16 13:42:49 +01:00
// else
// sr.register(new Scheme("https", ssfI, 443));
return new DefaultHttpClient(ccm, client.getParams());
}
catch (Exception ex)
{
ex.printStackTrace();
return null;
}
2021-02-16 13:42:49 +01:00
}
2021-05-10 19:56:54 +02:00
public static void startOtherActivity(boolean startByAction, String param)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "StartOtherActivity", "Starting other Activity...", 4);
String params[];
if(param.contains(Action.actionParameter2Split))
params = param.split(Action.actionParameter2Split);
else
params = param.split(";");
2021-04-09 17:39:59 +02:00
2021-02-16 13:42:49 +01:00
try
{
2023-11-08 00:15:39 +01:00
Intent externalApplicationIntent;
2021-04-09 17:39:59 +02:00
if (!startByAction)
2021-04-13 20:00:36 +02:00
{
2021-05-08 15:14:31 +02:00
// selected by activity
String packageName, className;
packageName = params[0];
className = params[1];
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by activity: " + packageName + " " + className, 3);
2023-11-08 00:15:39 +01:00
externalApplicationIntent = new Intent(Intent.ACTION_MAIN);
externalApplicationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
2021-05-08 15:14:31 +02:00
2023-11-08 00:15:39 +01:00
if(packageName.equals("dummyPkg"))
externalApplicationIntent.setAction(className);
2021-05-08 15:14:31 +02:00
2023-11-19 23:44:10 +01:00
externalApplicationIntent.setClassName(packageName, className);
2023-11-08 00:15:39 +01:00
if (!Miscellaneous.doesActivityExist(externalApplicationIntent, Miscellaneous.getAnyContext()))
2021-05-08 15:14:31 +02:00
Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2);
}
else
{
// selected by action
Miscellaneous.logEvent("i", "StartOtherApp", "Starting app by action: " + param, 3);
2021-05-09 14:42:24 +02:00
2023-11-08 00:15:39 +01:00
externalApplicationIntent = new Intent();
2021-05-09 14:42:24 +02:00
if (!params[0].equals(dummyPackageString))
2023-11-08 00:15:39 +01:00
externalApplicationIntent.setPackage(params[0]);
2023-11-08 00:15:39 +01:00
externalApplicationIntent.setAction(params[1]);
2023-11-05 16:20:48 +01:00
2023-11-08 00:15:39 +01:00
if (params[2].equals(ActivityManageActionStartActivity.startByServiceString) || params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString))
2023-11-05 16:20:48 +01:00
{
2023-11-08 00:15:39 +01:00
externalApplicationIntent.setComponent(new ComponentName(params[0], params[2]));
2023-11-05 16:20:48 +01:00
}
2021-05-08 15:14:31 +02:00
}
2023-11-08 00:15:39 +01:00
externalApplicationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2021-05-08 15:14:31 +02:00
// Pack intents
2023-11-08 00:15:39 +01:00
externalApplicationIntent = packParametersIntoIntent(externalApplicationIntent, params, 3);
2022-06-07 17:18:35 +02:00
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
2023-11-08 00:15:39 +01:00
automationServerRef.startActivity(externalApplicationIntent);
else if (params[2].equals(ActivityManageActionStartActivity.startByServiceString))
automationServerRef.startService(externalApplicationIntent);
2023-11-24 23:57:26 +01:00
else if (params[2].equals(ActivityManageActionStartActivity.startByForegroundServiceString) && Build.VERSION.SDK_INT >= 26)
2023-11-08 00:15:39 +01:00
automationServerRef.startForegroundService(externalApplicationIntent);
2022-06-07 17:18:35 +02:00
else
2023-11-08 00:15:39 +01:00
automationServerRef.sendBroadcast(externalApplicationIntent);
2022-06-07 17:18:35 +02:00
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "StartOtherApp", automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
Toast.makeText(automationServerRef, automationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public static Intent packParametersIntoIntent(Intent intent, String[] params, int startIndex)
{
for (int i = startIndex; i < params.length; i++)
{
String[] singleParam = params[i].split(Action.intentPairSeparator);
2021-05-08 15:14:31 +02:00
2021-02-16 13:42:49 +01:00
/*Class c = Class.forName(singleParam[0]);
for(Method m : c.getMethods())
{
if(m.getName().startsWith("parse"))
{
Object o = m.invoke(null, singleParam[0]);
externalActivityIntent.putExtra(singleParam[1], o);
}
}*/
2022-06-07 17:18:35 +02:00
if (singleParam[0].equals("boolean"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Boolean.parseBoolean(singleParam[2]));
}
else if (singleParam[0].equals("byte"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Byte.parseByte(singleParam[2]));
}
else if (singleParam[0].equals("char"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], singleParam[2].charAt(0));
}
else if (singleParam[0].equals("CharSequence"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], (CharSequence) singleParam[2]);
}
else if (singleParam[0].equals("double"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Double.parseDouble(singleParam[2]));
}
else if (singleParam[0].equals("float"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Float.parseFloat(singleParam[2]));
}
else if (singleParam[0].equals("int"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Integer.parseInt(singleParam[2]));
}
else if (singleParam[0].equals("long"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Long.parseLong(singleParam[2]));
}
else if (singleParam[0].equals("short"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Short.parseShort(singleParam[2]));
}
else if (singleParam[0].equals("Uri"))
{
2023-05-05 23:26:32 +02:00
try
2021-05-11 20:00:50 +02:00
{
2023-05-05 23:26:32 +02:00
if (singleParam[1].equalsIgnoreCase("IntentData"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
intent.setData(Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
}
else
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
intent.putExtra(singleParam[1], Uri.parse(Miscellaneous.replaceVariablesInText(singleParam[2], context)));
}
2021-05-11 20:00:50 +02:00
}
2023-05-05 23:26:32 +02:00
catch (Exception e)
2021-05-08 15:14:31 +02:00
{
2023-05-05 23:26:32 +02:00
throw new RuntimeException(e);
2021-05-08 15:14:31 +02:00
}
2021-04-13 20:00:36 +02:00
}
2022-06-07 17:18:35 +02:00
else if (singleParam[0].equals("String"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with name " + singleParam[1] + " and value " + singleParam[2], 3);
2023-05-05 23:26:32 +02:00
try
{
intent.putExtra(singleParam[1], Miscellaneous.replaceVariablesInText(singleParam[2], context));
}
catch (Exception e)
{
intent.putExtra(singleParam[1], singleParam[2]);
}
2022-06-07 17:18:35 +02:00
}
else
2022-06-07 17:18:35 +02:00
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
2021-02-16 13:42:49 +01:00
}
2022-06-07 17:18:35 +02:00
return intent;
2021-02-16 13:42:49 +01:00
}
public static void waitBeforeNextAction(Long waitTime)
{
Miscellaneous.logEvent("i", "waitBeforeNextAction", "waitBeforeNextAction for " + String.valueOf(waitTime) + " milliseconds.", 4);
try
{
Thread.sleep(waitTime);
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("e", "waitBeforeNextAction", Log.getStackTraceString(e), 2);
}
}
public static void wakeupDevice(Long awakeTime)
{
String duration = "default";
if (awakeTime > 0)
2021-02-16 13:42:49 +01:00
duration = String.valueOf(awakeTime) + " milliseconds";
Miscellaneous.logEvent("i", "wakeupDevice", "wakeupDevice for " + String.valueOf(duration) + ".", 4);
if (awakeTime > 0)
{
/*
* This action needs to be performed in a separate thread. If it ran in the same one
* the screen would turn on, the specified amount of time would pass and the screen
* would turn off again before any other action in the rule would be ran.
*/
Thread t = new Thread(new WakeUpDeviceClass(awakeTime));
t.start();
}
2021-02-16 13:42:49 +01:00
}
public static void sendTextMessage(Context context, String[] parametersArray)
{
2022-11-13 17:49:02 +01:00
String phoneNumber, message, messageType = ActivityManageActionSendTextMessage.messageTypeSms, filePath = null;
2021-02-16 13:42:49 +01:00
phoneNumber = parametersArray[0];
message = parametersArray[1];
2022-11-10 23:06:07 +01:00
if(parametersArray.length > 2)
{
messageType = parametersArray[2];
if(parametersArray.length > 3)
filePath = parametersArray[3];
}
2021-02-16 13:42:49 +01:00
try
{
String textToSend = Miscellaneous.replaceVariablesInText(message, context);
2022-11-10 23:06:07 +01:00
if(messageType.equals("sms"))
sendSmsMessage(phoneNumber, textToSend);
else
sendMmsMessage(phoneNumber, textToSend, filePath);
}
catch (Exception e)
{
Miscellaneous.logEvent("e", Miscellaneous.getAnyContext().getString(R.string.sendTextMessage), "Error in sendTextMessage: " + Log.getStackTraceString(e), 3);
}
}
2021-02-16 13:42:49 +01:00
2022-11-10 23:06:07 +01:00
private static void sendSmsMessage(String phoneNumber, String textToSend)
{
try
{
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, Actions.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, textToSend, pi, null);
2021-02-16 13:42:49 +01:00
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", Miscellaneous.getAnyContext().getString(R.string.sendTextMessage), "Error in sendTextMessage: " + Log.getStackTraceString(e), 3);
2022-11-10 23:06:07 +01:00
}
}
2022-11-13 17:49:02 +01:00
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
2022-11-10 23:06:07 +01:00
private static void sendMmsMessage(String phoneNumber, String textToSend, String fileToBeAttached)
{
try
{
2022-11-13 17:49:02 +01:00
Miscellaneous.logEvent("i", "sendMmsMessage()", "Sending MMS message...", 2);
2022-11-16 22:42:25 +01:00
// Uri contentUri = Uri.fromFile(new File(fileToBeAttached));
String str2 = "send." + String.valueOf(Math.abs(new Random().nextLong())) + ".dat";
Uri contentUri = new Uri.Builder().authority(context.getPackageName() + ".MmsFileProvider").path(str2).scheme("content").build();
2022-12-24 02:27:35 +01:00
// Bundle a3 = C3326a.m16196a(new C8792q("enableGroupMms", true), new C8792q("maxMessageSize", Integer.valueOf(C3664a.m17428d())));
2022-11-16 22:42:25 +01:00
2022-11-13 17:49:02 +01:00
SmsManager.getDefault().sendMultimediaMessage(context, contentUri, phoneNumber, null, null);
2022-11-10 23:06:07 +01:00
}
catch (Exception e)
{
2022-11-13 17:49:02 +01:00
Miscellaneous.logEvent("e", "sendMmsMessage()", "Error in sendMmsMessage(): " + Log.getStackTraceString(e), 3);
2021-02-16 13:42:49 +01:00
}
}
2021-02-16 13:42:49 +01:00
private static class WakeUpDeviceClass implements Runnable
2021-02-16 13:42:49 +01:00
{
private long awakeTime;
public WakeUpDeviceClass(long awakeTime)
{
super();
this.awakeTime = awakeTime;
}
@Override
public void run()
{
try
2021-02-16 13:42:49 +01:00
{
2021-12-08 17:22:18 +01:00
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
2021-12-08 19:57:27 +01:00
WakeLock wakeLock = pm.newWakeLock((PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock");
2021-12-08 17:22:18 +01:00
wakeLock.acquire();
try
{
Thread.sleep(awakeTime);
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4);
}
wakeLock.release();
2021-02-16 13:42:49 +01:00
}
2021-12-08 17:22:18 +01:00
catch(Exception e)
2021-02-16 13:42:49 +01:00
{
2021-12-08 17:22:18 +01:00
Miscellaneous.logEvent("e", "Wakeup device action", "Error while waking up device: " + Log.getStackTraceString(e), 1);
2021-02-16 13:42:49 +01:00
}
}
}
2021-12-12 20:03:53 +01:00
/*public static void turnOnScreen()
2021-12-08 17:22:18 +01:00
{
// turn on screen
2021-12-08 19:57:27 +01:00
Miscellaneous.logEvent("i", "Actions", "Turning screen on.", 3);
2021-12-08 17:22:18 +01:00
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
2021-12-09 18:03:00 +01:00
WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
2021-12-08 17:22:18 +01:00
wakeLock.acquire();
2021-12-12 20:03:53 +01:00
}*/
2021-12-08 17:22:18 +01:00
@TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
2021-12-08 19:57:27 +01:00
public static void turnOffScreen()
{
Miscellaneous.logEvent("i", "Actions", "Turning screen off.", 3);
2021-12-08 23:08:05 +01:00
2021-12-18 13:29:47 +01:00
2021-12-08 23:08:05 +01:00
/*params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
2021-12-12 20:03:53 +01:00
getWindow().setAttributes(params);*/
2021-12-08 23:08:05 +01:00
2021-12-19 14:47:46 +01:00
// PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
2021-12-12 20:03:53 +01:00
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
2021-12-19 14:47:46 +01:00
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , AutomationService.NOTIFICATION_CHANNEL_ID + ":turnOffScreen");
// wakeLock.acquire();
2021-12-12 20:03:53 +01:00
// WakeLock wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
2021-12-08 23:08:05 +01:00
// WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK , "tag");
2021-12-12 20:03:53 +01:00
// wakeLock.acquire();
2021-12-19 14:47:46 +01:00
// wakeLock.release();
lockScreen();
2021-12-08 17:22:18 +01:00
}
2021-12-19 14:47:46 +01:00
public static void lockScreen()
2021-12-12 20:03:53 +01:00
{
Miscellaneous.logEvent("i", "Actions", "Locking screen.", 3);
// Works, but requires Manifest.permission.BIND_DEVICE_ADMIN
// https://stackoverflow.com/questions/23898406/java-lang-securityexception-no-active-admin-owned-by-uid-10047-for-policy-4-on
2021-12-19 14:47:46 +01:00
DevicePolicyManager deviceManager = (DevicePolicyManager)Miscellaneous.getAnyContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
deviceManager.lockNow();
}
2021-12-12 20:03:53 +01:00
2021-12-08 23:08:05 +01:00
// using root
/*private void turnOffScreen()
{
try
{
Class c = Class.forName("android.os.PowerManager");
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
2021-12-11 02:04:45 +01:00
for(Method m : c.getDeclaredMethods())
{
if(m.getName().equals("goToSleep"))
{
2021-12-08 23:08:05 +01:00
m.setAccessible(true);
2021-12-11 02:04:45 +01:00
if(m.getParameterTypes().length == 1)
{
2021-12-08 23:08:05 +01:00
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
}
}
}
}
catch (Exception e)
{
}
}*/
2021-02-16 13:42:49 +01:00
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("NewApi")
public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible)
{
/*
Beginning from SDK Version 17 this may not work anymore.
Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, value is unchanged.
https://stackoverflow.com/questions/22349928/permission-denial-not-allowed-to-send-broadcast-android-intent-action-airplane
https://stackoverflow.com/questions/7066427/turn-off-airplane-mode-in-android
*/
2021-02-16 13:42:49 +01:00
boolean returnValue = false;
try
{
2022-01-26 21:40:29 +01:00
boolean isEnabled = ConnectivityReceiver.isAirplaneMode(automationServerRef);
2021-02-16 13:42:49 +01:00
if (isEnabled)
2021-02-16 13:42:49 +01:00
Miscellaneous.logEvent("i", "Airplane mode", "Current status is enabled.", 4);
else
Miscellaneous.logEvent("i", "Airplane mode", "Current status is disabled.", 4);
if (toggleActionIfPossible)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "Airplane mode", context.getResources().getString(R.string.toggling), 4);
desiredState = !isEnabled;
}
if (isEnabled != desiredState)
2021-02-16 13:42:49 +01:00
{
int desiredValueInt = 0;
if (desiredState)
2021-02-16 13:42:49 +01:00
desiredValueInt = 1;
if (Build.VERSION.SDK_INT < 17 || ActivityPermissions.havePermission(Manifest.permission.WRITE_SECURE_SETTINGS, context))
2021-02-16 13:42:49 +01:00
{
//returnValue = android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, desiredValueInt);
returnValue = android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, desiredValueInt);
// Intent airplaneIntent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
// airplaneIntent.putExtra("state", desiredState);
// context.sendBroadcast(airplaneIntent);
2021-02-16 13:42:49 +01:00
}
else
{
if (desiredState)
2021-02-16 13:42:49 +01:00
{
String[] commands = new String[]
{
"settings put global airplane_mode_on 1",
"am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true"
};
2021-02-16 13:42:49 +01:00
returnValue = executeCommandViaSu(commands);
}
else
{
String[] commands = new String[]
{
"settings put global airplane_mode_on 0",
"am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false"
};
2021-02-16 13:42:49 +01:00
returnValue = executeCommandViaSu(commands);
}
// returnValue = android.provider.Settings.Global.putString(context.getContentResolver(), "airplane_mode_on", String.valueOf(desiredValueInt));
}
// Post an intent to reload
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", !isEnabled);
context.sendBroadcast(intent);
}
else
Miscellaneous.logEvent("i", "Airplane mode", "Airplane mode is already in status " + String.valueOf(desiredState) + ". Nothing to do.", 3);
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "Airplane mode", Log.getStackTraceString(e), 2);
}
return returnValue;
}
/**
* Toggles the device between the different types of networks.
* Might not work. It seems only system apps are allowed to do this.
*/
public static boolean setNetworkType(int desiredType)
{
Miscellaneous.logEvent("i", "setNetworkType", "Asked to set network type to: " + String.valueOf(desiredType), 3);
if (desiredType > 0)
2021-02-16 13:42:49 +01:00
{
try
{
ConnectivityManager connManager = (ConnectivityManager) Miscellaneous.getAnyContext().getSystemService(context.CONNECTIVITY_SERVICE);
// TelephonyManager.NETWORK_TYPE_EDGE
if (connManager.getNetworkPreference() == desiredType)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("i", "setNetworkType", "Desired networkType already set. Not doing anything.", 4);
}
else
{
Miscellaneous.logEvent("i", "setNetworkType", "Setting network type to: " + String.valueOf(desiredType), 3);
connManager.setNetworkPreference(desiredType);
}
return true;
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "setNetworkType", "Error changing network type: " + Log.getStackTraceString(e), 2);
return false;
}
}
else
{
Miscellaneous.logEvent("w", "setNetworkType", "Invalid type of network specified: " + String.valueOf(desiredType), 4);
return false;
}
}
public static void speakText(String parameter2)
{
try
{
String textToSpeak = Miscellaneous.replaceVariablesInText(parameter2, context);
2022-01-26 21:40:29 +01:00
automationServerRef.speak(textToSpeak, true);
2021-02-16 13:42:49 +01:00
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "Speak text", "Error in speak text: " + Log.getStackTraceString(e), 3);
}
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public static boolean playMusic(boolean desiredState, boolean toggleActionIfPossible)
{
try
{
//TODO:toggle
// if(desiredState)
// {
Miscellaneous.logEvent("e", "Play music", "Starting music player...", 3);
2021-02-16 13:42:49 +01:00
String deviceName = Build.MODEL;
/*
* Fix for Samsung devices: http://stackoverflow.com/questions/12532207/open-music-player-on-galaxy-s3
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 | deviceName.contains("SM-"))
playMusicIntent = new Intent(Intent.CATEGORY_APP_MUSIC);
else
playMusicIntent = new Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER);
playMusicIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(playMusicIntent);
return true;
2021-02-16 13:42:49 +01:00
}
catch (ActivityNotFoundException e)
2021-02-16 13:42:49 +01:00
{
Toast.makeText(context, "Error: No music player found.", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): No music player found. " + Log.getStackTraceString(e), 3);
return false;
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Toast.makeText(context, "Error starting music player.", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): " + Log.getStackTraceString(e), 3);
return false;
}
}
2022-01-26 21:40:29 +01:00
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
2022-01-24 20:13:35 +01:00
public static boolean controlMediaPlayback(Context context, int command)
{
2022-01-26 21:40:29 +01:00
int keyCode = -1;
switch(command)
{
case 0:
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
break;
case 1:
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY;
break;
case 2:
keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE;
break;
case 3:
2022-01-26 22:53:02 +01:00
keyCode = KeyEvent.KEYCODE_MEDIA_STOP;
2022-01-26 21:40:29 +01:00
break;
case 4:
2022-01-26 22:53:02 +01:00
keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
break;
case 5:
2022-01-26 21:40:29 +01:00
keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
break;
}
2022-01-27 11:34:04 +01:00
return controlMediaByDispatch(keyCode);
2022-01-26 22:53:02 +01:00
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
static boolean controlMediaByDispatch(int keyCode)
{
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
mAudioManager.dispatchMediaKeyEvent(event);
2022-01-25 18:08:46 +01:00
2022-01-26 21:40:29 +01:00
return true;
2022-01-26 22:53:02 +01:00
}
2021-02-16 13:42:49 +01:00
private String getTransactionCode()
{
try
{
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
getITelephonyMethod.setAccessible(true);
Object ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
Class ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
Class stub = ITelephonyClass.getDeclaringClass();
Field field = stub.getDeclaredField("TRANSACTION_setDataEnabled");
field.setAccessible(true);
return String.valueOf(field.getInt(null));
}
catch (Exception e)
{
if (Build.VERSION.SDK_INT >= 22)
return "86";
else if (Build.VERSION.SDK_INT == 21)
return "83";
}
return "";
}
2021-02-16 13:42:49 +01:00
private static String getTransactionCodeFromApi20(Context context) throws Exception
{
try
{
final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName());
final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony");
mTelephonyMethod.setAccessible(true);
final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager);
final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName());
final Class<?> mClass = mTelephonyStubClass.getDeclaringClass();
final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled");
field.setAccessible(true);
return String.valueOf(field.getInt(null));
}
catch (Exception e)
{
// The "TRANSACTION_setDataEnabled" field is not available,
// or named differently in the current API level, so we throw
// an exception and inform users that the method is not available.
throw e;
}
2021-02-16 13:42:49 +01:00
}
public static class MobileDataStuff
{
2021-05-16 19:51:22 +02:00
// https://stackoverflow.com/questions/31120082/latest-update-on-enabling-and-disabling-mobile-data-programmatically
2021-02-16 13:42:49 +01:00
/**
* Turns data on and off.
* Requires root permissions from lollipop on.
*
* @param toggleActionIfPossible
*/
public static boolean setDataConnection(boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "setData", "Asked to turn data to: " + String.valueOf(desiredState), 3);
2021-02-16 13:42:49 +01:00
try
{
ConnectivityManager connManager = (ConnectivityManager) Miscellaneous.getAnyContext().getSystemService(Miscellaneous.getAnyContext().CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(connManager.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(connManager);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
2021-02-16 13:42:49 +01:00
Boolean isEnabled = isMobileDataEnabled();
2021-05-16 19:51:22 +02:00
if (toggleActionIfPossible)
{
context.getResources().getString(R.string.toggling);
desiredState = !isEnabled;
}
2021-05-16 19:51:22 +02:00
2021-10-03 15:09:07 +02:00
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH)
{
for (Method m : iConnectivityManagerClass.getDeclaredMethods())
2021-05-16 19:51:22 +02:00
{
Miscellaneous.logEvent("i", "method", m.getName(), 5);
2021-05-16 19:51:22 +02:00
}
2021-02-16 13:42:49 +01:00
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, desiredState);
2021-02-16 13:42:49 +01:00
}
else
2021-02-16 13:42:49 +01:00
{
return setDataConnectionWithRoot(desiredState);
2021-02-16 13:42:49 +01:00
}
return true;
}
catch (Exception e)
{
Miscellaneous.logEvent("e", "setData", "Error changing network type: " + Log.getStackTraceString(e), 2);
return false;
2021-02-16 13:42:49 +01:00
}
}
2021-02-16 13:42:49 +01:00
2021-10-03 21:38:33 +02:00
protected static boolean setDataConnectionWithRoot(boolean desiredState)
{
try
{
2021-10-03 15:09:07 +02:00
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1)
2021-02-16 13:42:49 +01:00
{
2022-01-26 21:40:29 +01:00
if(MobileDataStuff.setMobileNetworkFromAndroid9(desiredState, automationServerRef))
2021-10-03 15:09:07 +02:00
{
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
return true;
}
else
{
Miscellaneous.logEvent("e", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootFail), 2);
return false;
}
}
else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
{
2022-01-26 21:40:29 +01:00
if (MobileDataStuff.setMobileNetworkTillAndroid5(desiredState, automationServerRef))
2021-10-03 15:09:07 +02:00
{
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
return true;
}
else
{
Miscellaneous.logEvent("e", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootFail), 2);
return false;
}
2021-02-16 13:42:49 +01:00
}
else
{
2022-01-26 21:40:29 +01:00
if (MobileDataStuff.setMobileNetworkAndroid6Till8(desiredState, automationServerRef))
2021-10-03 15:09:07 +02:00
{
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
return true;
}
else
{
Miscellaneous.logEvent("e", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootFail), 2);
return false;
}
2021-02-16 13:42:49 +01:00
}
}
catch (Exception e)
{
String rootString;
if (Miscellaneous.isPhoneRooted())
rootString = Miscellaneous.getAnyContext().getResources().getString(R.string.phoneIsRooted);
else
rootString = Miscellaneous.getAnyContext().getResources().getString(R.string.phoneIsNotRooted);
Miscellaneous.logEvent("e", "setDataWithRoot()", "Error setting data setting with root. " + rootString + ": " + Log.getStackTraceString(e), 3);
return false;
}
}
2021-02-16 13:42:49 +01:00
@SuppressLint("NewApi")
2021-10-03 21:38:33 +02:00
public static boolean setMobileNetworkAndroid6Till8(boolean desiredState, Context context) throws Exception
2021-02-16 13:42:49 +01:00
{
String command = null;
try
{
2021-10-03 21:38:33 +02:00
int desiredStateString;
if(desiredState)
desiredStateString = 1;
else
desiredStateString = 0;
2021-10-03 15:09:07 +02:00
// Get the current state of the mobile network.
2021-10-03 21:38:33 +02:00
// boolean state = isMobileDataEnabled() ? 0 : 1;
2021-10-03 15:09:07 +02:00
// Get the value of the "TRANSACTION_setDataEnabled" field.
String transactionCode = getTransactionCode(context);
// Android 5.1+ (API 22) and later.
SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
// Loop through the subscription list i.e. SIM list.
for (int i = 0; i < mSubscriptionManager.getActiveSubscriptionInfoCountMax(); i++)
{
2021-10-03 15:09:07 +02:00
if (transactionCode != null && transactionCode.length() > 0)
{
2021-09-25 02:03:44 +02:00
// Get the active subscription ID for a given SIM card.
int subscriptionId = mSubscriptionManager.getActiveSubscriptionInfoList().get(i).getSubscriptionId();
// Execute the command via `su` to turn off
// mobile network for a subscription service.
2021-10-03 21:38:33 +02:00
command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + desiredStateString;
2021-10-03 15:09:07 +02:00
Miscellaneous.logEvent("i", "setMobileNetworkAndroid6Till8()", "Running command: " + command.toString(), 5);
2021-09-25 02:03:44 +02:00
return executeCommandViaSu(new String[]{command});
}
}
2021-10-03 15:09:07 +02:00
}
catch (Exception e)
{
// Oops! Something went wrong, so we throw the exception here.
throw e;
}
return false;
}
@SuppressLint("NewApi")
2021-10-03 21:38:33 +02:00
public static boolean setMobileNetworkTillAndroid5(boolean desiredState, Context context) throws Exception
2021-10-03 15:09:07 +02:00
{
String command = null;
try
{
2021-10-03 21:38:33 +02:00
int desiredStateString;
if(desiredState)
desiredStateString = 1;
else
desiredStateString = 0;
2021-10-03 15:09:07 +02:00
// Get the current state of the mobile network.
2021-10-03 21:38:33 +02:00
// int currentState = isMobileDataEnabled() ? 0 : 1;
2021-10-03 15:09:07 +02:00
// Get the value of the "TRANSACTION_setDataEnabled" field.
String transactionCode = getTransactionCode(context);
// Android 5.0 (API 21) only.
if (transactionCode != null && transactionCode.length() > 0)
{
2021-10-03 15:09:07 +02:00
// Execute the command via `su` to turn off mobile network.
2021-10-03 21:38:33 +02:00
command = "service call phone " + transactionCode + " i32 " + desiredStateString;
2021-10-03 15:09:07 +02:00
Miscellaneous.logEvent("i", "setMobileNetworkTillAndroid5()", "Running command: " + command.toString(), 5);
return executeCommandViaSu(new String[]{command});
}
}
catch (Exception e)
{
// Oops! Something went wrong, so we throw the exception here.
throw e;
}
return false;
2021-02-16 13:42:49 +01:00
}
2021-10-03 15:09:07 +02:00
@SuppressLint("NewApi")
2021-10-03 21:38:33 +02:00
public static boolean setMobileNetworkFromAndroid9(boolean desiredState, Context context) throws Exception
2021-10-03 15:09:07 +02:00
{
String command = null;
String desiredStateString;
2021-10-03 21:38:33 +02:00
if(desiredState)
2021-10-03 21:20:47 +02:00
desiredStateString = "enable";
2021-10-03 21:38:33 +02:00
else
desiredStateString = "disable";
2021-10-03 15:09:07 +02:00
try
{
/*
Android 8.1 is the last version on which the transaction code can be determined
with the below method. From 9.0 on the field TRANSACTION_setDataEnabled does not
exist anymore. Usually it was 83 and we'll just try this number hardcoded.
Alternatively the bottom of this might be an approach:
https://stackoverflow.com/questions/26539445/the-setmobiledataenabled-method-is-no-longer-callable-as-of-android-l-and-later
*/
// Execute the command via `su` to turn off
// mobile network for a subscription service.
command = "svc data " + desiredStateString;
Miscellaneous.logEvent("i", "setMobileNetworkFromAndroid9()", "Running command: " + command.toString(), 5);
return executeCommandViaSu(new String[]{command});
}
catch (Exception e)
{
// Oops! Something went wrong, so we throw the exception here.
throw e;
}
}
2021-02-16 13:42:49 +01:00
@SuppressLint("NewApi")
public static boolean isMobileDataEnabled()
{
boolean isEnabled = false;
if (Build.VERSION.SDK_INT <= 20)
{
2021-02-16 13:42:49 +01:00
try
{
ConnectivityManager connManager = (ConnectivityManager) Miscellaneous.getAnyContext().getSystemService(Miscellaneous.getAnyContext().CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(connManager.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(connManager);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
Method getMobileDataEnabledMethod = null;
for (Method m : iConnectivityManagerClass.getDeclaredMethods())
{
Miscellaneous.logEvent("i", "Methods", m.getName(), 5);
if (m.getName().equals("getMobileDataEnabled"))
{
getMobileDataEnabledMethod = m;
break;
}
}
// final Method getMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("getMobileDataEnabled", null);
getMobileDataEnabledMethod.setAccessible(true);
2021-02-16 13:42:49 +01:00
isEnabled = (Boolean) getMobileDataEnabledMethod.invoke(iConnectivityManager, (Object[]) null);
}
catch (Exception e)
2021-02-16 13:42:49 +01:00
{
Miscellaneous.logEvent("e", "isMobileDataEnabled()", "Error checking if mobile data is enabled: " + Log.getStackTraceString(e), 3);
2021-02-16 13:42:49 +01:00
}
}
else
{
isEnabled = android.provider.Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1;
}
2021-02-16 13:42:49 +01:00
return isEnabled;
}
private static String getTransactionCode(Context context) throws Exception
{
try
{
final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName());
final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony");
mTelephonyMethod.setAccessible(true);
final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager);
final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName());
final Class<?> mClass = mTelephonyStubClass.getDeclaringClass();
final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled");
field.setAccessible(true);
return String.valueOf(field.getInt(null));
}
catch (Exception e)
{
// The "TRANSACTION_setDataEnabled" field is not available,
// or named differently in the current API level, so we throw
// an exception and inform users that the method is not available.
throw e;
}
2021-02-16 13:42:49 +01:00
}
}
2021-02-16 13:42:49 +01:00
protected static boolean executeCommandViaSu(String[] commands)
{
2022-07-14 22:55:54 +02:00
boolean suAvailable = false;
String suVersion = null;
String suVersionInternal = null;
// List<String> suResult = null;
int suResult;
boolean success = false;
try
{
suAvailable = Shell.SU.available();
if (suAvailable)
{
suVersion = Shell.SU.version(false);
suVersionInternal = Shell.SU.version(true);
2022-07-14 22:55:54 +02:00
Miscellaneous.logEvent("i", "executeCommandViaSu()", "suVersion: " + suVersion + ", suVersionInternal: " + suVersionInternal, 5);
// suResult = Shell.SU.run(commands);
suResult = Shell.Pool.SU.run(commands);
// if (suResult != null)
// success = true;
Miscellaneous.logEvent("i", "executeCommandViaSu()", "RC=" + String.valueOf(suResult), 3);
if(suResult == 0)
success = true;
}
2022-07-14 22:55:54 +02:00
else
Miscellaneous.logEvent("w", "executeCommandViaSu()", "su not available.", 4);
}
catch (Exception e)
{
success = false;
}
2022-07-14 22:55:54 +02:00
Miscellaneous.logEvent("i", "executeCommandViaSu()", "Returning " + String.valueOf(success), 4);
return success;
2021-02-16 13:42:49 +01:00
}
public static void setScreenBrightness(boolean autoBrightness, int brightnessValue)
{
if (autoBrightness)
2021-02-16 13:42:49 +01:00
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
int actualBrightnessValue = (int) ((float) brightnessValue / 100.0 * 255.0);
2021-02-16 13:42:49 +01:00
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS, actualBrightnessValue);
}
public boolean isAirplaneModeOn(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
return android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
else
{
return android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
2022-05-29 20:14:50 +02:00
2022-06-01 22:36:30 +02:00
public static boolean runExecutable(Context context, boolean runAsRoot, String path, String parameters)
2022-05-29 20:14:50 +02:00
{
2022-06-01 22:36:30 +02:00
if(runAsRoot)
{
if(!StringUtils.isEmpty(parameters))
return executeCommandViaSu(new String[] { path + " " + parameters });
else
return executeCommandViaSu(new String[] { path });
}
else
{
Object[] result;
File executable = new File(path);
File workingDir = new File(executable.getParent());
if(!StringUtils.isEmpty(parameters))
result = runExternalApplication(path, 0, workingDir, parameters);
else
result = runExternalApplication(path, 0, workingDir, null);
boolean execResult = (boolean) result[0];
return execResult;
}
}
/**
*
* @param commandToExecute
* @param timeout
* @param params
* @return Returns an array: 0=exit code, 1=cmdline output
*/
public static Object[] runExternalApplication(String commandToExecute, long timeout, File workingDirectory, String params)
{
/*
* Classes stolen from https://github.com/stleary/JSON-java
*/
String fullCommand;
if(!StringUtils.isEmpty(params))
fullCommand = commandToExecute + " " + params;
else
fullCommand = commandToExecute;
Miscellaneous.logEvent("i", "Running executable", "Running external application " + fullCommand, 4);
Object[] returnObject = new Object[2];
StringBuilder output = new StringBuilder();
String line = null;
OutputStream stdin = null;
InputStream stderr = null;
InputStream stdout = null;
try
{
Process process = null;
if(workingDirectory != null)
process = Runtime.getRuntime().exec(fullCommand, null, workingDirectory);
else
process = Runtime.getRuntime().exec(fullCommand);
stdin = process.getOutputStream ();
stderr = process.getErrorStream ();
stdout = process.getInputStream ();
// "write" the parms into stdin
/*line = "param1" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param2" + "\n";
stdin.write(line.getBytes() );
stdin.flush();
line = "param3" + "\n";
stdin.write(line.getBytes() );
stdin.flush();*/
stdin.close();
// clean up if any output in stdout
BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stdout] " + line, 4);
output.append(line);
}
brCleanUp.close();
// clean up if any output in stderr
brCleanUp = new BufferedReader (new InputStreamReader(stderr));
while ((line = brCleanUp.readLine ()) != null)
{
Miscellaneous.logEvent ("i", "Running executable", "[Stderr] " + line, 4);
output.append(line);
}
brCleanUp.close();
try
{
// Wait for the process to exit, we want the return code
if(timeout > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
try
{
if(!process.waitFor(timeout, TimeUnit.MILLISECONDS))
{
Miscellaneous.logEvent("i", "Running executable", "Timeout of " + String.valueOf(timeout) + " ms reached. Killing check attempt.", 3);
process.destroyForcibly();
}
}
catch(NoSuchMethodError e)
{
process.waitFor();
}
}
else
process.waitFor();
}
catch (InterruptedException e)
{
Miscellaneous.logEvent("i", "Running executable", "Waiting for process failed: " + Log.getStackTraceString(e), 4);
Miscellaneous.logEvent("i", "Running executable", Log.getStackTraceString(e), 1);
}
if(process.exitValue() == 0)
Miscellaneous.logEvent("i", "Running executable", "ReturnCode: " + String.valueOf(process.exitValue()), 4);
else
Miscellaneous.logEvent("i", "Running executable", "External execution (RC=" + String.valueOf(process.exitValue()) + ") returned error: " + output.toString(), 3);
returnObject[0] = process.exitValue();
returnObject[1] = output.toString();
return returnObject;
}
catch (IOException e)
{
Miscellaneous.logEvent("e", "Running executable", Log.getStackTraceString(e), 1);
}
Miscellaneous.logEvent("i", "Running executable", "Error running external application.", 1);
// if(slotMap != null)
// for(String key : slotMap.keySet())
// System.clearProperty(key);
return null;
2022-05-29 20:14:50 +02:00
}
2022-06-03 19:26:34 +02:00
public static boolean isTetheringActive1(Context context)
{
try
{
for(Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
{
NetworkInterface intf = en.nextElement();
for(Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
{
InetAddress inetAddress = enumIpAddr.nextElement();
if(!intf.isLoopback())
{
if(intf.getName().contains("rndis"))
{
return true;
}
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "isTetheringActive()", Log.getStackTraceString(e), 3);
}
return false;
}
2022-07-02 01:38:39 +02:00
public final static int wakeLockTimeoutDisabled = -1;
static boolean wakeLockStopRequested = false;
2022-07-02 12:46:34 +02:00
public static void wakeLockStart(Context context, long duration)
2022-07-02 01:38:39 +02:00
{
2022-07-02 12:46:34 +02:00
Thread lockThread = new Thread(new Runnable()
2022-07-02 01:38:39 +02:00
{
2022-07-02 12:46:34 +02:00
@Override
public void run()
2022-07-02 01:38:39 +02:00
{
2022-07-02 12:46:34 +02:00
wakeLockStopRequested = false;
long waited = 0;
int step = 2000;
2022-07-02 01:38:39 +02:00
try
{
2022-07-02 12:46:34 +02:00
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK");
fullWakeLock.acquire(); // turn on
2022-07-02 01:38:39 +02:00
2022-07-02 12:46:34 +02:00
do
{
2022-07-02 01:38:39 +02:00
2022-07-02 12:46:34 +02:00
try
{
Thread.sleep(step); // turn on duration
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(duration > 0)
waited += step;
if(wakeLockStopRequested) //stop requested
Miscellaneous.logEvent("i", "WakeLockStart", "Stop requested.", 4);
}
while(!wakeLockStopRequested && (duration < 0 || waited <= duration));
fullWakeLock.release();
}
catch (Exception e)
2022-07-02 01:38:39 +02:00
{
}
}
2022-07-02 12:46:34 +02:00
});
2022-07-02 01:38:39 +02:00
2022-07-02 12:46:34 +02:00
lockThread.start();
2022-07-02 01:38:39 +02:00
}
public static void wakeLockStop()
{
Miscellaneous.logEvent("i", "WakeLockStart", "Requesting stop.", 4);
wakeLockStopRequested = true;
}
2022-10-02 18:59:54 +02:00
2022-10-03 13:22:25 +02:00
public static void startPhoneCall(Context context, String phoneNumber)
2022-10-02 18:59:54 +02:00
{
Intent intent;
/*
Bug in Android 14 makes it necessary to add double quotes around MMI code.
More precisely it's required for codes containing the # character.
*/
if(Build.VERSION.SDK_INT >= 34)
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode("\"" + phoneNumber + "\"")));
else
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + Uri.encode(phoneNumber)));
2022-10-02 18:59:54 +02:00
// intent.setClassName("com.android.phone","com.android.phone.OutgoingCallBroadcaster");
2022-10-02 23:26:27 +02:00
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
2022-10-02 18:59:54 +02:00
context.startActivity(intent);
}
2022-10-03 13:22:25 +02:00
public static void endPhoneCall(Context context)
{
if(Build.VERSION.SDK_INT < 21)
{
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try
{
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm);
c = Class.forName(telephonyService.getClass().getName());
m = c.getDeclaredMethod("endCall");
m.setAccessible(true);
m.invoke(telephonyService);
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
TelecomManager mgr = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE);
mgr.endCall();
}
}
2023-03-12 23:57:54 +01:00
public static void copyToClipboard(Context context, String text)
{
2023-03-15 23:27:27 +01:00
Miscellaneous.logEvent("i", "Clipboard", "Copying data to clipboard: " + text, 4);
2023-03-12 23:57:54 +01:00
2023-03-15 23:27:27 +01:00
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(text);
}
else
{
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("Data-from-Automation", text);
clipboard.setPrimaryClip(clip);
}
2023-03-12 23:57:54 +01:00
}
2023-12-14 00:15:59 +01:00
public static void takeScreenshot()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
{
MyAccessibilityService.getInstance().performGlobalAction(AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
}
}
2023-12-19 23:52:28 +01:00
2023-12-20 23:54:36 +01:00
public static void setLocationService(int desiredState, Context context)
2023-12-19 23:52:28 +01:00
{
2023-12-20 23:54:36 +01:00
// if(desiredState)
// {
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY).toString());
// }
// else
// {
// android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, new Integer(android.provider.Settings.Secure.LOCATION_MODE_OFF).toString());
// }
android.provider.Settings.Secure.putString(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE, String.valueOf(desiredState));
2023-12-19 23:52:28 +01:00
}
}