From 5653a9c70e5905d895b9e387f5b73fe05d28e2cb Mon Sep 17 00:00:00 2001 From: jens Date: Tue, 4 Jan 2022 17:51:27 +0100 Subject: [PATCH] profile trigger --- app/src/apkFlavor/AndroidManifest.xml | 1 + .../java/com/jens/automation2/Rule.java | 5 +- .../jens/automation2/ActivityManageRule.java | 53 ++++++-- .../ActivityManageTriggerProfile.java | 116 ++++++++++++++++++ .../com/jens/automation2/Miscellaneous.java | 17 +++ .../java/com/jens/automation2/Profile.java | 20 ++- .../java/com/jens/automation2/Trigger.java | 56 ++++++--- .../activity_manage_trigger_profile.xml | 66 ++++++++++ app/src/main/res/values/strings.xml | 4 + .../metadata/android/en-US/changelogs/116.txt | 3 +- 10 files changed, 313 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/com/jens/automation2/ActivityManageTriggerProfile.java create mode 100644 app/src/main/res/layout/activity_manage_trigger_profile.xml diff --git a/app/src/apkFlavor/AndroidManifest.xml b/app/src/apkFlavor/AndroidManifest.xml index 0f37505..5ac27c1 100644 --- a/app/src/apkFlavor/AndroidManifest.xml +++ b/app/src/apkFlavor/AndroidManifest.xml @@ -147,6 +147,7 @@ + diff --git a/app/src/apkFlavor/java/com/jens/automation2/Rule.java b/app/src/apkFlavor/java/com/jens/automation2/Rule.java index c828fbc..ec07025 100644 --- a/app/src/apkFlavor/java/com/jens/automation2/Rule.java +++ b/app/src/apkFlavor/java/com/jens/automation2/Rule.java @@ -16,6 +16,7 @@ import java.sql.Time; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.List; public class Rule implements Comparable @@ -23,9 +24,9 @@ public class Rule implements Comparable private static ArrayList ruleCollection = new ArrayList(); public static boolean isAnyRuleActive = false; - private static ArrayList ruleRunHistory = new ArrayList(); + private static List ruleRunHistory = new ArrayList(); - public static ArrayList getRuleRunHistory() + public static List getRuleRunHistory() { return ruleRunHistory; } diff --git a/app/src/main/java/com/jens/automation2/ActivityManageRule.java b/app/src/main/java/com/jens/automation2/ActivityManageRule.java index d63211b..def6c39 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageRule.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageRule.java @@ -3,7 +3,6 @@ package com.jens.automation2; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; -import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; @@ -14,6 +13,7 @@ import android.os.Build; import android.os.Bundle; import android.text.InputType; import android.text.util.Linkify; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; @@ -50,6 +50,7 @@ public class ActivityManageRule extends Activity { final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver"; public final static String intentNameTriggerParameter1 = "triggerParameter1"; + public final static String intentNameTriggerParameter2 = "triggerParameter2"; public final static String intentNameActionParameter1 = "actionParameter1"; public final static String intentNameActionParameter2 = "actionParameter2"; @@ -106,6 +107,8 @@ public class ActivityManageRule extends Activity final static int requestCodeActionPlaySoundEdit = 502; final static int requestCodeTriggerPhoneCallAdd = 601; final static int requestCodeTriggerPhoneCallEdit = 602; + final static int requestCodeTriggerProfileAdd = 603; + final static int requestCodeTriggerProfileEdit = 604; final static int requestCodeTriggerWifiAdd = 723; final static int requestCodeTriggerWifiEdit = 724; final static int requestCodeActionSendTextMessageAdd = 5001; @@ -271,6 +274,12 @@ public class ActivityManageRule extends Activity phoneCallEditor.putExtra("edit", true); startActivityForResult(phoneCallEditor, requestCodeTriggerPhoneCallEdit); break; + case profileActive: + Intent profileActiveEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerProfile.class); + profileActiveEditor.putExtra(ActivityManageRule.intentNameTriggerParameter1, selectedTrigger.getTriggerParameter()); + profileActiveEditor.putExtra(ActivityManageRule.intentNameTriggerParameter2, selectedTrigger.getTriggerParameter2()); + startActivityForResult(profileActiveEditor, requestCodeTriggerProfileEdit); + break; case wifiConnection: Intent wifiEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerWifi.class); wifiEditor.putExtra("edit", true); @@ -285,7 +294,7 @@ public class ActivityManageRule extends Activity startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit); break; default: - break; + break; } } }); @@ -496,6 +505,8 @@ public class ActivityManageRule extends Activity items.add(new Item(typesLong[i].toString(), R.drawable.notification)); else if(types[i].toString().equals(Trigger_Enum.deviceOrientation.toString())) items.add(new Item(typesLong[i].toString(), R.drawable.smartphone)); + else if(types[i].toString().equals(Trigger_Enum.profileActive.toString())) + items.add(new Item(typesLong[i].toString(), R.drawable.sound)); else items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); } @@ -568,7 +579,6 @@ public class ActivityManageRule extends Activity Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class); startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd); return; -// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; } else if(triggerType == Trigger_Enum.deviceOrientation) { @@ -576,10 +586,7 @@ public class ActivityManageRule extends Activity Intent devicePositionTriggerEditor = new Intent(myContext, ActivityManageTriggerDeviceOrientation.class); startActivityForResult(devicePositionTriggerEditor, requestCodeTriggerDeviceOrientationAdd); return; -// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; } -// else if(triggerType == Trigger_Enum.wifiConnection) -// booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)}; 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) @@ -599,7 +606,13 @@ public class ActivityManageRule extends Activity Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class); startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd); return; -// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; + } + else if(triggerType == Trigger_Enum.profileActive) + { + newTrigger.setTriggerType(Trigger_Enum.profileActive); + Intent profileTriggerEditor = new Intent(myContext, ActivityManageTriggerProfile.class); + startActivityForResult(profileTriggerEditor, requestCodeTriggerProfileAdd); + return; } else if(triggerType == Trigger_Enum.activityDetection) { @@ -622,7 +635,7 @@ public class ActivityManageRule extends Activity } catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); + Miscellaneous.logEvent("w", "ActivityDetection", "Either play services are not available or the ActivityDetection classes are not. " + Log.getStackTraceString(e), 4); } return; } @@ -1428,6 +1441,30 @@ public class ActivityManageRule extends Activity this.refreshTriggerList(); } } + else if(requestCode == requestCodeTriggerProfileAdd) + { + if(resultCode == RESULT_OK) + { + newTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true)); + newTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2)); + newTrigger.setParentRule(ruleToEdit); + ruleToEdit.getTriggerSet().add(newTrigger); + this.refreshTriggerList(); + } + } + else if(requestCode == requestCodeTriggerProfileEdit) + { + if(resultCode == RESULT_OK) + { + Trigger editedTrigger = new Trigger(); + editedTrigger.setTriggerType(Trigger_Enum.profileActive); + editedTrigger.setTriggerParameter(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true)); + editedTrigger.setTriggerParameter2(data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2)); + editedTrigger.setParentRule(ruleToEdit); + ruleToEdit.getTriggerSet().set(editIndex, editedTrigger); + this.refreshTriggerList(); + } + } } protected AlertDialog getActionTypeDialog() diff --git a/app/src/main/java/com/jens/automation2/ActivityManageTriggerProfile.java b/app/src/main/java/com/jens/automation2/ActivityManageTriggerProfile.java new file mode 100644 index 0000000..870b8ec --- /dev/null +++ b/app/src/main/java/com/jens/automation2/ActivityManageTriggerProfile.java @@ -0,0 +1,116 @@ +package com.jens.automation2; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.Spinner; +import android.widget.Toast; + +import androidx.annotation.Nullable; + +import java.util.List; + +public class ActivityManageTriggerProfile extends Activity +{ + public static final String profileFieldName = "profileName"; + + boolean editMode = false; + + Button bSaveTriggerProfile; + Spinner spinnerProfiles; + CheckBox chkProfileActive, chkProfileCheckSettings; + + ArrayAdapter profileSpinnerAdapter; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_manage_trigger_profile); + + bSaveTriggerProfile = (Button)findViewById(R.id.bSaveTriggerProfile); + spinnerProfiles = (Spinner)findViewById(R.id.spinnerProfiles); + chkProfileActive = (CheckBox)findViewById(R.id.chkProfileActive); + chkProfileCheckSettings = (CheckBox)findViewById(R.id.chkProfileCheckSettings); + + try + { + profileSpinnerAdapter = new ArrayAdapter(this, R.layout.text_view_for_poi_listview_mediumtextsize, Profile.getProfileCollection()); + loadProfileItems(); + } + catch (Exception e) + { + Miscellaneous.logEvent("w", "ActivityManageTriggerProfile", Log.getStackTraceString(e), 1); + } + + if(getIntent().hasExtra(ActivityManageRule.intentNameTriggerParameter2)) + { + editMode = true; + try + { + String values[] = getIntent().getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split); + if(values.length >= 2) + { + boolean active = getIntent().getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true); + chkProfileActive.setChecked(active); + + boolean checkSettings = Boolean.parseBoolean(values[0]); + chkProfileCheckSettings.setChecked(checkSettings); + + String profileName = values[1]; + + List profileList = Profile.getProfileCollection(); + for(int i = 0; i < profileList.size(); i++) + { + if(profileList.get(i).getName().equals(profileName)) + { + spinnerProfiles.setSelection(i); + break; + } + } + } + } + catch(Exception e) + { + Toast.makeText(ActivityManageTriggerProfile.this, getResources().getString(R.string.triggerWrong), Toast.LENGTH_SHORT).show(); + Miscellaneous.logEvent("e", "ActivityManageTriggerProfile", "There\'s something wrong with parameters. Content: " + getIntent().getStringExtra(ActivityManageRule.intentNameActionParameter2) + ", " + Log.getStackTraceString(e), 1); + } + } + + bSaveTriggerProfile.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + Intent returnData = new Intent(); + returnData.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkProfileActive.isChecked()); + returnData.putExtra(ActivityManageRule.intentNameTriggerParameter2, + spinnerProfiles.getSelectedItem().toString() + Trigger.triggerParameter2Split + + chkProfileCheckSettings.isChecked()); + + setResult(RESULT_OK, returnData); + finish(); + } + }); + } + + private void loadProfileItems() + { + try + { + if(spinnerProfiles.getAdapter() == null) + spinnerProfiles.setAdapter(profileSpinnerAdapter); + + profileSpinnerAdapter.notifyDataSetChanged(); + } + catch(NullPointerException e) + { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/jens/automation2/Miscellaneous.java b/app/src/main/java/com/jens/automation2/Miscellaneous.java index 1a8a18f..5f8c28b 100644 --- a/app/src/main/java/com/jens/automation2/Miscellaneous.java +++ b/app/src/main/java/com/jens/automation2/Miscellaneous.java @@ -1065,6 +1065,23 @@ public class Miscellaneous extends Service return ""; } + public static String explode(String glue, String[] inputArray) + { + if(inputArray != null) + { + StringBuilder builder = new StringBuilder(); + for (String s : inputArray) + builder.append(s + glue); + + if (builder.length() > 0) + builder.delete(builder.length() - glue.length(), builder.length()); + + return builder.toString(); + } + else + return ""; + } + public static boolean isGooglePlayInstalled(Context context) { // return false; diff --git a/app/src/main/java/com/jens/automation2/Profile.java b/app/src/main/java/com/jens/automation2/Profile.java index 1a8424f..99ab5f1 100644 --- a/app/src/main/java/com/jens/automation2/Profile.java +++ b/app/src/main/java/com/jens/automation2/Profile.java @@ -14,10 +14,12 @@ import com.jens.automation2.Action.Action_Enum; import java.io.File; import java.util.ArrayList; +import java.util.List; public class Profile implements Comparable { - protected static ArrayList profileCollection = new ArrayList(); + protected static List profileCollection = new ArrayList(); + protected static List profileActivationHistory = new ArrayList<>(); protected String name; protected String oldName; @@ -267,7 +269,7 @@ public class Profile implements Comparable return hapticFeedback; } - public static ArrayList getProfileCollection() + public static List getProfileCollection() { return profileCollection; } @@ -395,6 +397,18 @@ public class Profile implements Comparable { for(Rule oneRule : rulesThatReferenceMe) { + for(Trigger oneTrigger : oneRule.getTriggerSet()) + { + if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.profileActive) + { + String[] parts = oneTrigger.getTriggerParameter2().split(Trigger.triggerParameter2Split); + parts[1] = this.name; + + oneTrigger.setTriggerParameter2(Miscellaneous.explode(Trigger.triggerParameter2Split, parts)); + // We don't need to save the file. This will happen anyway in PointOfInterest.writePoisToFile() below. + } + } + for(Action oneAction : oneRule.getActionSet()) { if(oneAction.getAction() == Action_Enum.changeSoundProfile) @@ -463,6 +477,8 @@ public class Profile implements Comparable { Miscellaneous.logEvent("i", "Profile " + this.getName(), String.format(context.getResources().getString(R.string.profileActivate), this.getName()), 3); + profileActivationHistory.add(this); + AutomationService.getInstance().checkLockSoundChangesTimeElapsed(); if(AutomationService.getInstance().getLockSoundChangesEnd() == null) diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index 8b24e1f..3251831 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -117,6 +117,10 @@ public class Trigger if(!getParentRule().checkActivityDetection(this)) result = false; break; + case profileActive: + if(!checkProfileActive()) + result = false; + break; default: break; } @@ -273,6 +277,34 @@ public class Trigger return true; } + boolean checkProfileActive() + { + try + { + String demandedProfileName = getTriggerParameter2().split(Trigger.triggerParameter2Split)[0]; + Profile lastProfile = null; + + if(Profile.profileActivationHistory.size() > 0) + { + lastProfile = Profile.profileActivationHistory.get(Profile.profileActivationHistory.size() - 1); + + if (getTriggerParameter()) + return demandedProfileName.equals(lastProfile.getName()); + else + return !demandedProfileName.equals(lastProfile.getName()); + } + else + return !getTriggerParameter(); + } + catch(Exception e) + { + Miscellaneous.logEvent("w", "Trigger", "Error checking profile trigger.", 4); + } + + return false; + } + + boolean checkDeviceOrientation() { String deviceOrientationPieces[] = getTriggerParameter2().split(Trigger.triggerParameter2Split); @@ -986,7 +1018,7 @@ 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, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy + pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy public String getFullName(Context context) { @@ -1028,6 +1060,8 @@ public class Trigger 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); default: return "Unknown"; } @@ -1373,21 +1407,7 @@ public class Trigger if (ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION")) { // This type doesn't have an activate/deactivate equivalent, at least not yet. -// try -// { returnString.append(Miscellaneous.runMethodReflective(ActivityManageRule.activityDetectionClassPath, "getDescription", new Object[]{getActivityDetectionType()})); -// for(Method method : activityDetection.getMethods()) -// { -// if(method.getName().equalsIgnoreCase("getDescription")) -// returnString.append(method.invoke()); -//// returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivity) + " " + activityDetection.getDescription(getActivityDetectionType())); -// } -// } -// catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) -// { -// e.printStackTrace(); -// } - } else returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.featureNotInFdroidVersion)); @@ -1500,6 +1520,12 @@ public class Trigger case deviceOrientation: returnString.append(Miscellaneous.getAnyContext().getString(R.string.deviceIsInCertainOrientation)); break; + case profileActive: + if(triggerParameter) + returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.profileActive), getTriggerParameter2().split(Trigger.triggerParameter2Split)[0])); + else + returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.profileNotActive), getTriggerParameter2().split(Trigger.triggerParameter2Split)[0])); + break; default: returnString.append("error"); break; diff --git a/app/src/main/res/layout/activity_manage_trigger_profile.xml b/app/src/main/res/layout/activity_manage_trigger_profile.xml new file mode 100644 index 0000000..ee64ae1 --- /dev/null +++ b/app/src/main/res/layout/activity_manage_trigger_profile.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +