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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 2b94090..61c4e80 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -738,4 +738,8 @@
If you have not used a send-sms action in this program before, Android may show an additional confirmation dialog, asking you to allow sending messages. You need to select the \"always allow\" checkbox and confirm if you want this action to work in the background. It\'s advised to run this rule manually once to provoke this confirmation dialog.
Exclude from battery optimization
Recommended for better reliability
+ Needs to be active
+ Check settings
+ profile %1$s is active
+ profile %1$s is not active
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/116.txt b/fastlane/metadata/android/en-US/changelogs/116.txt
index 0429069..ce9b078 100644
--- a/fastlane/metadata/android/en-US/changelogs/116.txt
+++ b/fastlane/metadata/android/en-US/changelogs/116.txt
@@ -1 +1,2 @@
-* Exclusion from battery optimization
\ No newline at end of file
+* Exclusion from battery optimization
+* Profiles can be used as trigger
\ No newline at end of file