profile trigger

This commit is contained in:
jens 2022-01-04 17:51:27 +01:00
parent 8c6331237d
commit 5653a9c70e
10 changed files with 313 additions and 28 deletions

View File

@ -147,6 +147,7 @@
<activity android:name=".ActivityDisplayLongMessage" /> <activity android:name=".ActivityDisplayLongMessage" />
<activity android:name=".ActivityManageActionSendTextMessage" /> <activity android:name=".ActivityManageActionSendTextMessage" />
<activity android:name=".ActivityManageActionPlaySound" /> <activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerProfile" />
<activity android:name=".ActivityManageTriggerTimeFrame" /> <activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" /> <activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityManageTriggerPhoneCall" /> <activity android:name=".ActivityManageTriggerPhoneCall" />

View File

@ -16,6 +16,7 @@ import java.sql.Time;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List;
public class Rule implements Comparable<Rule> public class Rule implements Comparable<Rule>
@ -23,9 +24,9 @@ public class Rule implements Comparable<Rule>
private static ArrayList<Rule> ruleCollection = new ArrayList<Rule>(); private static ArrayList<Rule> ruleCollection = new ArrayList<Rule>();
public static boolean isAnyRuleActive = false; public static boolean isAnyRuleActive = false;
private static ArrayList<Rule> ruleRunHistory = new ArrayList<Rule>(); private static List<Rule> ruleRunHistory = new ArrayList<Rule>();
public static ArrayList<Rule> getRuleRunHistory() public static List<Rule> getRuleRunHistory()
{ {
return ruleRunHistory; return ruleRunHistory;
} }

View File

@ -3,7 +3,6 @@ package com.jens.automation2;
import android.Manifest; import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -14,6 +13,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.InputType; import android.text.InputType;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -50,6 +50,7 @@ public class ActivityManageRule extends Activity
{ {
final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver"; final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver";
public final static String intentNameTriggerParameter1 = "triggerParameter1"; public final static String intentNameTriggerParameter1 = "triggerParameter1";
public final static String intentNameTriggerParameter2 = "triggerParameter2";
public final static String intentNameActionParameter1 = "actionParameter1"; public final static String intentNameActionParameter1 = "actionParameter1";
public final static String intentNameActionParameter2 = "actionParameter2"; public final static String intentNameActionParameter2 = "actionParameter2";
@ -106,6 +107,8 @@ public class ActivityManageRule extends Activity
final static int requestCodeActionPlaySoundEdit = 502; final static int requestCodeActionPlaySoundEdit = 502;
final static int requestCodeTriggerPhoneCallAdd = 601; final static int requestCodeTriggerPhoneCallAdd = 601;
final static int requestCodeTriggerPhoneCallEdit = 602; final static int requestCodeTriggerPhoneCallEdit = 602;
final static int requestCodeTriggerProfileAdd = 603;
final static int requestCodeTriggerProfileEdit = 604;
final static int requestCodeTriggerWifiAdd = 723; final static int requestCodeTriggerWifiAdd = 723;
final static int requestCodeTriggerWifiEdit = 724; final static int requestCodeTriggerWifiEdit = 724;
final static int requestCodeActionSendTextMessageAdd = 5001; final static int requestCodeActionSendTextMessageAdd = 5001;
@ -271,6 +274,12 @@ public class ActivityManageRule extends Activity
phoneCallEditor.putExtra("edit", true); phoneCallEditor.putExtra("edit", true);
startActivityForResult(phoneCallEditor, requestCodeTriggerPhoneCallEdit); startActivityForResult(phoneCallEditor, requestCodeTriggerPhoneCallEdit);
break; 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: case wifiConnection:
Intent wifiEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerWifi.class); Intent wifiEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerWifi.class);
wifiEditor.putExtra("edit", true); wifiEditor.putExtra("edit", true);
@ -285,7 +294,7 @@ public class ActivityManageRule extends Activity
startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit); startActivityForResult(devicePositionEditor, requestCodeTriggerDeviceOrientationEdit);
break; break;
default: default:
break; break;
} }
} }
}); });
@ -496,6 +505,8 @@ public class ActivityManageRule extends Activity
items.add(new Item(typesLong[i].toString(), R.drawable.notification)); items.add(new Item(typesLong[i].toString(), R.drawable.notification));
else if(types[i].toString().equals(Trigger_Enum.deviceOrientation.toString())) else if(types[i].toString().equals(Trigger_Enum.deviceOrientation.toString()))
items.add(new Item(typesLong[i].toString(), R.drawable.smartphone)); 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 else
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); 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); Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd); startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
return; return;
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
} }
else if(triggerType == Trigger_Enum.deviceOrientation) else if(triggerType == Trigger_Enum.deviceOrientation)
{ {
@ -576,10 +586,7 @@ public class ActivityManageRule extends Activity
Intent devicePositionTriggerEditor = new Intent(myContext, ActivityManageTriggerDeviceOrientation.class); Intent devicePositionTriggerEditor = new Intent(myContext, ActivityManageTriggerDeviceOrientation.class);
startActivityForResult(devicePositionTriggerEditor, requestCodeTriggerDeviceOrientationAdd); startActivityForResult(devicePositionTriggerEditor, requestCodeTriggerDeviceOrientationAdd);
return; 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) else if(triggerType == Trigger_Enum.process_started_stopped)
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
else if(triggerType == Trigger_Enum.notification) else if(triggerType == Trigger_Enum.notification)
@ -599,7 +606,13 @@ public class ActivityManageRule extends Activity
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class); Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd); startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
return; 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) else if(triggerType == Trigger_Enum.activityDetection)
{ {
@ -622,7 +635,7 @@ public class ActivityManageRule extends Activity
} }
catch (IllegalAccessException | InvocationTargetException e) 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; return;
} }
@ -1428,6 +1441,30 @@ public class ActivityManageRule extends Activity
this.refreshTriggerList(); 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() protected AlertDialog getActionTypeDialog()

View File

@ -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<Profile> 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<Profile>(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<Profile> 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();
}
}
}

View File

@ -1065,6 +1065,23 @@ public class Miscellaneous extends Service
return ""; 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) public static boolean isGooglePlayInstalled(Context context)
{ {
// return false; // return false;

View File

@ -14,10 +14,12 @@ import com.jens.automation2.Action.Action_Enum;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class Profile implements Comparable<Profile> public class Profile implements Comparable<Profile>
{ {
protected static ArrayList<Profile> profileCollection = new ArrayList<Profile>(); protected static List<Profile> profileCollection = new ArrayList<Profile>();
protected static List<Profile> profileActivationHistory = new ArrayList<>();
protected String name; protected String name;
protected String oldName; protected String oldName;
@ -267,7 +269,7 @@ public class Profile implements Comparable<Profile>
return hapticFeedback; return hapticFeedback;
} }
public static ArrayList<Profile> getProfileCollection() public static List<Profile> getProfileCollection()
{ {
return profileCollection; return profileCollection;
} }
@ -395,6 +397,18 @@ public class Profile implements Comparable<Profile>
{ {
for(Rule oneRule : rulesThatReferenceMe) 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()) for(Action oneAction : oneRule.getActionSet())
{ {
if(oneAction.getAction() == Action_Enum.changeSoundProfile) if(oneAction.getAction() == Action_Enum.changeSoundProfile)
@ -463,6 +477,8 @@ public class Profile implements Comparable<Profile>
{ {
Miscellaneous.logEvent("i", "Profile " + this.getName(), String.format(context.getResources().getString(R.string.profileActivate), this.getName()), 3); Miscellaneous.logEvent("i", "Profile " + this.getName(), String.format(context.getResources().getString(R.string.profileActivate), this.getName()), 3);
profileActivationHistory.add(this);
AutomationService.getInstance().checkLockSoundChangesTimeElapsed(); AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
if(AutomationService.getInstance().getLockSoundChangesEnd() == null) if(AutomationService.getInstance().getLockSoundChangesEnd() == null)

View File

@ -117,6 +117,10 @@ public class Trigger
if(!getParentRule().checkActivityDetection(this)) if(!getParentRule().checkActivityDetection(this))
result = false; result = false;
break; break;
case profileActive:
if(!checkProfileActive())
result = false;
break;
default: default:
break; break;
} }
@ -273,6 +277,34 @@ public class Trigger
return true; 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() boolean checkDeviceOrientation()
{ {
String deviceOrientationPieces[] = getTriggerParameter2().split(Trigger.triggerParameter2Split); String deviceOrientationPieces[] = getTriggerParameter2().split(Trigger.triggerParameter2Split);
@ -986,7 +1018,7 @@ public class Trigger
*/ */
public enum Trigger_Enum { 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) public String getFullName(Context context)
{ {
@ -1028,6 +1060,8 @@ public class Trigger
return context.getResources().getString(R.string.notification); return context.getResources().getString(R.string.notification);
case deviceOrientation: case deviceOrientation:
return context.getResources().getString(R.string.deviceOrientation); return context.getResources().getString(R.string.deviceOrientation);
case profileActive:
return context.getResources().getString(R.string.profile);
default: default:
return "Unknown"; return "Unknown";
} }
@ -1373,21 +1407,7 @@ public class Trigger
if (ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION")) 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. // This type doesn't have an activate/deactivate equivalent, at least not yet.
// try
// {
returnString.append(Miscellaneous.runMethodReflective(ActivityManageRule.activityDetectionClassPath, "getDescription", new Object[]{getActivityDetectionType()})); 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 else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.featureNotInFdroidVersion)); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.featureNotInFdroidVersion));
@ -1500,6 +1520,12 @@ public class Trigger
case deviceOrientation: case deviceOrientation:
returnString.append(Miscellaneous.getAnyContext().getString(R.string.deviceIsInCertainOrientation)); returnString.append(Miscellaneous.getAnyContext().getString(R.string.deviceIsInCertainOrientation));
break; 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: default:
returnString.append("error"); returnString.append("error");
break; break;

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/default_margin"
android:orientation="vertical">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow>
<TextView
android:text="@string/profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Spinner
android:id="@+id/spinnerProfiles"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:text="@string/needsToBeActive"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/chkProfileActive"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView
android:text="@string/checkSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/chkProfileCheckSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/bSaveTriggerProfile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -738,4 +738,8 @@
<string name="smsDialogNotice">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.</string> <string name="smsDialogNotice">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.</string>
<string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Exclude from battery optimization</string> <string name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS">Exclude from battery optimization</string>
<string name="recommendedForBetterReliability">Recommended for better reliability</string> <string name="recommendedForBetterReliability">Recommended for better reliability</string>
<string name="needsToBeActive">Needs to be active</string>
<string name="checkSettings">Check settings</string>
<string name="profileActive">profile %1$s is active</string>
<string name="profileNotActive">profile %1$s is not active</string>
</resources> </resources>

View File

@ -1 +1,2 @@
* Exclusion from battery optimization * Exclusion from battery optimization
* Profiles can be used as trigger