2021-02-16 13:42:49 +01:00
package com.jens.automation2 ;
2021-05-30 20:03:30 +02:00
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 ;
2021-05-30 12:27:27 +02:00
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 ;
2021-05-12 17:16:56 +02:00
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
{
2021-05-30 20:03:30 +02:00
if ( toggleActionIfPossible )
2021-02-16 13:42:49 +01:00
{
Miscellaneous . logEvent ( " i " , " setScreenRotation " , myContext . getResources ( ) . getString ( R . string . toggling ) , 2 ) ;
2021-05-30 20:03:30 +02:00
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 ;
}
2021-05-30 20:03:30 +02:00
if ( desiredState )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02:00
if ( android . provider . Settings . System . getInt ( myContext . getContentResolver ( ) , android . provider . Settings . System . ACCELEROMETER_ROTATION , 0 ) = = 1 )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02: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 ) ;
}
}
2021-05-30 20:03:30 +02:00
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 )
{
2021-05-30 20:03:30 +02:00
WifiManager wifiManager = ( WifiManager ) context . getSystemService ( Context . WIFI_SERVICE ) ;
2021-02-16 13:42:49 +01:00
boolean currentlyEnabled = false ;
Method [ ] methods = wifiManager . getClass ( ) . getDeclaredMethods ( ) ;
2021-05-30 20:03:30 +02:00
for ( Method method : methods )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02: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 ( ) ) ;
2021-05-30 20:03:30 +02:00
if ( currentlyEnabled )
2021-02-16 13:42:49 +01:00
Miscellaneous . logEvent ( " i " , " isWifiApEnabled " , " true " , 5 ) ;
else
Miscellaneous . logEvent ( " i " , " isWifiApEnabled " , " false " , 5 ) ;
}
2021-05-30 20:03:30 +02:00
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-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
if ( toggleActionIfPossible )
2021-02-16 13:42:49 +01:00
{
Miscellaneous . logEvent ( " i " , " WifiAp " , context . getResources ( ) . getString ( R . string . toggling ) , 2 ) ;
desiredState = ! state ;
}
2021-05-30 20:03:30 +02:00
if ( ( ( state & & ! desiredState ) | | ( ! state & & desiredState ) ) )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02:00
if ( Build . VERSION . SDK_INT < Build . VERSION_CODES . O )
2021-02-16 13:42:49 +01:00
{
2021-05-30 12:27:27 +02: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
{
2021-05-30 12:27:27 +02: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
{
2021-05-30 12:27:27 +02:00
try
2021-02-16 13:42:49 +01:00
{
2021-05-30 12:27:27 +02: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
}
2021-05-30 12:27:27 +02:00
catch ( Exception e )
2021-02-16 13:42:49 +01:00
{
2021-05-30 12:27:27 +02:00
Miscellaneous . logEvent ( " i " , " WifiAp " , context . getResources ( ) . getString ( R . string . errorActivatingWifiAp ) + " . " + e . getMessage ( ) , 2 ) ;
2021-02-16 13:42:49 +01:00
}
}
2021-05-30 12:27:27 +02:00
}
}
else
{
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback ( )
{
@Override
public void onTetheringStarted ( )
2021-02-16 13:42:49 +01:00
{
2021-05-30 12:27:27 +02:00
Log . i ( " Tether " , " Läuft " ) ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 12:27:27 +02:00
@Override
public void onTetheringFailed ( )
{
Log . i ( " Tether " , " Doof " ) ;
}
} ;
MyOreoWifiManager mowm = new MyOreoWifiManager ( context ) ;
2021-05-30 20:03:30 +02:00
if ( desiredState )
2021-05-30 12:27:27 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
connMgr = ( ConnectivityManager ) connectivityServiceObject ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02:00
if ( ( state & & ! desiredState ) | | ( ! state & & desiredState ) )
2021-02-16 13:42:49 +01:00
{
try
{
Method method = connectivityServiceObject . getClass ( ) . getDeclaredMethod ( " getTetheredIfaces " ) ;
2021-05-30 20:03:30 +02:00
if ( ! method . isAccessible ( ) )
2021-02-16 13:42:49 +01:00
method . setAccessible ( true ) ;
String [ ] tetheredInterfaces = ( String [ ] ) method . invoke ( connectivityServiceObject ) ;
2021-05-30 20:03:30 +02:00
if ( tetheredInterfaces . length > 0 )
2021-02-16 13:42:49 +01:00
state = true ;
}
2021-05-30 20:03:30 +02:00
catch ( NoSuchMethodException e )
2021-02-16 13:42:49 +01:00
{
// System doesn't have that method, try another way
String ipAddr = getIPAddressUsb ( true ) ;
2021-05-30 20:03:30 +02:00
if ( ipAddr . length ( ) = = 0 )
state = false ; // tethering not enabled
else
state = true ; // tethering enabled
2021-02-16 13:42:49 +01:00
}
}
}
2021-05-30 20:03:30 +02:00
catch ( Exception e )
2021-02-16 13:42:49 +01:00
{
Miscellaneous . logEvent ( " w " , " UsbTethering " , context2 . getResources ( ) . getString ( R . string . logErrorDeterminingCurrentUsbTetheringState ) , 3 ) ;
}
2021-05-30 20:03:30 +02:00
if ( toggleActionIfPossible )
2021-02-16 13:42:49 +01:00
{
Miscellaneous . logEvent ( " w " , " UsbTethering " , context2 . getResources ( ) . getString ( R . string . toggling ) , 3 ) ;
desiredState = ! state ;
}
2021-05-30 20:03:30 +02:00
if ( ( state & & ! desiredState ) | | ( ! state & & desiredState ) )
2021-02-16 13:42:49 +01:00
{
String desiredString = " " ;
2021-05-30 20:03:30 +02:00
if ( desiredState )
2021-02-16 13:42:49 +01:00
desiredString = " activate " ;
else
desiredString = " deactivate " ;
try
{
Method method = null ;
2021-05-30 20:03:30 +02:00
for ( Method m : connectivityServiceObject . getClass ( ) . getDeclaredMethods ( ) )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02:00
if ( desiredState & & m . getName ( ) . equals ( " tether " ) )
2021-02-16 13:42:49 +01:00
{
method = m ;
break ;
}
2021-05-30 20:03:30 +02:00
if ( ! desiredState & & m . getName ( ) . equals ( " untether " ) )
2021-02-16 13:42:49 +01:00
{
method = m ;
break ;
}
}
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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
{
2021-05-30 20:03:30 +02:00
try
{
if ( ! method . isAccessible ( ) )
2021-02-16 13:42:49 +01:00
method . setAccessible ( true ) ;
2021-05-30 20:03:30 +02:00
available = ( String [ ] ) getMethod . invoke ( connMgr ) ;
2021-02-16 13:42:49 +01:00
// break;
2021-05-30 20:03:30 +02:00
}
catch ( Exception e )
{
e . printStackTrace ( ) ;
}
}
}
2021-02-16 13:42:49 +01:00
// DETECT INTERFACE NAME
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
if ( ! method . isAccessible ( ) )
2021-02-16 13:42:49 +01:00
method . setAccessible ( true ) ;
2021-05-30 20:03:30 +02:00
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-05-30 20:03:30 +02:00
}
}
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 ) ;
}
2021-05-30 20:03:30 +02:00
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
2021-05-30 20:03:30 +02:00
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
2021-05-30 20:03:30 +02:00
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
2021-05-30 20:03:30 +02:00
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 ;
}
}
2021-05-30 20:03:30 +02:00
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
2021-05-30 20:03:30 +02: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
2022-01-21 13:00:44 +01:00
myAudioManager . setRingerMode ( desiredSoundSetting ) ;
2021-02-16 13:42:49 +01:00
}
private static String getIPAddressUsb ( final boolean useIPv4 )
{
2021-05-30 20:03:30 +02:00
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 )
{
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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 )
{
2021-05-30 20:03:30 +02:00
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
// {
2021-05-30 20:03:30 +02:00
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
// }
2021-05-30 20:03:30 +02:00
ClientConnectionManager ccm = client . getConnectionManager ( ) ;
SchemeRegistry sr = ccm . getSchemeRegistry ( ) ;
2021-02-16 13:42:49 +01:00
// if(!Settings.httpAcceptAllCertificates)
2021-05-30 20:03:30 +02:00
sr . register ( new Scheme ( " https " , ssf , 443 ) ) ;
2021-02-16 13:42:49 +01:00
// else
// sr.register(new Scheme("https", ssfI, 443));
2021-05-30 20:03:30 +02:00
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 ) ;
2023-12-03 23:24:58 +01:00
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
2021-05-30 20:03:30 +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
2021-05-30 20:03:30 +02:00
if ( ! params [ 0 ] . equals ( dummyPackageString ) )
2023-11-08 00:15:39 +01:00
externalApplicationIntent . setPackage ( params [ 0 ] ) ;
2021-05-12 17:16:56 +02:00
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
}
2021-05-12 17:16:56 +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 " ;
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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
}
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02:00
PendingIntent pi = PendingIntent . getActivity ( context , 0 , new Intent ( context , Actions . class ) , 0 ) ;
SmsManager sms = SmsManager . getDefault ( ) ;
2022-01-21 13:56:21 +01:00
sms . sendTextMessage ( phoneNumber , null , textToSend , pi , null ) ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 20:03:30 +02: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-05-30 20:03:30 +02:00
}
2021-02-16 13:42:49 +01:00
2021-05-30 20:03:30 +02: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 ( )
{
2021-05-30 20:03:30 +02:00
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 )
{
2021-05-30 20:03:30 +02:00
/ *
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
2021-05-30 20:03:30 +02: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 ) ;
2021-05-30 20:03:30 +02:00
if ( toggleActionIfPossible )
2021-02-16 13:42:49 +01:00
{
Miscellaneous . logEvent ( " i " , " Airplane mode " , context . getResources ( ) . getString ( R . string . toggling ) , 4 ) ;
desiredState = ! isEnabled ;
}
2021-05-30 20:03:30 +02:00
if ( isEnabled ! = desiredState )
2021-02-16 13:42:49 +01:00
{
int desiredValueInt = 0 ;
2021-05-30 20:03:30 +02:00
if ( desiredState )
2021-02-16 13:42:49 +01:00
desiredValueInt = 1 ;
2021-05-30 20:03:30 +02:00
if ( Build . VERSION . SDK_INT < 17 | | ActivityPermissions . havePermission ( Manifest . permission . WRITE_SECURE_SETTINGS , context ) )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02:00
if ( desiredState )
2021-02-16 13:42:49 +01:00
{
String [ ] commands = new String [ ]
2021-05-30 20:03:30 +02:00
{
" 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 [ ]
2021-05-30 20:03:30 +02:00
{
" 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 ) ;
}
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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
2021-05-30 20:03:30 +02:00
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 ;
}
2021-05-30 20:03:30 +02:00
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
}
2021-05-30 20:03:30 +02: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
2021-05-30 20:03:30 +02:00
// if(desiredState)
// {
Miscellaneous . logEvent ( " e " , " Play music " , " Starting music player... " , 3 ) ;
2021-02-16 13:42:49 +01:00
2021-05-30 20:03:30 +02: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
}
2021-05-30 20:03:30 +02: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 ;
}
2021-05-30 20:03:30 +02:00
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 ( )
{
2021-05-30 20:03:30 +02:00
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
{
2021-05-30 20:03:30 +02:00
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
/ * *
2021-05-30 20:03:30 +02: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
2021-05-30 20:03:30 +02: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
2021-05-30 20:03:30 +02:00
Boolean isEnabled = isMobileDataEnabled ( ) ;
2021-05-16 19:51:22 +02:00
2021-05-30 20:03:30 +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 )
2021-05-30 20:03:30 +02:00
{
for ( Method m : iConnectivityManagerClass . getDeclaredMethods ( ) )
2021-05-16 19:51:22 +02:00
{
2021-05-30 20:03:30 +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
2021-05-30 20:03:30 +02:00
final Method setMobileDataEnabledMethod = iConnectivityManagerClass . getDeclaredMethod ( " setMobileDataEnabled " , Boolean . TYPE ) ;
setMobileDataEnabledMethod . setAccessible ( true ) ;
setMobileDataEnabledMethod . invoke ( iConnectivityManager , desiredState ) ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 20:03:30 +02:00
else
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02:00
return setDataConnectionWithRoot ( desiredState ) ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 20:03:30 +02: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-05-30 20:03:30 +02:00
}
2021-02-16 13:42:49 +01:00
2021-10-03 21:38:33 +02:00
protected static boolean setDataConnectionWithRoot ( boolean desiredState )
2021-05-30 20:03:30 +02:00
{
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
}
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +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
// 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-05-30 20:03:30 +02:00
{
2021-10-03 15:09:07 +02:00
if ( transactionCode ! = null & & transactionCode . length ( ) > 0 )
2021-05-30 20:03:30 +02:00
{
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-05-30 20:03:30 +02:00
}
}
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-05-30 20:03:30 +02:00
{
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 } ) ;
2021-05-30 20:03:30 +02:00
}
}
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-05-30 20:03:30 +02: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 ;
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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 ) ;
}
2021-05-30 20:03:30 +02:00
catch ( Exception e )
2021-02-16 13:42:49 +01:00
{
2021-05-30 20:03:30 +02:00
Miscellaneous . logEvent ( " e " , " isMobileDataEnabled() " , " Error checking if mobile data is enabled: " + Log . getStackTraceString ( e ) , 3 ) ;
2021-02-16 13:42:49 +01:00
}
2021-05-30 20:03:30 +02: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
{
2021-05-30 20:03:30 +02:00
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-05-30 20:03:30 +02: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 ;
2021-05-30 20:03:30 +02:00
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 )
2021-05-30 20:03:30 +02:00
success = true ;
}
2022-07-14 22:55:54 +02:00
else
Miscellaneous . logEvent ( " w " , " executeCommandViaSu() " , " su not available. " , 4 ) ;
2021-05-30 20:03:30 +02:00
}
catch ( Exception e )
{
success = false ;
}
2022-07-14 22:55:54 +02:00
Miscellaneous . logEvent ( " i " , " executeCommandViaSu() " , " Returning " + String . valueOf ( success ) , 4 ) ;
2021-05-30 20:03:30 +02:00
return success ;
2021-02-16 13:42:49 +01:00
}
public static void setScreenBrightness ( boolean autoBrightness , int brightnessValue )
{
2021-05-30 20:03:30 +02:00
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 ) ;
2021-05-30 20:03:30 +02:00
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 ) ;
}
2021-05-30 20:03:30 +02:00
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
{
2023-12-18 22:55:18 +01: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
}
2021-05-30 20:03:30 +02:00
}