diff --git a/app/src/main/java/com/jens/automation2/Action.java b/app/src/main/java/com/jens/automation2/Action.java index 0fe3587..2e15445 100644 --- a/app/src/main/java/com/jens/automation2/Action.java +++ b/app/src/main/java/com/jens/automation2/Action.java @@ -41,6 +41,7 @@ public class Action setDataConnection, speakText, playMusic, + controlMediaPlayback, setScreenBrightness, playSound, vibrate, @@ -104,6 +105,8 @@ public class Action return context.getResources().getString(R.string.actionSpeakText); case playMusic: return context.getResources().getString(R.string.actionPlayMusic); + case controlMediaPlayback: + return context.getResources().getString(R.string.actionMediaControl); case playSound: return context.getResources().getString(R.string.playSound); case sendTextMessage: @@ -160,7 +163,6 @@ public class Action { StringBuilder returnString = new StringBuilder(); - try { switch (getAction()) @@ -225,6 +227,9 @@ public class Action case playMusic: returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic)); break; + case controlMediaPlayback: + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionMediaControl)); + break; case sendTextMessage: returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage)); break; @@ -311,6 +316,27 @@ public class Action returnString.append(", " + Miscellaneous.getAnyContext().getResources().getString(R.string.ifString) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.text) + " " + Trigger.getMatchString(parts[3]) + " " + parts[4]); } + else if(this.getAction().equals(Action_Enum.controlMediaPlayback)) + { + switch (this.getParameter2()) + { + case "0": + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playPause)); + break; + case "1": + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.play)); + break; + case "2": + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.pause)); + break; + case "3": + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.previous)); + break; + case "4": + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.next)); + break; + } + } else if (parameter2 != null && parameter2.length() > 0) returnString.append(": " + parameter2.replace(Action.actionParameter2Split, "; ")); } diff --git a/app/src/main/java/com/jens/automation2/Actions.java b/app/src/main/java/com/jens/automation2/Actions.java index 07f8544..e2d1e50 100644 --- a/app/src/main/java/com/jens/automation2/Actions.java +++ b/app/src/main/java/com/jens/automation2/Actions.java @@ -1452,23 +1452,7 @@ public class Actions 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); - return true; - // } - // else - // { - // if(playMusicIntent != null) - // { - // context.stopService(playMusicIntent); - // } - // } - - // return false; } catch (ActivityNotFoundException e) { @@ -1484,6 +1468,38 @@ public class Actions } } + public static boolean controlMediaPlayback(Context context, int command) + { + AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + + if (mAudioManager.isMusicActive()) { + + Intent.CATEGORY_APP_MUSIC + Intent i = new Intent("com.android.music.musicservicecommand"); + + i.putExtra("command", "pause"); + + switch(command) + { + public static final String SERVICECMD = "com.android.music.musicservicecommand"; + public static final String CMDNAME = "command"; + + public static final String CMDSTOP = "stop"; + public static final String CMDPAUSE = "pause"; + public static final String CMDPREVIOUS = "previous"; + public static final String CMDNEXT = "next"; + + case 0: + i.putExtra("command", "togglepause"); + break; + case 2: + i.putExtra("command", "pause"); + break; + } + context.this.sendBroadcast(i); + } + } + private String getTransactionCode() { try diff --git a/app/src/main/java/com/jens/automation2/ActivityManageRule.java b/app/src/main/java/com/jens/automation2/ActivityManageRule.java index 6ff1f5a..936ca55 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageRule.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageRule.java @@ -65,14 +65,11 @@ public class ActivityManageRule extends Activity static ProgressDialog progressDialog = null; static Trigger_Enum triggerType; - static boolean triggerParameter; static PointOfInterest triggerPoi; static String triggerProcess; static int triggerBattery; static double triggerSpeed; static double triggerNoise; - static TimeFrame triggerTimeFrame; - static String triggerWifiName; static Rule ruleToEdit; static boolean newRule; @@ -604,7 +601,9 @@ public class ActivityManageRule extends Activity return; } else if(triggerType == Trigger_Enum.process_started_stopped) + { booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; + } else if(triggerType == Trigger_Enum.notification) { newTrigger.setTriggerType(Trigger_Enum.notification); @@ -700,6 +699,9 @@ public class ActivityManageRule extends Activity } else getTriggerParameterDialog(context, booleanChoices).show(); + + if(triggerType.equals(Trigger_Enum.process_started_stopped)) + Miscellaneous.messageBox(getResources().getString(R.string.info), String.format(getResources().getString(R.string.featureCeasedToWorkLastWorkingAndroidVersion), "7"), ActivityManageRule.this).show(); } }); @@ -1612,6 +1614,8 @@ public class ActivityManageRule extends Activity items.add(new Item(typesLong[i].toString(), R.drawable.talking)); else if(types[i].toString().equals(Action_Enum.playMusic.toString())) items.add(new Item(typesLong[i].toString(), R.drawable.tune)); + else if(types[i].toString().equals(Action_Enum.controlMediaPlayback.toString())) + items.add(new Item(typesLong[i].toString(), R.drawable.tune)); else if(types[i].toString().equals(Action_Enum.setScreenBrightness.toString())) items.add(new Item(typesLong[i].toString(), R.drawable.brightness)); else if(types[i].toString().equals(Action_Enum.playSound.toString())) @@ -1778,6 +1782,11 @@ public class ActivityManageRule extends Activity ruleToEdit.getActionSet().add(newAction); refreshActionList(); } + else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.controlMediaPlayback.toString())) + { + newAction.setAction(Action_Enum.controlMediaPlayback); + getActionControlMediaPlayback(ActivityManageRule.this).show(); + } else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.vibrate.toString())) { newAction.setAction(Action_Enum.vibrate); @@ -2019,8 +2028,29 @@ public class ActivityManageRule extends Activity AlertDialog alertDialog = alertDialogBuilder.create(); return alertDialog; - } - + } + + private AlertDialog getActionControlMediaPlayback(final Context myContext) + { + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); + alertDialogBuilder.setTitle(myContext.getResources().getString(R.string.selectCommand)); + final String choices[] = { myContext.getString(R.string.playPause), myContext.getString(R.string.play), myContext.getString(R.string.pause), myContext.getString(R.string.previous), myContext.getString(R.string.next) }; + alertDialogBuilder.setItems(choices, new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) + { + newAction.setParameter2(String.valueOf(which)); + + ruleToEdit.getActionSet().add(newAction); + refreshActionList(); + } + }); + AlertDialog alertDialog = alertDialogBuilder.create(); + + return alertDialog; + } + protected void refreshTriggerList() { Miscellaneous.logEvent("i", "ListView", "Attempting to update TriggerListView", 4); diff --git a/app/src/main/java/com/jens/automation2/ActivityPermissions.java b/app/src/main/java/com/jens/automation2/ActivityPermissions.java index b1fed68..fd03c59 100644 --- a/app/src/main/java/com/jens/automation2/ActivityPermissions.java +++ b/app/src/main/java/com/jens/automation2/ActivityPermissions.java @@ -358,9 +358,10 @@ public class ActivityPermissions extends Activity for (Rule rule : Rule.getRuleCollection()) { for (String singlePermission : getPermissionsForRule(rule)) + { if (!havePermission(singlePermission, workingContext)) { - if( + if ( singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION) || @@ -372,14 +373,15 @@ public class ActivityPermissions extends Activity if (!Miscellaneous.googleToBlameForLocation(true)) addToArrayListUnique(singlePermission, requiredPermissions); } - else if(singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection)) + else if (singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection)) { - if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor")) + if (!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor")) addToArrayListUnique(singlePermission, requiredPermissions); } else addToArrayListUnique(singlePermission, requiredPermissions); } + } } } @@ -527,6 +529,9 @@ public class ActivityPermissions extends Activity break; case playMusic: break; + case controlMediaPlayback: + addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions); + break; case sendTextMessage: addToArrayListUnique(Manifest.permission.SEND_SMS, requiredPermissions); getPermissionsForVariablesInUse(action.getParameter2(), requiredPermissions); diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index bf5bf91..cf06603 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -37,6 +37,60 @@ import java.util.Date; public class Trigger { + public enum Trigger_Enum { + pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, screenState, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy + + public String getFullName(Context context) + { + switch(this) + { + case pointOfInterest: + return context.getResources().getString(R.string.triggerPointOfInterest); + case timeFrame: + return context.getResources().getString(R.string.triggerTimeFrame); + case charging: + return context.getResources().getString(R.string.triggerCharging); + case batteryLevel: + return context.getResources().getString(R.string.batteryLevel); + case usb_host_connection: + return context.getResources().getString(R.string.triggerUsb_host_connection); + case speed: + return context.getResources().getString(R.string.triggerSpeed); + case noiseLevel: + return context.getResources().getString(R.string.triggerNoiseLevel); + case wifiConnection: + return context.getResources().getString(R.string.wifiConnection); + case process_started_stopped: + return context.getResources().getString(R.string.anotherAppIsRunning); + case airplaneMode: + return context.getResources().getString(R.string.airplaneMode); + case roaming: + return context.getResources().getString(R.string.roaming); + case phoneCall: + return context.getResources().getString(R.string.phoneCall); + case nfcTag: + return context.getResources().getString(R.string.nfcTag); + case activityDetection: + return context.getResources().getString(R.string.activityDetection); + case bluetoothConnection: + return context.getResources().getString(R.string.bluetoothConnection); + case headsetPlugged: + return context.getResources().getString(R.string.triggerHeadsetPlugged); + case notification: + return context.getResources().getString(R.string.notification); + case deviceOrientation: + return context.getResources().getString(R.string.deviceOrientation); + case profileActive: + return context.getResources().getString(R.string.profile); + case screenState: + return context.getResources().getString(R.string.screenState); + default: + return "Unknown"; + } + } + + }; + Rule parentRule = null; Calendar lastTimeNotApplied = null; @@ -974,8 +1028,6 @@ public class Trigger calSet.set(Calendar.SECOND, 0); calSet.set(Calendar.MILLISECOND, 0); -// if(this.applies(null)) -// { // If the starting time is a day ahead remove 1 day. if(calSet.getTimeInMillis() > now.getTimeInMillis()) calSet.add(Calendar.DAY_OF_MONTH, -1); @@ -986,15 +1038,7 @@ public class Trigger Calendar calSchedule = Calendar.getInstance(); calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000); - /* - * Das war mal aktiviert. Allerdings: Die ganze Funktion liefert zurück, wenn die Regel NOCH nicht - * zutrifft, aber wir z.B. gleich den zeitlichen Bereich betreten. - */ -// if(trigger.checkDateTime(calSchedule.getTime(), false)) -// { return calSchedule; -// } -// } } else Miscellaneous.logEvent("i", "Trigger", "Trigger " + trigger.toString() + " is not executed repeatedly.", 5); @@ -1027,75 +1071,14 @@ public class Trigger return false; } - /* - * Can be several things: - * -PointOfInterest - * -TimeFrame - * -Event (like charging, cable plugged, etc.) - */ - - public enum Trigger_Enum { - pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, screenState, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy - - public String getFullName(Context context) - { - switch(this) - { - case pointOfInterest: - return context.getResources().getString(R.string.triggerPointOfInterest); - case timeFrame: - return context.getResources().getString(R.string.triggerTimeFrame); - case charging: - return context.getResources().getString(R.string.triggerCharging); - case batteryLevel: - return context.getResources().getString(R.string.batteryLevel); - case usb_host_connection: - return context.getResources().getString(R.string.triggerUsb_host_connection); - case speed: - return context.getResources().getString(R.string.triggerSpeed); - case noiseLevel: - return context.getResources().getString(R.string.triggerNoiseLevel); - case wifiConnection: - return context.getResources().getString(R.string.wifiConnection); - case process_started_stopped: - return context.getResources().getString(R.string.anotherAppIsRunning); - case airplaneMode: - return context.getResources().getString(R.string.airplaneMode); - case roaming: - return context.getResources().getString(R.string.roaming); - case phoneCall: - return context.getResources().getString(R.string.phoneCall); - case nfcTag: - return context.getResources().getString(R.string.nfcTag); - case activityDetection: - return context.getResources().getString(R.string.activityDetection); - case bluetoothConnection: - return context.getResources().getString(R.string.bluetoothConnection); - case headsetPlugged: - return context.getResources().getString(R.string.triggerHeadsetPlugged); - case notification: - return context.getResources().getString(R.string.notification); - case deviceOrientation: - return context.getResources().getString(R.string.deviceOrientation); - case profileActive: - return context.getResources().getString(R.string.profile); - case screenState: - return context.getResources().getString(R.string.screenState); - default: - return "Unknown"; - } - } - - }; - - private boolean triggerParameter; //if true->started event, if false->stopped - private String triggerParameter2; + boolean triggerParameter; //if true->started event, if false->stopped + String triggerParameter2; public static final String triggerParameter2Split = "tp2split"; - private Trigger_Enum triggerType = null; - private PointOfInterest pointOfInterest = null; - private TimeFrame timeFrame; + Trigger_Enum triggerType = null; + PointOfInterest pointOfInterest = null; + TimeFrame timeFrame; public static String triggerPhoneCallStateRinging = "ringing"; public static String triggerPhoneCallStateStarted = "started"; @@ -1105,17 +1088,17 @@ public class Trigger public static String triggerPhoneCallDirectionAny = "any"; public static String triggerPhoneCallNumberAny = "any"; - private double speed; //km/h - private long noiseLevelDb; - private String processName = null; - private int batteryLevel; - private int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing - private String phoneNumber = null; - private String nfcTagId = null; - private String bluetoothEvent = null; - private String bluetoothDeviceAddress = null; - private int activityDetectionType = -1; - private int headphoneType = -1; + double speed; //km/h + long noiseLevelDb; + String processName = null; + int batteryLevel; + int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing + String phoneNumber = null; + String nfcTagId = null; + String bluetoothEvent = null; + String bluetoothDeviceAddress = null; + int activityDetectionType = -1; + int headphoneType = -1; public int getHeadphoneType() { diff --git a/app/src/main/java/com/jens/automation2/XmlFileInterface.java b/app/src/main/java/com/jens/automation2/XmlFileInterface.java index 946e223..b7d698a 100644 --- a/app/src/main/java/com/jens/automation2/XmlFileInterface.java +++ b/app/src/main/java/com/jens/automation2/XmlFileInterface.java @@ -1160,12 +1160,17 @@ public class XmlFileInterface newAction.setAction(Action_Enum.disableScreenRotation); else if(actionNameString.equals("disableScreenRotation")) newAction.setAction(Action_Enum.disableScreenRotation); + else if(actionNameString.equals("playMusic")) + { + newAction.setAction(Action_Enum.controlMediaPlayback); + newAction.setParameter2("1"); + } else if(actionNameString.equals("wakeupDevice")) { newAction.setAction(Action_Enum.turnScreenOnOrOff); newAction.setParameter1(true); } - // *** deprecated + // *** :deprecated else newAction.setAction(Action_Enum.valueOf(actionNameString)); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 273447c..c71a413 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -774,4 +774,12 @@ unlocked Select desired state Screen state + Because of Google\'s infinite wisdom, the last Android version this feature is known to work on is %1$s. You can configure it, but it probably will not have any effect. + Control media playback + Select command + toggle play/pause + play + pause + previous + next \ No newline at end of file