From 21ee06e9b11d9e58f5ef81847cd234e6da932c11 Mon Sep 17 00:00:00 2001 From: jens Date: Sun, 30 May 2021 20:03:30 +0200 Subject: [PATCH] Wifi tethering without root above Oreo works again. --- .../java/com/jens/automation2/Actions.java | 905 +++++++++--------- .../ActivityManageActionSendTextMessage.java | 2 +- .../ActivityManageActionSpeakText.java | 2 +- .../ActivityManageActionTriggerUrl.java | 2 +- .../jens/automation2/ActivityManageRule.java | 10 +- ...tivity_manage_action_send_textmessage.xml} | 0 ... => activity_manage_action_speak_text.xml} | 0 ...=> activity_manage_action_trigger_url.xml} | 9 +- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values-es/strings.xml | 2 + app/src/main/res/values/strings.xml | 3 +- .../metadata/android/en-US/changelogs/105.txt | 3 + 12 files changed, 489 insertions(+), 450 deletions(-) rename app/src/main/res/layout/{send_textmessage_editor.xml => activity_manage_action_send_textmessage.xml} (100%) rename app/src/main/res/layout/{speak_text_editor.xml => activity_manage_action_speak_text.xml} (100%) rename app/src/main/res/layout/{activity_manage_action_url_editor.xml => activity_manage_action_trigger_url.xml} (90%) create mode 100644 fastlane/metadata/android/en-US/changelogs/105.txt diff --git a/app/src/main/java/com/jens/automation2/Actions.java b/app/src/main/java/com/jens/automation2/Actions.java index 53e8b34e..70939fd9 100644 --- a/app/src/main/java/com/jens/automation2/Actions.java +++ b/app/src/main/java/com/jens/automation2/Actions.java @@ -1,5 +1,6 @@ package com.jens.automation2; +import android.Manifest; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.PendingIntent; @@ -58,8 +59,8 @@ public class Actions private static Intent playMusicIntent; private static boolean suAvailable = false; private static String suVersion = null; - private static String suVersionInternal = null; - private static List suResult = null; + private static String suVersionInternal = null; + private static List suResult = null; public final static String smsSeparator = "&sms&"; public final static String dummyPackageString = "dummyPkg239asd"; @@ -71,24 +72,24 @@ public class Actions { Miscellaneous.logEvent("i", "Wifi", "Changing Wifi to " + String.valueOf(desiredState), 4); - if(desiredState && Settings.useWifiForPositioning) + if (desiredState && Settings.useWifiForPositioning) WifiBroadcastReceiver.startWifiReceiver(autoMationServerRef.getLocationProvider()); - WifiManager myWifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); + WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); // toggle - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Toast.makeText(context, context.getResources().getString(R.string.toggling) + " " + context.getResources().getString(R.string.wifi), Toast.LENGTH_LONG).show(); desiredState = !myWifi.isWifiEnabled(); } // Only perform action if necessary - if((!myWifi.isWifiEnabled() && desiredState) | (myWifi.isWifiEnabled() && !desiredState)) + if ((!myWifi.isWifiEnabled() && desiredState) | (myWifi.isWifiEnabled() && !desiredState)) { String wifiString = ""; - if(desiredState) + if (desiredState) { wifiString = context.getResources().getString(R.string.activating) + " " + context.getResources().getString(R.string.wifi); } @@ -100,7 +101,7 @@ public class Actions Toast.makeText(context, wifiString, Toast.LENGTH_LONG).show(); boolean returnValue = myWifi.setWifiEnabled(desiredState); - if(!returnValue) + 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); @@ -116,19 +117,19 @@ public class Actions Miscellaneous.logEvent("i", "ScreenRotation", "Changing ScreenRotation to " + String.valueOf(desiredState), 4); try { - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.toggling), 2); - boolean currentStatus = android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0; - if(currentStatus) + boolean currentStatus = android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0; + if (currentStatus) desiredState = !currentStatus; } - if(desiredState) + if (desiredState) { - if(android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0) + if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0) { - android.provider.Settings.System.putInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 1); + android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 1); Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationEnabled), 2); } else @@ -136,16 +137,16 @@ public class Actions } else { - if(android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 1) + if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 1) { - android.provider.Settings.System.putInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0); + android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0); Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationDisabled), 2); } else Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationAlreadyDisabled), 2); } } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", "setScreenRotation", myContext.getResources().getString(R.string.errorChangingScreenRotation) + ": " + Log.getStackTraceString(e), 2); } @@ -153,25 +154,25 @@ public class Actions private static boolean isWifiApEnabled(Context context) { - WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); boolean currentlyEnabled = false; Method[] methods = wifiManager.getClass().getDeclaredMethods(); - for(Method method : methods) + for (Method method : methods) { - if(method.getName().equals("isWifiApEnabled")) + if (method.getName().equals("isWifiApEnabled")) { try { Object returnObject = method.invoke(wifiManager); currentlyEnabled = Boolean.valueOf(returnObject.toString()); - if(currentlyEnabled) + if (currentlyEnabled) Miscellaneous.logEvent("i", "isWifiApEnabled", "true", 5); else Miscellaneous.logEvent("i", "isWifiApEnabled", "false", 5); } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("i", "isWifiApEnabled", context.getResources().getString(R.string.errorDeterminingWifiApState) + ": " + e.getMessage(), 4); } @@ -179,21 +180,22 @@ public class Actions } return currentlyEnabled; } + public static Boolean setWifiTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible) { Miscellaneous.logEvent("i", "WifiTethering", "Changing WifiTethering to " + String.valueOf(desiredState), 4); boolean state = Actions.isWifiApEnabled(context); - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Miscellaneous.logEvent("i", "WifiAp", context.getResources().getString(R.string.toggling), 2); desiredState = !state; } - if(((state && !desiredState) || (!state && desiredState))) + if (((state && !desiredState) || (!state && desiredState))) { - if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); Method[] methods = wifiManager.getClass().getDeclaredMethods(); @@ -252,7 +254,7 @@ public class Actions }; MyOreoWifiManager mowm = new MyOreoWifiManager(context); - if(desiredState) + if (desiredState) mowm.startTethering(cb); else mowm.stopTethering(); @@ -274,9 +276,9 @@ public class Actions try { connectivityServiceObject = context.getSystemService(Context.CONNECTIVITY_SERVICE); - connMgr = (ConnectivityManager)connectivityServiceObject; + connMgr = (ConnectivityManager) connectivityServiceObject; } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", "UsbTethering", context2.getResources().getString(R.string.logErrorGettingConnectionManagerService), 2); return false; @@ -284,45 +286,45 @@ public class Actions try { - if((state && !desiredState) || (!state && desiredState)) + if ((state && !desiredState) || (!state && desiredState)) { try { Method method = connectivityServiceObject.getClass().getDeclaredMethod("getTetheredIfaces"); - if(!method.isAccessible()) + if (!method.isAccessible()) method.setAccessible(true); String[] tetheredInterfaces = (String[]) method.invoke(connectivityServiceObject); - if(tetheredInterfaces.length > 0) + if (tetheredInterfaces.length > 0) state = true; } - catch(NoSuchMethodException e) + catch (NoSuchMethodException e) { // System doesn't have that method, try another way String ipAddr = getIPAddressUsb(true); - if (ipAddr.length() == 0) - state = false; // tethering not enabled - else - state = true; // tethering enabled + if (ipAddr.length() == 0) + state = false; // tethering not enabled + else + state = true; // tethering enabled } } } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.logErrorDeterminingCurrentUsbTetheringState), 3); } - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.toggling), 3); desiredState = !state; } - if((state && !desiredState) || (!state && desiredState)) + if ((state && !desiredState) || (!state && desiredState)) { String desiredString = ""; - if(desiredState) + if (desiredState) desiredString = "activate"; else desiredString = "deactivate"; @@ -331,22 +333,22 @@ public class Actions { Method method = null; - for(Method m : connectivityServiceObject.getClass().getDeclaredMethods()) + for (Method m : connectivityServiceObject.getClass().getDeclaredMethods()) { - if(desiredState && m.getName().equals("tether")) + if (desiredState && m.getName().equals("tether")) { method = m; break; } - if(!desiredState && m.getName().equals("untether")) + if (!desiredState && m.getName().equals("untether")) { method = m; break; } } - if(method == null) + if (method == null) throw new NoSuchMethodException(); @@ -360,38 +362,38 @@ public class Actions // DETECT INTERFACE NAME Miscellaneous.logEvent("i", "UsbTethering", context2.getResources().getString(R.string.logDetectingTetherableUsbInterface), 4); - String[] available = null; - Method[] wmMethods = connMgr.getClass().getDeclaredMethods(); - for(Method getMethod: wmMethods) - { - if(getMethod.getName().equals("getTetherableUsbRegexs")) + String[] available = null; + Method[] wmMethods = connMgr.getClass().getDeclaredMethods(); + for (Method getMethod : wmMethods) + { + if (getMethod.getName().equals("getTetherableUsbRegexs")) { - try - { - if(!method.isAccessible()) + try + { + if (!method.isAccessible()) method.setAccessible(true); - available = (String[]) getMethod.invoke(connMgr); + available = (String[]) getMethod.invoke(connMgr); // break; - } - catch (Exception e) - { - e.printStackTrace(); - } - } - } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } // DETECT INTERFACE NAME - if(available.length > 0) - { - for(String interfaceName : available) - { - Miscellaneous.logEvent("i", "UsbTethering", "Detected " + String.valueOf(available.length) + " tetherable usb interfaces.", 5); + if (available.length > 0) + { + for (String interfaceName : available) + { + Miscellaneous.logEvent("i", "UsbTethering", "Detected " + String.valueOf(available.length) + " tetherable usb interfaces.", 5); Miscellaneous.logEvent("i", "UsbTethering", "Trying to " + desiredString + " UsbTethering on interface " + interfaceName + "...", 5); - if(!method.isAccessible()) + if (!method.isAccessible()) method.setAccessible(true); - Integer returnCode = (Integer)method.invoke(connectivityServiceObject, interfaceName); - if(returnCode == 0) + Integer returnCode = (Integer) method.invoke(connectivityServiceObject, interfaceName); + if (returnCode == 0) { Miscellaneous.logEvent("i", "UsbTethering", "UsbTethering " + desiredString + "d.", 5); return true; @@ -400,14 +402,14 @@ public class Actions { Miscellaneous.logEvent("w", "UsbTethering", "Failed to " + desiredString + "Usb Tethering. ReturnCode of method " + method.getName() + ": " + String.valueOf(returnCode), 5); } - } - } + } + } } catch (NoSuchMethodException e) { Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. This kind of error may indicate we are above Android 2.3: " + Log.getStackTraceString(e), 3); } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. " + Log.getStackTraceString(e), 3); } @@ -424,14 +426,14 @@ public class Actions BluetoothAdapter myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // toggle - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.toggling), 2); desiredState = !myBluetoothAdapter.isEnabled(); } // activate - if(!myBluetoothAdapter.isEnabled() && desiredState) + if (!myBluetoothAdapter.isEnabled() && desiredState) { Toast.makeText(context, context.getResources().getString(R.string.activating) + " Bluetooth.", Toast.LENGTH_LONG).show(); myBluetoothAdapter.enable(); @@ -439,14 +441,14 @@ public class Actions } // deactivate - if(myBluetoothAdapter.isEnabled() && !desiredState) + if (myBluetoothAdapter.isEnabled() && !desiredState) { Toast.makeText(context, context.getResources().getString(R.string.deactivating) + " Bluetooth.", Toast.LENGTH_LONG).show(); myBluetoothAdapter.disable(); return true; } } - catch(NullPointerException e) + catch (NullPointerException e) { Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.failedToTriggerBluetooth), 2); Toast.makeText(context, context.getResources().getString(R.string.bluetoothFailed), Toast.LENGTH_LONG).show(); @@ -459,59 +461,59 @@ public class Actions { Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing sound to " + String.valueOf(soundSetting), 4); - AudioManager myAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); + AudioManager myAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); myAudioManager.setRingerMode(soundSetting); } private static String getIPAddressUsb(final boolean useIPv4) { - try - { - final List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); - for (final NetworkInterface intf : interfaces) - { - if (intf.getDisplayName().startsWith("usb")) // ro "rndis0" - { - final List 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 ""; + try + { + final List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (final NetworkInterface intf : interfaces) + { + if (intf.getDisplayName().startsWith("usb")) // ro "rndis0" + { + final List 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 ""; } public static void playSound(boolean alwaysPlay, String soundFileLocation) { - if(alwaysPlay || ((AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE)).getRingerMode() == AudioManager.RINGER_MODE_NORMAL) + if (alwaysPlay || ((AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE)).getRingerMode() == AudioManager.RINGER_MODE_NORMAL) { MediaPlayer mp = new MediaPlayer(); try { File file = new File(soundFileLocation); - if(file.exists()) + if (file.exists()) { Uri fileUri = Uri.parse(soundFileLocation); mp.setLooping(false); @@ -549,10 +551,10 @@ public class Actions public static HttpClient getInsecureSslClient(HttpClient client) { - try - { - SSLContext ctx = SSLContext.getInstance("TLS"); - SSLSocketFactory ssf = null; + try + { + SSLContext ctx = SSLContext.getInstance("TLS"); + SSLSocketFactory ssf = null; // MySSLSocketFactoryInsecure ssfI = null; // if(!Settings.httpAcceptAllCertificates) @@ -575,28 +577,28 @@ public class Actions // } // else // { - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - trustStore.load(null, null); - ssf = new MySSLSocketFactoryInsecure(trustStore); - ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - ctx.init(null, null, null); + 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); // } - ClientConnectionManager ccm = client.getConnectionManager(); - SchemeRegistry sr = ccm.getSchemeRegistry(); + ClientConnectionManager ccm = client.getConnectionManager(); + SchemeRegistry sr = ccm.getSchemeRegistry(); // if(!Settings.httpAcceptAllCertificates) - sr.register(new Scheme("https", ssf, 443)); + sr.register(new Scheme("https", ssf, 443)); // else // sr.register(new Scheme("https", ssfI, 443)); - return new DefaultHttpClient(ccm, client.getParams()); - } - catch (Exception ex) - { - ex.printStackTrace(); - return null; - } + return new DefaultHttpClient(ccm, client.getParams()); + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } } public static void startOtherActivity(boolean startByAction, String param) @@ -611,7 +613,7 @@ public class Actions int paramsStartIndex; - if(!startByAction) + if (!startByAction) { // selected by activity @@ -630,9 +632,9 @@ public class Actions // if(packageName.equals("dummyPkg")) // externalActivityIntent.setAction(className); // else - externalActivityIntent.setClassName(packageName, className); + externalActivityIntent.setClassName(packageName, className); - if(!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext())) + if (!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext())) Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2); } else @@ -642,7 +644,7 @@ public class Actions externalActivityIntent = new Intent(); - if(!params[0].equals(dummyPackageString)) + if (!params[0].equals(dummyPackageString)) externalActivityIntent.setPackage(params[0]); externalActivityIntent.setAction(params[1]); @@ -712,7 +714,7 @@ public class Actions } else if (singleParam[0].equals("Uri")) { - if(singleParam[1].equalsIgnoreCase("IntentData")) + if (singleParam[1].equalsIgnoreCase("IntentData")) { Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3); externalActivityIntent.setData(Uri.parse(singleParam[2])); @@ -732,12 +734,12 @@ public class Actions Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3); } - if(params[2].equals(ActivityManageActionStartActivity.startByActivityString)) + if (params[2].equals(ActivityManageActionStartActivity.startByActivityString)) autoMationServerRef.startActivity(externalActivityIntent); else autoMationServerRef.sendBroadcast(externalActivityIntent); } - catch(Exception e) + 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(); @@ -761,26 +763,26 @@ public class Actions public static void wakeupDevice(Long awakeTime) { String duration = "default"; - if(awakeTime > 0) + if (awakeTime > 0) duration = String.valueOf(awakeTime) + " milliseconds"; Miscellaneous.logEvent("i", "wakeupDevice", "wakeupDevice for " + String.valueOf(duration) + ".", 4); - if(awakeTime > 0) - { - /* - * This action needs to be performed in a separate thread. If it ran in the same one - * the screen would turn on, the specified amount of time would pass and the screen - * would turn off again before any other action in the rule would be ran. - */ - Thread t = new Thread(new WakeUpDeviceClass(awakeTime)); - t.start(); - } + 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(); + } } - public static void sendTextMessage(Context context, String[] parametersArray) - { - String phoneNumber, message; + public static void sendTextMessage(Context context, String[] parametersArray) + { + String phoneNumber, message; phoneNumber = parametersArray[0]; message = parametersArray[1]; @@ -795,17 +797,17 @@ public class Actions AutomationService.getInstance().startActivity(intent); */ - PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, Actions.class), 0); - SmsManager sms = SmsManager.getDefault(); - sms.sendTextMessage(phoneNumber, null, message, pi, null); + PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, Actions.class), 0); + SmsManager sms = SmsManager.getDefault(); + sms.sendTextMessage(phoneNumber, null, message, pi, null); } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", Miscellaneous.getAnyContext().getString(R.string.sendTextMessage), "Error in sendTextMessage: " + Log.getStackTraceString(e), 3); } - } + } - private static class WakeUpDeviceClass implements Runnable + private static class WakeUpDeviceClass implements Runnable { private long awakeTime; @@ -819,19 +821,19 @@ public class Actions public void run() { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - WakeLock wakeLock = pm.newWakeLock((WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock"); - wakeLock.acquire(); + WakeLock wakeLock = pm.newWakeLock((WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Automation:Wakelock"); + wakeLock.acquire(); - try + try { Thread.sleep(awakeTime); } - catch (InterruptedException e) + catch (InterruptedException e) { Miscellaneous.logEvent("w", context.getResources().getString(R.string.wakeupDevice), "Error keeping device awake: " + Log.getStackTraceString(e), 4); } - wakeLock.release(); + wakeLock.release(); } } @@ -839,8 +841,13 @@ public class Actions @SuppressLint("NewApi") public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible) { - // Beginning from SDK Version 17 this may not work anymore. - // Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, value is unchanged. + /* + 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 + */ boolean returnValue = false; @@ -848,47 +855,52 @@ public class Actions { boolean isEnabled = ConnectivityReceiver.isAirplaneMode(autoMationServerRef); - if(isEnabled) + if (isEnabled) Miscellaneous.logEvent("i", "Airplane mode", "Current status is enabled.", 4); else Miscellaneous.logEvent("i", "Airplane mode", "Current status is disabled.", 4); - if(toggleActionIfPossible) + if (toggleActionIfPossible) { Miscellaneous.logEvent("i", "Airplane mode", context.getResources().getString(R.string.toggling), 4); desiredState = !isEnabled; } - if(isEnabled != desiredState) + if (isEnabled != desiredState) { int desiredValueInt = 0; - if(desiredState) + if (desiredState) desiredValueInt = 1; - if(Build.VERSION.SDK_INT < 17) + if (Build.VERSION.SDK_INT < 17 || ActivityPermissions.havePermission(Manifest.permission.WRITE_SECURE_SETTINGS, context)) { - 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.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); } else { - if(desiredState) + if (desiredState) { String[] commands = new String[] - { - "settings put global airplane_mode_on 1", - "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" - }; + { + "settings put global airplane_mode_on 1", + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true" + }; returnValue = executeCommandViaSu(commands); } else { - String[] commands = new String[] - { - "settings put global airplane_mode_on 0", - "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false" - }; + { + "settings put global airplane_mode_on 0", + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false" + }; returnValue = executeCommandViaSu(commands); } @@ -903,7 +915,7 @@ public class Actions else Miscellaneous.logEvent("i", "Airplane mode", "Airplane mode is already in status " + String.valueOf(desiredState) + ". Nothing to do.", 3); } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", "Airplane mode", Log.getStackTraceString(e), 2); } @@ -918,7 +930,7 @@ public class Actions public static boolean setNetworkType(int desiredType) { Miscellaneous.logEvent("i", "setNetworkType", "Asked to set network type to: " + String.valueOf(desiredType), 3); - if(desiredType > 0) + if (desiredType > 0) { try { @@ -926,7 +938,7 @@ public class Actions // TelephonyManager.NETWORK_TYPE_EDGE - if(connManager.getNetworkPreference() == desiredType) + if (connManager.getNetworkPreference() == desiredType) { Miscellaneous.logEvent("i", "setNetworkType", "Desired networkType already set. Not doing anything.", 4); } @@ -937,7 +949,7 @@ public class Actions } return true; } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", "setNetworkType", "Error changing network type: " + Log.getStackTraceString(e), 2); return false; @@ -957,7 +969,7 @@ public class Actions String textToSpeak = Miscellaneous.replaceVariablesInText(parameter2, context); autoMationServerRef.speak(textToSpeak, true); } - catch(Exception e) + catch (Exception e) { Miscellaneous.logEvent("e", "Speak text", "Error in speak text: " + Log.getStackTraceString(e), 3); } @@ -969,47 +981,47 @@ public class Actions try { //TODO:toggle - // if(desiredState) - // { - Miscellaneous.logEvent("e", "Play music", "Starting music player...", 3); + // if(desiredState) + // { + Miscellaneous.logEvent("e", "Play music", "Starting music player...", 3); - 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); + 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); + playMusicIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(playMusicIntent); - // playMusicIntent = new Intent(); - // playMusicIntent.setAction(android.content.Intent.ACTION_VIEW); - // File file = new File(YOUR_SONG_URI); - // playMusicIntent.setDataAndType(Uri.fromFile(file), "audio/*"); - // context.startActivity(playMusicIntent); + // playMusicIntent = new Intent(); + // playMusicIntent.setAction(android.content.Intent.ACTION_VIEW); + // File file = new File(YOUR_SONG_URI); + // playMusicIntent.setDataAndType(Uri.fromFile(file), "audio/*"); + // context.startActivity(playMusicIntent); - return true; - // } - // else - // { - // if(playMusicIntent != null) - // { - // context.stopService(playMusicIntent); - // } - // } + return true; + // } + // else + // { + // if(playMusicIntent != null) + // { + // context.stopService(playMusicIntent); + // } + // } - // return false; + // return false; } - catch(ActivityNotFoundException e) + catch (ActivityNotFoundException e) { Toast.makeText(context, "Error: No music player found.", Toast.LENGTH_LONG).show(); Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): No music player found. " + Log.getStackTraceString(e), 3); return false; } - catch(Exception e) + catch (Exception e) { Toast.makeText(context, "Error starting music player.", Toast.LENGTH_LONG).show(); Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): " + Log.getStackTraceString(e), 3); @@ -1019,52 +1031,52 @@ public class Actions private String getTransactionCode() { - try - { - TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - Class telephonyManagerClass = Class.forName(telephonyManager.getClass().getName()); - Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony"); - getITelephonyMethod.setAccessible(true); - Object ITelephonyStub = getITelephonyMethod.invoke(telephonyManager); - Class ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName()); + 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 ""; - } + 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 ""; + } private static String getTransactionCodeFromApi20(Context context) throws Exception { - try - { - final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - final Class mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName()); - final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony"); - mTelephonyMethod.setAccessible(true); - final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager); - final Class mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName()); - final Class mClass = mTelephonyStubClass.getDeclaringClass(); - final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled"); - field.setAccessible(true); - return String.valueOf(field.getInt(null)); - } - catch (Exception e) - { - // The "TRANSACTION_setDataEnabled" field is not available, - // or named differently in the current API level, so we throw - // an exception and inform users that the method is not available. - throw e; - } + 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; + } } public static class MobileDataStuff @@ -1072,243 +1084,256 @@ public class Actions // https://stackoverflow.com/questions/31120082/latest-update-on-enabling-and-disabling-mobile-data-programmatically /** - * Turns data on and off. - * Requires root permissions from lollipop on. - * @param toggleActionIfPossible - */ - public static boolean setDataConnection(boolean desiredState, boolean toggleActionIfPossible) + * 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); + + try { - Miscellaneous.logEvent("i", "setData", "Asked to turn data to: " + String.valueOf(desiredState), 3); + 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()); - try + Boolean isEnabled = isMobileDataEnabled(); + + if (toggleActionIfPossible) { - 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()); + context.getResources().getString(R.string.toggling); + desiredState = !isEnabled; + } - Boolean isEnabled = isMobileDataEnabled(); - - if(toggleActionIfPossible) - { - context.getResources().getString(R.string.toggling); - desiredState = !isEnabled; - } - - if(Build.VERSION.SDK_INT <= 20) + if (Build.VERSION.SDK_INT <= 20) + { + for (Method m : iConnectivityManagerClass.getDeclaredMethods()) { - for(Method m : iConnectivityManagerClass.getDeclaredMethods()) - { - Miscellaneous.logEvent("i", "method", m.getName(), 5); - } - - final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); - setMobileDataEnabledMethod.setAccessible(true); - - setMobileDataEnabledMethod.invoke(iConnectivityManager, desiredState); - } - else - { - return setDataConnectionWithRoot(desiredState); + Miscellaneous.logEvent("i", "method", m.getName(), 5); } - return true; + final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); + setMobileDataEnabledMethod.setAccessible(true); + + setMobileDataEnabledMethod.invoke(iConnectivityManager, desiredState); } - catch(Exception e) + else { - Miscellaneous.logEvent("e", "setData", "Error changing network type: " + Log.getStackTraceString(e), 2); - return false; + return setDataConnectionWithRoot(desiredState); } + + return true; } + catch (Exception e) + { + Miscellaneous.logEvent("e", "setData", "Error changing network type: " + Log.getStackTraceString(e), 2); + return false; + } + } protected static boolean setDataConnectionWithRoot(boolean enable) - { - try - { - int desiredState = 0; - if(enable) - desiredState = 1; + { + try + { + int desiredState = 0; + if (enable) + desiredState = 1; - if(MobileDataStuff.setMobileNetworkFromLollipop(desiredState, autoMationServerRef)) + if (MobileDataStuff.setMobileNetworkFromLollipop(desiredState, autoMationServerRef)) { 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; + Miscellaneous.logEvent("e", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootFail), 2); + return false; } - } - 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); + } + 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; - } - } + Miscellaneous.logEvent("e", "setDataWithRoot()", "Error setting data setting with root. " + rootString + ": " + Log.getStackTraceString(e), 3); + return false; + } + } @SuppressLint("NewApi") public static boolean setMobileNetworkFromLollipop(int desiredState, Context context) throws Exception { - String command = null; - int state = 0; + String command = null; + int state = 0; - try - { - // Get the current state of the mobile network. - state = isMobileDataEnabled() ? 0 : 1; - // Get the value of the "TRANSACTION_setDataEnabled" field. - String transactionCode = getTransactionCode(context); - // Android 5.1+ (API 22) and later. - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) - { - 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++) - { - if (transactionCode != null && transactionCode.length() > 0) - { - // Get the active subscription ID for a given SIM card. + try + { + // Get the current state of the mobile network. + state = isMobileDataEnabled() ? 0 : 1; + // Get the value of the "TRANSACTION_setDataEnabled" field. + String transactionCode = getTransactionCode(context); + // Android 5.1+ (API 22) and later. + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) + { + 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++) + { + if (transactionCode != null && transactionCode.length() > 0) + { + // 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. - command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + desiredState; - Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", "Running command: " + command.toString(), 5); - return executeCommandViaSu(new String[] { command }); - } - } - } - else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) - { - // Android 5.0 (API 21) only. - if (transactionCode != null && transactionCode.length() > 0) - { - // Execute the command via `su` to turn off mobile network. - command = "service call phone " + transactionCode + " i32 " + desiredState; - return executeCommandViaSu(new String[] { command }); - } - } - } - catch(Exception e) - { - // Oops! Something went wrong, so we throw the exception here. - throw e; - } - - return false; + // Execute the command via `su` to turn off + // mobile network for a subscription service. + command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + desiredState; + Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", "Running command: " + command.toString(), 5); + return executeCommandViaSu(new String[]{command}); + } + } + } + else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) + { + // Android 5.0 (API 21) only. + if (transactionCode != null && transactionCode.length() > 0) + { + // Execute the command via `su` to turn off mobile network. + command = "service call phone " + transactionCode + " i32 " + desiredState; + return executeCommandViaSu(new String[]{command}); + } + } + } + catch (Exception e) + { + // Oops! Something went wrong, so we throw the exception here. + throw e; + } + + return false; } - + @SuppressLint("NewApi") public static boolean isMobileDataEnabled() { boolean isEnabled = false; - - if(Build.VERSION.SDK_INT <= 20) - { + + if (Build.VERSION.SDK_INT <= 20) + { try { ConnectivityManager connManager = (ConnectivityManager) Miscellaneous.getAnyContext().getSystemService(Miscellaneous.getAnyContext().CONNECTIVITY_SERVICE); - final Class conmanClass = Class.forName(connManager.getClass().getName()); - final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); - iConnectivityManagerField.setAccessible(true); - final Object iConnectivityManager = iConnectivityManagerField.get(connManager); - final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); - - Method getMobileDataEnabledMethod = null; - for(Method m : iConnectivityManagerClass.getDeclaredMethods()) - { - Miscellaneous.logEvent("i", "Methods", m.getName(), 5); - if(m.getName().equals("getMobileDataEnabled")) - { - getMobileDataEnabledMethod = m; - break; - } - } - // final Method getMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("getMobileDataEnabled", null); - - getMobileDataEnabledMethod.setAccessible(true); - + 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); + isEnabled = (Boolean) getMobileDataEnabledMethod.invoke(iConnectivityManager, (Object[]) null); } - catch (Exception e) + catch (Exception e) { - Miscellaneous.logEvent("e", "isMobileDataEnabled()", "Error checking if mobile data is enabled: " + Log.getStackTraceString(e), 3); + Miscellaneous.logEvent("e", "isMobileDataEnabled()", "Error checking if mobile data is enabled: " + Log.getStackTraceString(e), 3); } - } - else - { - isEnabled = android.provider.Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1; - } - + } + else + { + isEnabled = android.provider.Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1; + } + return isEnabled; } private static String getTransactionCode(Context context) throws Exception { - try - { - final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - final Class mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName()); - final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony"); - mTelephonyMethod.setAccessible(true); - final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager); - final Class mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName()); - final Class mClass = mTelephonyStubClass.getDeclaringClass(); - final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled"); - field.setAccessible(true); - return String.valueOf(field.getInt(null)); - } - catch (Exception e) - { - // The "TRANSACTION_setDataEnabled" field is not available, - // or named differently in the current API level, so we throw - // an exception and inform users that the method is not available. - throw e; - } + 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; + } } } - + protected static boolean executeCommandViaSu(String[] commands) { - boolean success = false; + boolean success = false; - try - { - suAvailable = Shell.SU.available(); - if (suAvailable) - { - suVersion = Shell.SU.version(false); - suVersionInternal = Shell.SU.version(true); - suResult = Shell.SU.run(commands); - - if(suResult != null) - success = true; - } - } - catch (Exception e) - { - success = false; - } - - return success; + try + { + suAvailable = Shell.SU.available(); + if (suAvailable) + { + suVersion = Shell.SU.version(false); + suVersionInternal = Shell.SU.version(true); + suResult = Shell.SU.run(commands); + + if (suResult != null) + success = true; + } + } + catch (Exception e) + { + success = false; + } + + return success; } public static void setScreenBrightness(boolean autoBrightness, int brightnessValue) { - if(autoBrightness) + if (autoBrightness) android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); else android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); - int actualBrightnessValue = (int)((float)brightnessValue / 100.0 * 255.0); + int actualBrightnessValue = (int) ((float) brightnessValue / 100.0 * 255.0); android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS, actualBrightnessValue); } -} + + public boolean isAirplaneModeOn(Context context) + { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) + { + return android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0) != 0; + } + else + { + return android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, 0) != 0; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/jens/automation2/ActivityManageActionSendTextMessage.java b/app/src/main/java/com/jens/automation2/ActivityManageActionSendTextMessage.java index 54abcb32..f399e336 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageActionSendTextMessage.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageActionSendTextMessage.java @@ -36,7 +36,7 @@ public class ActivityManageActionSendTextMessage extends Activity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.setContentView(R.layout.send_textmessage_editor); + this.setContentView(R.layout.activity_manage_action_send_textmessage); etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage); etPhoneNumber = (EditText)findViewById(R.id.etPhoneNumber); diff --git a/app/src/main/java/com/jens/automation2/ActivityManageActionSpeakText.java b/app/src/main/java/com/jens/automation2/ActivityManageActionSpeakText.java index 6cd3d4c9..9f9cf3fe 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageActionSpeakText.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageActionSpeakText.java @@ -24,7 +24,7 @@ public class ActivityManageActionSpeakText extends Activity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.setContentView(R.layout.speak_text_editor); + this.setContentView(R.layout.activity_manage_action_speak_text); etSpeakText = (EditText)findViewById(R.id.etTextToSpeak); bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl); diff --git a/app/src/main/java/com/jens/automation2/ActivityManageActionTriggerUrl.java b/app/src/main/java/com/jens/automation2/ActivityManageActionTriggerUrl.java index 6b57cdc4..8a3d2bb6 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageActionTriggerUrl.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageActionTriggerUrl.java @@ -39,7 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.setContentView(R.layout.activity_manage_action_url_editor); + this.setContentView(R.layout.activity_manage_action_trigger_url); etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl); etTriggerUrlUsername = (EditText)findViewById(R.id.etTriggerUrlUsername); diff --git a/app/src/main/java/com/jens/automation2/ActivityManageRule.java b/app/src/main/java/com/jens/automation2/ActivityManageRule.java index a49cd5fc..3bf0ed8f 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageRule.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageRule.java @@ -1483,13 +1483,13 @@ public class ActivityManageRule extends Activity } else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString())) { - if(Build.VERSION.SDK_INT >= 17) - { - Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show(); - Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show(); - } newAction.setAction(Action_Enum.setAirplaneMode); getActionParameter1Dialog(ActivityManageRule.this).show(); + if(Build.VERSION.SDK_INT >= 17) + { +// Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show(); + Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show(); + } } else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDataConnection.toString())) { diff --git a/app/src/main/res/layout/send_textmessage_editor.xml b/app/src/main/res/layout/activity_manage_action_send_textmessage.xml similarity index 100% rename from app/src/main/res/layout/send_textmessage_editor.xml rename to app/src/main/res/layout/activity_manage_action_send_textmessage.xml diff --git a/app/src/main/res/layout/speak_text_editor.xml b/app/src/main/res/layout/activity_manage_action_speak_text.xml similarity index 100% rename from app/src/main/res/layout/speak_text_editor.xml rename to app/src/main/res/layout/activity_manage_action_speak_text.xml diff --git a/app/src/main/res/layout/activity_manage_action_url_editor.xml b/app/src/main/res/layout/activity_manage_action_trigger_url.xml similarity index 90% rename from app/src/main/res/layout/activity_manage_action_url_editor.xml rename to app/src/main/res/layout/activity_manage_action_trigger_url.xml index c99365d8..0559e531 100644 --- a/app/src/main/res/layout/activity_manage_action_url_editor.xml +++ b/app/src/main/res/layout/activity_manage_action_trigger_url.xml @@ -2,17 +2,24 @@ + android:layout_margin="@dimen/default_margin" > + + WLAN Liste laden Es gibt keine bekannten WLANs auf Ihrem Gerät. Die Liste von WLANs auf Ihrem Gerät könnte verwendet werden, um zu ermitteln, an welchen Orten Sie waren. Deshalb ist die Positions-Berechtigung nötig, um die Liste dieser WLANs zu laden. Wenn Sie eines aus der Liste auswählen möchten, müssen Sie diese Berechtigung gewähren. Wenn nicht, können Sie immer noch eines manuell eingeben. + Diese Funktion öffnet NICHT den Browser, sondern löst die HTTP Anfrage im Hintergrund aus. Sie können das z.B. benutzen, um Befehle an Ihre Heimautomatisierung zu schicken. \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 46df4b80..0555bdef 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -408,4 +408,6 @@ Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dis algun recibidiendo saliendo + Esa función NO abre el browser, pero provoca el URL en el segundo plano. Per ejemplo puede usarlo a enviar ordenes a su automatización de casa. + No hay wifis conociendos en su disparador. \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 434c8cd5..a89d77d9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -70,7 +70,7 @@ End Save URL to trigger: - Variables: You can use the following variables. Upon triggering they will be replaced with the corresponding value on your device. Include the brackets in your text. [uniqueid] - Your device\'s unique id [serialnr] - Your device\'s serial number [latitude] - Your device\'s latitude [longitude] - Your device\'s longitude [phonenr] - Number of last incoming or outgoing call [d] - Day of the month, 2 digits with leading zeros [m] - Numeric representation of a month, with leading zeros [Y] - A full numeric representation of a year, 4 digits [h] - 12-hour format of an hour with leading zeros [H] - 24-hour format of an hour with leading zeros [i] - Minutes with leading zeros [s] - Seconds, with leading zeros [ms] - milliseconds [notificationTitle] - title of last notification [notificationText] - text of last notification + Variables:\nYou can use the following variables. Upon triggering they will be replaced with the corresponding value on your device. Include the brackets in your text.\n\n[uniqueid] - Your device\'s unique id\n[serialnr] - Your device\'s serial number\n[latitude] - Your device\'s latitude\n[longitude] - Your device\'s longitude\n[phonenr] - Number of last incoming or outgoing call\n[d] - Day of the month, 2 digits with leading zeros\n[m] - Numeric representation of a month, with leading zeros\n[Y] - A full numeric representation of a year, 4 digits\n[h] - 12-hour format of an hour with leading zeros\n[H] - 24-hour format of an hour with leading zeros\n[i] - Minutes with leading zeros\n[s] - Seconds, with leading zeros\n[ms] - milliseconds\n[notificationTitle] - title of last notification\n[notificationText] - text of last notification wifi Activating Deactivating @@ -674,4 +674,5 @@ Load wifi list The list of wifis your device has been connected to could be used to determine which places you have been to. That\'s why the location permission is required to load the list of wifis. If you want to be able to pick one from the list you need to grant that permission. If not you can still enter your wifi name manually. There are no known wifis on your device. + This feature does NOT open a browser, but triggers a URL in the background. You can use this e.g. to send commands to your home automation. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/105.txt b/fastlane/metadata/android/en-US/changelogs/105.txt new file mode 100644 index 00000000..abc73772 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/105.txt @@ -0,0 +1,3 @@ +* Activate wifi tethering doesn't require root anymore +* Italian translation updated +* Spanish translation updated \ No newline at end of file