Compare commits
24 Commits
7127ac45bc
...
e0c3b9d450
Author | SHA1 | Date | |
---|---|---|---|
e0c3b9d450 | |||
c134b15ab1 | |||
6ef6277976 | |||
10e6c74ba8 | |||
b6f3d928ae | |||
e898264178 | |||
0891dca98d | |||
8843a97b79 | |||
1c24af7bcb | |||
ee43e109da | |||
13bcb02ffc | |||
864ed2111e | |||
67e6a38ddc | |||
fb44196a0d | |||
7894504791 | |||
0df5342036 | |||
712a374adb | |||
80f8f9cfe2 | |||
1d9ed8b3ff | |||
5d6221888a | |||
56806f0349 | |||
8a43741b21 | |||
054ab6d84b | |||
47b56d4978 |
@ -11,8 +11,8 @@ android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 101
|
||||
versionName "1.6.25"
|
||||
versionCode 102
|
||||
versionName "1.6.30"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -42,7 +42,7 @@ android {
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".googlePlay"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 30
|
||||
targetSdkVersion 29
|
||||
}
|
||||
|
||||
fdroidFlavor
|
||||
|
@ -10,8 +10,8 @@
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 101,
|
||||
"versionName": "1.6.25-googlePlay",
|
||||
"versionCode": 102,
|
||||
"versionName": "1.6.30-googlePlay",
|
||||
"outputFile": "app-googlePlayFlavor-release.apk"
|
||||
}
|
||||
]
|
||||
|
@ -62,6 +62,7 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
|
||||
@ -136,11 +137,12 @@
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityManageActionTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
@ -178,10 +180,10 @@
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
@ -203,6 +205,25 @@
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
|
||||
</service>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
android:authorities="com.jens.automation2"
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,13 +1,17 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.location.DetectedActivity;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
@ -16,6 +20,7 @@ import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
import com.jens.automation2.receivers.NoiseListener;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
import com.jens.automation2.receivers.ProcessListener;
|
||||
|
||||
@ -24,6 +29,10 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
||||
|
||||
|
||||
public class Rule implements Comparable<Rule>
|
||||
{
|
||||
@ -42,9 +51,20 @@ public class Rule implements Comparable<Rule>
|
||||
private String name;
|
||||
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
|
||||
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
|
||||
private Calendar lastExecution;
|
||||
|
||||
private static Date lastActivatedRuleActivationTime;
|
||||
|
||||
public Calendar getLastExecution()
|
||||
{
|
||||
return lastExecution;
|
||||
}
|
||||
|
||||
public void setLastExecution(Calendar lastExecution)
|
||||
{
|
||||
this.lastExecution = lastExecution;
|
||||
}
|
||||
|
||||
public boolean isRuleToggle()
|
||||
{
|
||||
return ruleToggle;
|
||||
@ -114,6 +134,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
@SuppressLint("NewApi")
|
||||
public String toStringLong()
|
||||
{
|
||||
String returnString = "";
|
||||
@ -469,7 +490,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() < oneTrigger.getBatteryLevel())
|
||||
if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -477,7 +498,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() > oneTrigger.getBatteryLevel())
|
||||
if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -488,7 +509,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -496,7 +517,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -649,45 +670,6 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
|
||||
|
||||
// if( // connected / disconnected
|
||||
// (oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACL_CONNECTED")))
|
||||
// |
|
||||
// (!oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED") | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECTED")))
|
||||
// )
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress() != null)
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No bluetooth address specified, any will do.", 4);
|
||||
// }
|
||||
// else if(oneTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
||||
// {
|
||||
// // ???
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address specified, checking that.", 4);
|
||||
// if(!BluetoothReceiver.getLastAffectedDevice().getAddress().equals(oneTrigger.getBluetoothDeviceAddress()))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectDeviceAddress), 3);
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address matches. Rule will apply.", 4);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if(BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND))
|
||||
// {
|
||||
// if(!oneTrigger.getTriggerParameter())
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyDeviceInRangeButShouldNotBe), 3);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// else // above only checks for last action, this checks for things in the past
|
||||
{
|
||||
if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
{
|
||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
||||
@ -751,7 +733,6 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged))
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter())
|
||||
@ -763,6 +744,109 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification))
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
String myApp = params[0];
|
||||
String myTitleDir = params[1];
|
||||
String myTitle = params[2];
|
||||
String myTextDir = params[3];
|
||||
String myText;
|
||||
if (params.length >= 5)
|
||||
myText = params[4];
|
||||
else
|
||||
myText = "";
|
||||
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
// Check an active notification that is still there
|
||||
|
||||
boolean foundMatch = false;
|
||||
|
||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
||||
{
|
||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + app + ", title: " + title + ", text: " + text, 5);
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, myTitle, title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, myText, text))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundMatch)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check a notification that is gone
|
||||
|
||||
if(NotificationListener.getLastNotification() != null)
|
||||
{
|
||||
if(!NotificationListener.getLastNotification().isCreated())
|
||||
{
|
||||
String app = NotificationListener.getLastNotification().getApp();
|
||||
String title = NotificationListener.getLastNotification().getTitle();
|
||||
String text = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, title, myTitle))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, text, myText))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -774,6 +858,8 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
private class ActivateRuleTask extends AsyncTask<Object, String, Void>
|
||||
{
|
||||
boolean wasActivated = false;
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Object... params)
|
||||
{
|
||||
@ -788,7 +874,7 @@ public class Rule implements Comparable<Rule>
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
wasActivated = activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -806,16 +892,24 @@ public class Rule implements Comparable<Rule>
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
/*
|
||||
Only update if the rules was actually executed. Became necessary for the notification trigger. If a user created a rule
|
||||
with a notification trigger and this app creates a notification itself this will otherwise end in an infinite loop.
|
||||
*/
|
||||
if(wasActivated)
|
||||
{
|
||||
setLastExecution(Calendar.getInstance());
|
||||
AutomationService.updateNotification();
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will activate the rule. Should be called by a separate execution thread
|
||||
* @param automationService
|
||||
*/
|
||||
protected void activateInternally(AutomationService automationService, boolean force)
|
||||
protected boolean activateInternally(AutomationService automationService, boolean force)
|
||||
{
|
||||
boolean isActuallyToggable = isActuallyToggable();
|
||||
|
||||
@ -836,7 +930,16 @@ public class Rule implements Comparable<Rule>
|
||||
publishProgress(message);
|
||||
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Rule.this.getActionSet().get(i).run(automationService, doToggle);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "RuleExecution", "Error running action of rule " + Rule.this.getName() + ": " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep log of last x rule activations (Settings)
|
||||
try
|
||||
@ -862,7 +965,10 @@ public class Rule implements Comparable<Rule>
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Request to activate rule " + Rule.this.getName() + ", but it is the last one that was activated. Won't do it again.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1280,6 +1386,26 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == triggerType)
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByActivityDetection()
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
@ -132,11 +132,11 @@
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityManageActionTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
@ -173,18 +173,35 @@
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
|
||||
</service>
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
android:authorities="com.jens.automation2"
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,12 +1,16 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
@ -14,6 +18,7 @@ import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
import com.jens.automation2.receivers.NoiseListener;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
import com.jens.automation2.receivers.ProcessListener;
|
||||
|
||||
@ -22,6 +27,9 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
||||
|
||||
public class Rule implements Comparable<Rule>
|
||||
{
|
||||
@ -40,9 +48,20 @@ public class Rule implements Comparable<Rule>
|
||||
private String name;
|
||||
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
|
||||
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
|
||||
private Calendar lastExecution;
|
||||
|
||||
private static Date lastActivatedRuleActivationTime;
|
||||
|
||||
public Calendar getLastExecution()
|
||||
{
|
||||
return lastExecution;
|
||||
}
|
||||
|
||||
public void setLastExecution(Calendar lastExecution)
|
||||
{
|
||||
this.lastExecution = lastExecution;
|
||||
}
|
||||
|
||||
public boolean isRuleToggle()
|
||||
{
|
||||
return ruleToggle;
|
||||
@ -112,6 +131,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
@SuppressLint("NewApi")
|
||||
public String toStringLong()
|
||||
{
|
||||
String returnString = "";
|
||||
@ -467,7 +487,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() < oneTrigger.getBatteryLevel())
|
||||
if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -475,7 +495,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() > oneTrigger.getBatteryLevel())
|
||||
if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -486,7 +506,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -494,7 +514,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -618,45 +638,6 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
|
||||
|
||||
// if( // connected / disconnected
|
||||
// (oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACL_CONNECTED")))
|
||||
// |
|
||||
// (!oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED") | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECTED")))
|
||||
// )
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress() != null)
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No bluetooth address specified, any will do.", 4);
|
||||
// }
|
||||
// else if(oneTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
||||
// {
|
||||
// // ???
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address specified, checking that.", 4);
|
||||
// if(!BluetoothReceiver.getLastAffectedDevice().getAddress().equals(oneTrigger.getBluetoothDeviceAddress()))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectDeviceAddress), 3);
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address matches. Rule will apply.", 4);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if(BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND))
|
||||
// {
|
||||
// if(!oneTrigger.getTriggerParameter())
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyDeviceInRangeButShouldNotBe), 3);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// else // above only checks for last action, this checks for things in the past
|
||||
{
|
||||
if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
{
|
||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
||||
@ -720,7 +701,6 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged))
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter())
|
||||
@ -732,6 +712,108 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification))
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
String myApp = params[0];
|
||||
String myTitleDir = params[1];
|
||||
String myTitle = params[2];
|
||||
String myTextDir = params[3];
|
||||
String myText;
|
||||
if (params.length >= 5)
|
||||
myText = params[4];
|
||||
else
|
||||
myText = "";
|
||||
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
// Check an active notification that is still there
|
||||
|
||||
boolean foundMatch = false;
|
||||
|
||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
||||
{
|
||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + app + ", title: " + title + ", text: " + text, 5);
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, myTitle, title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, myText, text))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundMatch)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check a notification that is gone
|
||||
|
||||
if(NotificationListener.getLastNotification() != null)
|
||||
{
|
||||
if(!NotificationListener.getLastNotification().isCreated())
|
||||
{
|
||||
String app = NotificationListener.getLastNotification().getApp();
|
||||
String title = NotificationListener.getLastNotification().getTitle();
|
||||
String text = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, title, myTitle))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, text, myText))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -743,6 +825,8 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
private class ActivateRuleTask extends AsyncTask<Object, String, Void>
|
||||
{
|
||||
boolean wasActivated = false;
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Object... params)
|
||||
{
|
||||
@ -757,7 +841,7 @@ public class Rule implements Comparable<Rule>
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
wasActivated = activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -775,16 +859,24 @@ public class Rule implements Comparable<Rule>
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
/*
|
||||
Only update if the rules was actually executed. Became necessary for the notification trigger. If a user created a rule
|
||||
with a notification trigger and this app creates a notification itself this will otherwise end in an infinite loop.
|
||||
*/
|
||||
if(wasActivated)
|
||||
{
|
||||
setLastExecution(Calendar.getInstance());
|
||||
AutomationService.updateNotification();
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will activate the rule. Should be called by a separate execution thread
|
||||
* @param automationService
|
||||
*/
|
||||
protected void activateInternally(AutomationService automationService, boolean force)
|
||||
protected boolean activateInternally(AutomationService automationService, boolean force)
|
||||
{
|
||||
boolean isActuallyToggable = isActuallyToggable();
|
||||
|
||||
@ -805,7 +897,16 @@ public class Rule implements Comparable<Rule>
|
||||
publishProgress(message);
|
||||
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Rule.this.getActionSet().get(i).run(automationService, doToggle);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "RuleExecution", "Error running action of rule " + Rule.this.getName() + ": " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep log of last x rule activations (Settings)
|
||||
try
|
||||
@ -831,7 +932,10 @@ public class Rule implements Comparable<Rule>
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Request to activate rule " + Rule.this.getName() + ", but it is the last one that was activated. Won't do it again.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1249,6 +1353,26 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == triggerType)
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByActivityDetection()
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
@ -126,11 +126,12 @@
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityManageActionTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
@ -168,13 +169,25 @@
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
@ -191,6 +204,12 @@
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
android:authorities="com.jens.automation2"
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,13 +1,17 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.location.DetectedActivity;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
@ -16,6 +20,7 @@ import com.jens.automation2.receivers.ConnectivityReceiver;
|
||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
import com.jens.automation2.receivers.NoiseListener;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
import com.jens.automation2.receivers.ProcessListener;
|
||||
|
||||
@ -24,6 +29,9 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
||||
|
||||
public class Rule implements Comparable<Rule>
|
||||
{
|
||||
@ -42,9 +50,20 @@ public class Rule implements Comparable<Rule>
|
||||
private String name;
|
||||
private boolean ruleActive = true; // rules can be deactivated, so they won't fire if you don't want them temporarily
|
||||
private boolean ruleToggle = false; // rule will run again and do the opposite of its actions if applicable
|
||||
private Calendar lastExecution;
|
||||
|
||||
private static Date lastActivatedRuleActivationTime;
|
||||
|
||||
public Calendar getLastExecution()
|
||||
{
|
||||
return lastExecution;
|
||||
}
|
||||
|
||||
public void setLastExecution(Calendar lastExecution)
|
||||
{
|
||||
this.lastExecution = lastExecution;
|
||||
}
|
||||
|
||||
public boolean isRuleToggle()
|
||||
{
|
||||
return ruleToggle;
|
||||
@ -114,6 +133,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
@SuppressLint("NewApi")
|
||||
public String toStringLong()
|
||||
{
|
||||
String returnString = "";
|
||||
@ -469,7 +489,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() < oneTrigger.getBatteryLevel())
|
||||
if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -477,7 +497,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BatteryReceiver.getBatteryLevel() > oneTrigger.getBatteryLevel())
|
||||
if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
||||
return false;
|
||||
@ -488,7 +508,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -496,7 +516,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else
|
||||
{
|
||||
if(com.jens.automation2.location.LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
if(LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
||||
return false;
|
||||
@ -649,45 +669,6 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
|
||||
|
||||
// if( // connected / disconnected
|
||||
// (oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACL_CONNECTED")))
|
||||
// |
|
||||
// (!oneTrigger.getTriggerParameter() && (BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_ACL_DISCONNECTED) | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED") | BluetoothReceiver.getLastAction().equals("android.bluetooth.device.action.ACTION_ACL_DISCONNECTED")))
|
||||
// )
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress() != null)
|
||||
// {
|
||||
// if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No bluetooth address specified, any will do.", 4);
|
||||
// }
|
||||
// else if(oneTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
||||
// {
|
||||
// // ???
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address specified, checking that.", 4);
|
||||
// if(!BluetoothReceiver.getLastAffectedDevice().getAddress().equals(oneTrigger.getBluetoothDeviceAddress()))
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectDeviceAddress), 3);
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Bluetooth address matches. Rule will apply.", 4);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if(BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND) | BluetoothReceiver.getLastAction().equals(android.bluetooth.BluetoothDevice.ACTION_FOUND))
|
||||
// {
|
||||
// if(!oneTrigger.getTriggerParameter())
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyDeviceInRangeButShouldNotBe), 3);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// else // above only checks for last action, this checks for things in the past
|
||||
{
|
||||
if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
{
|
||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
||||
@ -751,7 +732,6 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged))
|
||||
{
|
||||
if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter())
|
||||
@ -763,6 +743,109 @@ public class Rule implements Comparable<Rule>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification))
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
String myApp = params[0];
|
||||
String myTitleDir = params[1];
|
||||
String myTitle = params[2];
|
||||
String myTextDir = params[3];
|
||||
String myText;
|
||||
if (params.length >= 5)
|
||||
myText = params[4];
|
||||
else
|
||||
myText = "";
|
||||
|
||||
if(oneTrigger.getTriggerParameter())
|
||||
{
|
||||
// Check an active notification that is still there
|
||||
|
||||
boolean foundMatch = false;
|
||||
|
||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
||||
{
|
||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + app + ", title: " + title + ", text: " + text, 5);
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, myTitle, title))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, myText, text))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundMatch)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check a notification that is gone
|
||||
|
||||
if(NotificationListener.getLastNotification() != null)
|
||||
{
|
||||
if(!NotificationListener.getLastNotification().isCreated())
|
||||
{
|
||||
String app = NotificationListener.getLastNotification().getApp();
|
||||
String title = NotificationListener.getLastNotification().getTitle();
|
||||
String text = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, title, myTitle))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myText.length() > 0)
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, text, myText))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -774,6 +857,8 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
private class ActivateRuleTask extends AsyncTask<Object, String, Void>
|
||||
{
|
||||
boolean wasActivated = false;
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Object... params)
|
||||
{
|
||||
@ -788,7 +873,7 @@ public class Rule implements Comparable<Rule>
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
wasActivated = activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -806,16 +891,24 @@ public class Rule implements Comparable<Rule>
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
/*
|
||||
Only update if the rules was actually executed. Became necessary for the notification trigger. If a user created a rule
|
||||
with a notification trigger and this app creates a notification itself this will otherwise end in an infinite loop.
|
||||
*/
|
||||
if(wasActivated)
|
||||
{
|
||||
setLastExecution(Calendar.getInstance());
|
||||
AutomationService.updateNotification();
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will activate the rule. Should be called by a separate execution thread
|
||||
* @param automationService
|
||||
*/
|
||||
protected void activateInternally(AutomationService automationService, boolean force)
|
||||
protected boolean activateInternally(AutomationService automationService, boolean force)
|
||||
{
|
||||
boolean isActuallyToggable = isActuallyToggable();
|
||||
|
||||
@ -836,7 +929,16 @@ public class Rule implements Comparable<Rule>
|
||||
publishProgress(message);
|
||||
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Rule.this.getActionSet().get(i).run(automationService, doToggle);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "RuleExecution", "Error running action of rule " + Rule.this.getName() + ": " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep log of last x rule activations (Settings)
|
||||
try
|
||||
@ -862,7 +964,10 @@ public class Rule implements Comparable<Rule>
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Request to activate rule " + Rule.this.getName() + ", but it is the last one that was activated. Won't do it again.", 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1280,6 +1385,26 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidates(Trigger.Trigger_Enum triggerType)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
for(Trigger oneTrigger : oneRule.getTriggerSet())
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == triggerType)
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByActivityDetection()
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
@ -2,7 +2,9 @@ package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.style.TabStopSpan;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
@ -12,6 +14,8 @@ import java.util.Locale;
|
||||
|
||||
public class Action
|
||||
{
|
||||
public static final String actionParameter2Split = "ap2split";
|
||||
|
||||
public enum Action_Enum {
|
||||
setWifi,
|
||||
setBluetooth,
|
||||
@ -33,6 +37,7 @@ public class Action
|
||||
speakText,
|
||||
playMusic,
|
||||
setScreenBrightness,
|
||||
playSound,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
@ -87,6 +92,8 @@ public class Action
|
||||
return context.getResources().getString(R.string.actionSpeakText);
|
||||
case playMusic:
|
||||
return context.getResources().getString(R.string.actionPlayMusic);
|
||||
case playSound:
|
||||
return context.getResources().getString(R.string.playSound);
|
||||
case sendTextMessage:
|
||||
return context.getResources().getString(R.string.sendTextMessage);
|
||||
case setScreenBrightness:
|
||||
@ -210,6 +217,10 @@ public class Action
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wakeupDevice));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.playSound))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.playSound));
|
||||
}
|
||||
else
|
||||
returnString.append(action.toString());
|
||||
|
||||
@ -320,6 +331,8 @@ public class Action
|
||||
}
|
||||
|
||||
public void run(Context context, boolean toggleActionIfPossible)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch(this.getAction())
|
||||
{
|
||||
@ -395,11 +408,20 @@ public class Action
|
||||
case setScreenBrightness:
|
||||
Actions.setScreenBrightness(getParameter1(), Integer.parseInt(getParameter2()));
|
||||
break;
|
||||
case playSound:
|
||||
Actions.playSound(getParameter1(), getParameter2());
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "ActionExecution", Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.errorRunningRule), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerUrl(Context context)
|
||||
{
|
||||
|
@ -8,7 +8,9 @@ import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
@ -32,6 +34,7 @@ import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
@ -465,6 +468,45 @@ public class Actions
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void playSound(boolean alwaysPlay, String soundFileLocation)
|
||||
{
|
||||
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())
|
||||
{
|
||||
Uri fileUri = Uri.parse(soundFileLocation);
|
||||
mp.setLooping(false);
|
||||
mp.setDataSource(Miscellaneous.getAnyContext(), fileUri);
|
||||
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
|
||||
{
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer mp)
|
||||
{
|
||||
mp.release();
|
||||
}
|
||||
});
|
||||
mp.prepare();
|
||||
mp.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Play sound file", "Sound file " + soundFileLocation + " does not exist. Can't play it.", 2);
|
||||
Toast.makeText(context, String.format(context.getResources().getString(R.string.cantFindSoundFile), soundFileLocation), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Play sound file", "Error playing sound: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Play sound file", "Not playing sound file because phone is on some kind of mute state.", 2);
|
||||
}
|
||||
|
||||
public void useDownloadedWebpage(String result)
|
||||
{
|
||||
// Toast.makeText(context, "Result: " + result, Toast.LENGTH_LONG).show();
|
||||
@ -527,7 +569,9 @@ public class Actions
|
||||
Miscellaneous.logEvent("i", "StartOtherActivity", "Starting other Activity...", 4);
|
||||
|
||||
String packageName, className;
|
||||
|
||||
String params[] = param.split(";");
|
||||
|
||||
packageName = params[0];
|
||||
className = params[1];
|
||||
|
||||
@ -537,8 +581,14 @@ public class Actions
|
||||
Intent externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
if(packageName.equals("dummyPkg"))
|
||||
externalActivityIntent.setAction(className);
|
||||
else
|
||||
externalActivityIntent.setClassName(packageName, className);
|
||||
|
||||
if(Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext()))
|
||||
{
|
||||
// has intent values to deliver
|
||||
for (int i = 2; i < params.length; i++)
|
||||
{
|
||||
@ -610,6 +660,11 @@ public class Actions
|
||||
|
||||
autoMationServerRef.startActivity(externalActivityIntent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2);
|
||||
}
|
||||
}
|
||||
catch(ActivityNotFoundException | SecurityException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "StartOtherApp", autoMationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
|
||||
|
@ -10,6 +10,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -29,6 +30,8 @@ import com.jens.automation2.AutomationService.serviceCommands;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
@ -39,7 +42,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
|
||||
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||
private ToggleButton toggleService, tbLockSound;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme, bShareConfigAndLog;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration, tvFileStoreLocation;
|
||||
|
||||
private ListView lvRuleHistory;
|
||||
@ -76,6 +79,9 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bShareConfigAndLog = (Button) findViewById(R.id.bShareConfigAndLog);
|
||||
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
@ -135,7 +141,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
Button bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -179,16 +184,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
/*bSettingsErase = (Button)findViewById(R.id.bSettingsErase);
|
||||
bSettingsErase.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getEraseSettingsDialog(ActivityMainScreen.this).show();
|
||||
}
|
||||
});*/
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -198,6 +193,15 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
bShareConfigAndLog.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getShareConfigAndLogDialogue(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
@ -279,6 +283,62 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
AlertDialog getShareConfigAndLogDialogue(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.shareConfigAndLogFilesWithDev));
|
||||
alertDialogBuilder.setMessage(context.getResources().getString(R.string.shareConfigAndLogExplanation));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
File dstZipFile = new File(Miscellaneous.getAnyContext().getCacheDir() + "/" + Settings.zipFileName);
|
||||
|
||||
ArrayList<String> srcFilesList = new ArrayList<>();
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
if(dstZipFile.exists())
|
||||
dstZipFile.delete();
|
||||
|
||||
Miscellaneous.zip(srcFiles, dstZipFile.getAbsolutePath());
|
||||
|
||||
/*
|
||||
Without root the zip file in the cache directory is not directly accessible.
|
||||
But have to route it through this content provider crap.
|
||||
*/
|
||||
|
||||
String subject = "Automation logs";
|
||||
|
||||
StringBuilder emailBody = new StringBuilder();
|
||||
emailBody.append("Device details" + Miscellaneous.lineSeparator);
|
||||
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
|
||||
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Product: " + android.os.Build.PRODUCT);
|
||||
|
||||
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
|
||||
|
||||
Miscellaneous.sendEmail(ActivityMainScreen.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||
{
|
||||
return activityMainScreenInstance;
|
||||
@ -370,9 +430,9 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, Miscellaneous.getAnyContext())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, Miscellaneous.getAnyContext())
|
||||
)
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||
else
|
||||
@ -458,7 +518,31 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if(folder != null && folder.length() > 0)
|
||||
{
|
||||
activityMainScreenInstance.tvFileStoreLocation.setText(String.format(activityMainScreenInstance.getResources().getString(R.string.filesStoredAt), folder));
|
||||
activityMainScreenInstance.tvFileStoreLocation.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Uri selectedUri = Uri.parse(folder);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
|
||||
if (intent.resolveActivityInfo(activityMainScreenInstance.getPackageManager(), 0) != null)
|
||||
{
|
||||
activityMainScreenInstance.startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(activityMainScreenInstance, activityMainScreenInstance.getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageBrightnessSetting extends Activity
|
||||
public class ActivityManageActionBrightnessSetting extends Activity
|
||||
{
|
||||
CheckBox chkAutoBrightness;
|
||||
SeekBar sbBrightness;
|
@ -0,0 +1,110 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ActivityManageActionPlaySound extends Activity
|
||||
{
|
||||
final static int PICKFILE_RESULT_CODE = 4711;
|
||||
|
||||
CheckBox chkPlaySoundAlwaysPlay;
|
||||
EditText etSelectedSoundFile;
|
||||
Button bSelectSoundFile, bSavePlaySound;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_play_sound);
|
||||
|
||||
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
|
||||
etSelectedSoundFile = (EditText)findViewById(R.id.etSelectedSoundFile);
|
||||
bSelectSoundFile = (Button)findViewById(R.id.bSelectSoundFile);
|
||||
bSavePlaySound = (Button)findViewById(R.id.bSavePlaySound);
|
||||
|
||||
boolean edit = getIntent().getBooleanExtra("edit", false);
|
||||
|
||||
if(edit)
|
||||
{
|
||||
boolean param1 = getIntent().getBooleanExtra("actionParameter1", false);
|
||||
String param2 = getIntent().getStringExtra("actionParameter2");
|
||||
chkPlaySoundAlwaysPlay.setChecked(param1);
|
||||
etSelectedSoundFile.setText(param2);
|
||||
}
|
||||
|
||||
bSelectSoundFile.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
//Need to check for storage permissions
|
||||
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
chooseFile.setType("*/*");
|
||||
chooseFile = Intent.createChooser(chooseFile, getResources().getString(R.string.selectSoundFile));
|
||||
startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
bSavePlaySound.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
savePlaySoundSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void savePlaySoundSettings()
|
||||
{
|
||||
if(etSelectedSoundFile.getText().toString() == null || etSelectedSoundFile.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionPlaySound.this, getResources().getString(R.string.selectSoundFile), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File soundFile = new File(etSelectedSoundFile.getText().toString());
|
||||
if(!soundFile.exists())
|
||||
{
|
||||
Toast.makeText(ActivityManageActionPlaySound.this, getResources().getString(R.string.fileDoesNotExist), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Intent returnData = new Intent();
|
||||
returnData.putExtra("actionParameter1", chkPlaySoundAlwaysPlay.isChecked());
|
||||
returnData.putExtra("actionParameter2", etSelectedSoundFile.getText().toString());
|
||||
|
||||
setResult(RESULT_OK, returnData);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
if(requestCode == PICKFILE_RESULT_CODE)
|
||||
{
|
||||
Uri fileUri = data.getData();
|
||||
String filePath = CompensateCrappyAndroidPaths.getPath(ActivityManageActionPlaySound.this, fileUri);
|
||||
etSelectedSoundFile.setText(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import androidx.annotation.NonNull;
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
|
||||
public class ActivityEditSendTextMessage extends Activity
|
||||
public class ActivityManageActionSendTextMessage extends Activity
|
||||
{
|
||||
Button bSaveSendTextMessage, bImportNumberFromContacts;
|
||||
EditText etPhoneNumber, etSendTextMessage;
|
||||
@ -67,7 +67,7 @@ public class ActivityEditSendTextMessage extends Activity
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityEditSendTextMessage.this))
|
||||
if(!ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageActionSendTextMessage.this))
|
||||
{
|
||||
requestPermissions("android.permission.READ_CONTACTS");
|
||||
}
|
||||
@ -76,10 +76,10 @@ public class ActivityEditSendTextMessage extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
ActivityEditSendTextMessage.edit = getIntent().getBooleanExtra("edit", false);
|
||||
ActivityManageActionSendTextMessage.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
{
|
||||
String[] parameters = ActivityEditSendTextMessage.resultingAction.getParameter2().split(Actions.smsSeparator);
|
||||
String[] parameters = ActivityManageActionSendTextMessage.resultingAction.getParameter2().split(Actions.smsSeparator);
|
||||
etPhoneNumber.setText(parameters[0]);
|
||||
etSendTextMessage.setText(parameters[1]);
|
||||
}
|
||||
@ -99,7 +99,7 @@ public class ActivityEditSendTextMessage extends Activity
|
||||
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
ActivityEditSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
ActivityManageActionSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
}
|
||||
|
||||
setResult(RESULT_OK);
|
||||
@ -162,7 +162,7 @@ public class ActivityEditSendTextMessage extends Activity
|
||||
String name = null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
Cursor cursor = ActivityEditSendTextMessage.this.getContentResolver().query(uri, null, null, null, null);
|
||||
Cursor cursor = ActivityManageActionSendTextMessage.this.getContentResolver().query(uri, null, null, null, null);
|
||||
|
||||
if (cursor.moveToFirst())
|
||||
{
|
@ -10,7 +10,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
public class ActivityEditSpeakText extends Activity
|
||||
public class ActivityManageActionSpeakText extends Activity
|
||||
{
|
||||
private Button bSaveSpeakText;
|
||||
private EditText etSpeakText;
|
||||
@ -48,9 +48,9 @@ public class ActivityEditSpeakText extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
ActivityEditSpeakText.edit = getIntent().getBooleanExtra("edit", false);
|
||||
ActivityManageActionSpeakText.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
etSpeakText.setText(ActivityEditSpeakText.resultingAction.getParameter2());
|
||||
etSpeakText.setText(ActivityManageActionSpeakText.resultingAction.getParameter2());
|
||||
|
||||
|
||||
// String url = getIntent().getStringExtra("urlToTrigger");
|
||||
@ -66,7 +66,7 @@ public class ActivityEditSpeakText extends Activity
|
||||
// setResult(RESULT_OK, returnIntent);
|
||||
|
||||
if(edit && resultingAction != null)
|
||||
ActivityEditSpeakText.resultingAction.setParameter2(etSpeakText.getText().toString());
|
||||
ActivityManageActionSpeakText.resultingAction.setParameter2(etSpeakText.getText().toString());
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
@ -35,13 +35,12 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageStartActivity extends Activity
|
||||
public class ActivityManageActionStartActivity extends Activity
|
||||
{
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue;
|
||||
EditText etParameterName, etParameterValue, etSelectedActivity;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity;
|
||||
Spinner spinnerParameterType;
|
||||
TextView tvSelectedActivity;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
@ -56,12 +55,12 @@ public class ActivityManageStartActivity extends Activity
|
||||
ApplicationInfo aInfo1 = this.applicationInfo;
|
||||
if (aInfo1 != null)
|
||||
{
|
||||
name1 = (String) ActivityManageStartActivity.this.getPackageManager().getApplicationLabel(aInfo1);
|
||||
name1 = (String) ActivityManageActionStartActivity.this.getPackageManager().getApplicationLabel(aInfo1);
|
||||
}
|
||||
ApplicationInfo aInfo2 = another.applicationInfo;
|
||||
if (aInfo2 != null)
|
||||
{
|
||||
name2 = (String) ActivityManageStartActivity.this.getPackageManager().getApplicationLabel(aInfo2);
|
||||
name2 = (String) ActivityManageActionStartActivity.this.getPackageManager().getApplicationLabel(aInfo2);
|
||||
}
|
||||
|
||||
return name1.compareTo(name2);
|
||||
@ -224,7 +223,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
|
||||
final String[] applicationArray = ActivityManageStartActivity.getApplicationNameListString(this);
|
||||
final String[] applicationArray = ActivityManageActionStartActivity.getApplicationNameListString(this);
|
||||
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -242,14 +241,14 @@ public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageStartActivity.getPackageListString(this, applicationName);
|
||||
final String[] packageArray = ActivityManageActionStartActivity.getPackageListString(this, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
getActionStartActivityDialog3(packageArray[which]).show();
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageStartActivity.this).show();
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageActionStartActivity.this).show();
|
||||
|
||||
}
|
||||
});
|
||||
@ -261,14 +260,14 @@ public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
|
||||
final String activityArray[] = ActivityManageStartActivity.getActivityListForPackageName(packageName);
|
||||
final String activityArray[] = ActivityManageActionStartActivity.getActivityListForPackageName(packageName);
|
||||
alertDialogBuilder.setItems(activityArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
tvSelectedActivity.setText(ai.packageName + ";" + ai.name);
|
||||
ActivityInfo ai = ActivityManageActionStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
etSelectedActivity.setText(ai.packageName + ";" + ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
@ -289,13 +288,13 @@ public class ActivityManageStartActivity extends Activity
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
|
||||
tvSelectedActivity = (TextView)findViewById(R.id.tvSelectedActivity);
|
||||
etSelectedActivity = (EditText) findViewById(R.id.etSelectedApplication);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageStartActivity.supportedIntentTypes);
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_smalltextsize, intentPairList);
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, intentPairList);
|
||||
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@ -304,7 +303,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageStartActivity.this, "", ActivityManageStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
progressDialog = ProgressDialog.show(ActivityManageActionStartActivity.this, "", ActivityManageActionStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
});
|
||||
|
||||
@ -316,19 +315,19 @@ public class ActivityManageStartActivity extends Activity
|
||||
// type;name;value
|
||||
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -360,7 +359,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
if(saveAction())
|
||||
{
|
||||
ActivityManageStartActivity.this.setResult(RESULT_OK);
|
||||
ActivityManageActionStartActivity.this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@ -382,9 +381,9 @@ public class ActivityManageStartActivity extends Activity
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
else
|
||||
ActivityManageStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
ActivityManageActionStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -408,7 +407,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
String[] params = resultingAction.getParameter2().split(";");
|
||||
if(params.length >= 2)
|
||||
{
|
||||
tvSelectedActivity.setText(params[0] + ";" + params[1]);
|
||||
etSelectedActivity.setText(params[0] + ";" + params[1]);
|
||||
|
||||
if(params.length > 2)
|
||||
{
|
||||
@ -434,13 +433,23 @@ public class ActivityManageStartActivity extends Activity
|
||||
|
||||
private boolean saveAction()
|
||||
{
|
||||
if(tvSelectedActivity.getText().toString().length() == 0)
|
||||
if(etSelectedActivity.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Intent testIntent = new Intent(ActivityManageActionStartActivity.this, etSelectedActivity);
|
||||
// Intent externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
// externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
// externalActivityIntent.setClassName(packageName, className);
|
||||
//
|
||||
// boolean activityExists = externalActivityIntent.resolveActivityInfo(getPackageManager(), 0) != null;
|
||||
// }
|
||||
|
||||
if(tvSelectedActivity.getText().toString().equals(getResources().getString(R.string.selectApplication)))
|
||||
if(etSelectedActivity.getText().toString().equals(getResources().getString(R.string.selectApplication)))
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
@ -451,7 +460,13 @@ public class ActivityManageStartActivity extends Activity
|
||||
|
||||
resultingAction.setAction(Action_Enum.startOtherActivity);
|
||||
|
||||
String parameter2 = tvSelectedActivity.getText().toString();
|
||||
String parameter2;
|
||||
|
||||
if(etSelectedActivity.getText().toString().contains(";"))
|
||||
parameter2 = etSelectedActivity.getText().toString();
|
||||
else
|
||||
parameter2 = "dummyPkg;" + etSelectedActivity.getText().toString();
|
||||
|
||||
for(String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
|
||||
@ -462,7 +477,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
|
||||
private AlertDialog getIntentPairDialog(final int itemPosition)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageStartActivity.this);
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageActionStartActivity.this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
|
||||
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@ -470,7 +485,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// Only 1 choice at the moment, no need to check
|
||||
ActivityManageStartActivity.this.intentPairList.remove(itemPosition);
|
||||
ActivityManageActionStartActivity.this.intentPairList.remove(itemPosition);
|
||||
updateIntentPairList();
|
||||
}
|
||||
});
|
||||
@ -484,7 +499,7 @@ public class ActivityManageStartActivity extends Activity
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
getActivityList(ActivityManageStartActivity.this);
|
||||
getActivityList(ActivityManageActionStartActivity.this);
|
||||
return null;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ActivityEditTriggerUrl extends Activity
|
||||
public class ActivityManageActionTriggerUrl extends Activity
|
||||
{
|
||||
Button bSaveTriggerUrl;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
|
||||
@ -70,7 +70,7 @@ public class ActivityEditTriggerUrl extends Activity
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter2(
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString().trim()
|
||||
@ -110,16 +110,16 @@ public class ActivityEditTriggerUrl extends Activity
|
||||
updateListView();
|
||||
|
||||
|
||||
ActivityEditTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
ActivityManageActionTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
{
|
||||
// username,password,URL
|
||||
String[] components = ActivityEditTriggerUrl.resultingAction.getParameter2().split(";");
|
||||
String[] components = ActivityManageActionTriggerUrl.resultingAction.getParameter2().split(";");
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
etTriggerUrl.setText(components[2]);
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityEditTriggerUrl.resultingAction.getParameter1());
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityManageActionTriggerUrl.resultingAction.getParameter1());
|
||||
etTriggerUrlUsername.setText(components[0]);
|
||||
etTriggerUrlPassword.setText(components[1]);
|
||||
}
|
||||
@ -141,9 +141,9 @@ public class ActivityEditTriggerUrl extends Activity
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter2(
|
||||
ActivityManageActionTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString()
|
@ -95,6 +95,10 @@ public class ActivityManageRule extends Activity
|
||||
final static int requestCodeActionScreenBrightnessAdd = 401;
|
||||
final static int requestCodeActionScreenBrightnessEdit = 402;
|
||||
final static int requestCodeActionSendTextMessage = 7001;
|
||||
final static int requestCodeTriggerNotificationAdd = 8000;
|
||||
final static int requestCodeTriggerNfcNotificationEdit = 8001;
|
||||
final static int requestCodeActionPlaySoundAdd = 501;
|
||||
final static int requestCodeActionPlaySoundEdit = 502;
|
||||
|
||||
public static ActivityManageRule getInstance()
|
||||
{
|
||||
@ -233,8 +237,8 @@ public class ActivityManageRule extends Activity
|
||||
// case speed:
|
||||
// break;
|
||||
case timeFrame:
|
||||
ActivityManageTimeFrame.editedTimeFrameTrigger = selectedTrigger;
|
||||
Intent timeFrameEditor = new Intent(ActivityManageRule.this, ActivityManageTimeFrame.class);
|
||||
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = selectedTrigger;
|
||||
Intent timeFrameEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerTimeFrame.class);
|
||||
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeEdit);
|
||||
break;
|
||||
// case usb_host_connection:
|
||||
@ -242,10 +246,16 @@ public class ActivityManageRule extends Activity
|
||||
// case wifiConnection:
|
||||
// break;
|
||||
case bluetoothConnection:
|
||||
ActivityManageBluetoothTrigger.editedBluetoothTrigger = selectedTrigger;
|
||||
Intent bluetoothEditor = new Intent(ActivityManageRule.this, ActivityManageBluetoothTrigger.class);
|
||||
ActivityManageTriggerBluetooth.editedBluetoothTrigger = selectedTrigger;
|
||||
Intent bluetoothEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerBluetooth.class);
|
||||
startActivityForResult(bluetoothEditor, requestCodeTriggerBluetoothEdit);
|
||||
break;
|
||||
case notification:
|
||||
ActivityManageTriggerNotification.editedNotificationTrigger = selectedTrigger;
|
||||
Intent notificationEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerNotification.class);
|
||||
notificationEditor.putExtra("edit", true);
|
||||
startActivityForResult(notificationEditor, requestCodeTriggerNfcNotificationEdit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -288,15 +298,15 @@ public class ActivityManageRule extends Activity
|
||||
// case setAirplaneMode:
|
||||
// break;
|
||||
case startOtherActivity:
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageStartActivity.class);
|
||||
ActivityManageStartActivity.resultingAction = a;
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
|
||||
ActivityManageActionStartActivity.resultingAction = a;
|
||||
intent.putExtra("edit", true);
|
||||
startActivityForResult(intent, requestCodeActionStartActivityEdit);
|
||||
break;
|
||||
case triggerUrl:
|
||||
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityEditTriggerUrl.class);
|
||||
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class);
|
||||
// activityEditTriggerUrlIntent.putExtra("urlToTrigger", a.getParameter2());
|
||||
ActivityEditTriggerUrl.resultingAction = a;
|
||||
ActivityManageActionTriggerUrl.resultingAction = a;
|
||||
activityEditTriggerUrlIntent.putExtra("edit", true);
|
||||
startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit);
|
||||
break;
|
||||
@ -321,24 +331,31 @@ public class ActivityManageRule extends Activity
|
||||
// case wakeupDevice:
|
||||
// break;
|
||||
case speakText:
|
||||
Intent activitySpeakTextIntent = new Intent(ActivityManageRule.this, ActivityEditSpeakText.class);
|
||||
ActivityEditSpeakText.resultingAction = a;
|
||||
Intent activitySpeakTextIntent = new Intent(ActivityManageRule.this, ActivityManageActionSpeakText.class);
|
||||
ActivityManageActionSpeakText.resultingAction = a;
|
||||
activitySpeakTextIntent.putExtra("edit", true);
|
||||
startActivityForResult(activitySpeakTextIntent, requestCodeActionSpeakTextEdit);
|
||||
break;
|
||||
case sendTextMessage:
|
||||
Intent activitySendTextMessageIntent = new Intent(ActivityManageRule.this, ActivityEditSendTextMessage.class);
|
||||
ActivityEditSendTextMessage.resultingAction = a;
|
||||
Intent activitySendTextMessageIntent = new Intent(ActivityManageRule.this, ActivityManageActionSendTextMessage.class);
|
||||
ActivityManageActionSendTextMessage.resultingAction = a;
|
||||
activitySendTextMessageIntent.putExtra("edit", true);
|
||||
startActivityForResult(activitySendTextMessageIntent, requestCodeActionSendTextMessage);
|
||||
break;
|
||||
case setScreenBrightness:
|
||||
Intent activityEditScreenBrightnessIntent = new Intent(ActivityManageRule.this, ActivityManageBrightnessSetting.class);
|
||||
Intent activityEditScreenBrightnessIntent = new Intent(ActivityManageRule.this, ActivityManageActionBrightnessSetting.class);
|
||||
// ActivityEditTriggerUrl.resultingAction = a;
|
||||
activityEditScreenBrightnessIntent.putExtra("autoBrightness", a.getParameter1());
|
||||
activityEditScreenBrightnessIntent.putExtra("brightnessValue", Integer.parseInt(a.getParameter2()));
|
||||
startActivityForResult(activityEditScreenBrightnessIntent, requestCodeActionScreenBrightnessEdit);
|
||||
break;
|
||||
case playSound:
|
||||
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
|
||||
actionPlaySoundIntent.putExtra("edit", true);
|
||||
actionPlaySoundIntent.putExtra("actionParameter1", a.getParameter1());
|
||||
actionPlaySoundIntent.putExtra("actionParameter2", a.getParameter2());
|
||||
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundEdit);
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Edit action", "Editing of action type " + a.getAction().toString() + " not implemented, yet.", 4);
|
||||
break;
|
||||
@ -466,6 +483,8 @@ public class ActivityManageRule extends Activity
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.bluetooth));
|
||||
else if(types[i].toString().equals(Trigger_Enum.headsetPlugged.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.headphone));
|
||||
else if(types[i].toString().equals(Trigger_Enum.notification.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.notification));
|
||||
else
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
@ -521,8 +540,8 @@ public class ActivityManageRule extends Activity
|
||||
else if(triggerType == Trigger_Enum.timeFrame)
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
|
||||
ActivityManageTimeFrame.editedTimeFrameTrigger = newTrigger;
|
||||
Intent timeFrameEditor = new Intent(myContext, ActivityManageTimeFrame.class);
|
||||
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = newTrigger;
|
||||
Intent timeFrameEditor = new Intent(myContext, ActivityManageTriggerTimeFrame.class);
|
||||
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeAdd);
|
||||
return;
|
||||
}
|
||||
@ -536,6 +555,13 @@ public class ActivityManageRule extends Activity
|
||||
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)
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNotification.class);
|
||||
startActivityForResult(nfcEditor, requestCodeTriggerNotificationAdd);
|
||||
return;
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.airplaneMode)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
|
||||
else if(triggerType == Trigger_Enum.roaming)
|
||||
@ -572,7 +598,7 @@ public class ActivityManageRule extends Activity
|
||||
if(NfcReceiver.checkNfcRequirements(ActivityManageRule.this, true))
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
|
||||
Intent nfcEditor = new Intent(myContext, ActivityManageNfc.class);
|
||||
Intent nfcEditor = new Intent(myContext, ActivityManageTriggerNfc.class);
|
||||
startActivityForResult(nfcEditor, requestCodeTriggerNfcTagAdd);
|
||||
return;
|
||||
}
|
||||
@ -583,8 +609,8 @@ public class ActivityManageRule extends Activity
|
||||
Miscellaneous.messageBox("Bluetooth", getResources().getString(R.string.deviceDoesNotHaveBluetooth), ActivityManageRule.this).show();;
|
||||
|
||||
newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
|
||||
ActivityManageBluetoothTrigger.editedBluetoothTrigger = newTrigger;
|
||||
Intent bluetoothEditor = new Intent(myContext, ActivityManageBluetoothTrigger.class);
|
||||
ActivityManageTriggerBluetooth.editedBluetoothTrigger = newTrigger;
|
||||
Intent bluetoothEditor = new Intent(myContext, ActivityManageTriggerBluetooth.class);
|
||||
startActivityForResult(bluetoothEditor, requestCodeTriggerBluetoothAdd);
|
||||
return;
|
||||
}
|
||||
@ -979,7 +1005,7 @@ public class ActivityManageRule extends Activity
|
||||
protected String[] doInBackground(ActivityManageRule... params)
|
||||
{
|
||||
// Looper.prepare();
|
||||
final String[] applicationArray = ActivityManageStartActivity.getApplicationNameListString(params[0]);
|
||||
final String[] applicationArray = ActivityManageActionStartActivity.getApplicationNameListString(params[0]);
|
||||
return applicationArray;
|
||||
}
|
||||
|
||||
@ -1026,7 +1052,7 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(myContext);
|
||||
alertDialogBuilder.setTitle(myContext.getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageStartActivity.getPackageListString(myContext, applicationName);
|
||||
final String[] packageArray = ActivityManageActionStartActivity.getPackageListString(myContext, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -1046,7 +1072,7 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(myContext);
|
||||
alertDialogBuilder.setTitle(myContext.getResources().getString(R.string.selectActivityToBeStarted));
|
||||
final String activityArray[] = ActivityManageStartActivity.getActivityListForPackageName(packageName);
|
||||
final String activityArray[] = ActivityManageActionStartActivity.getActivityListForPackageName(packageName);
|
||||
alertDialogBuilder.setItems(activityArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
@ -1074,7 +1100,7 @@ public class ActivityManageRule extends Activity
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
//add TriggerUrl
|
||||
ruleToEdit.getActionSet().add(ActivityEditTriggerUrl.resultingAction);
|
||||
ruleToEdit.getActionSet().add(ActivityManageActionTriggerUrl.resultingAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
@ -1089,7 +1115,7 @@ public class ActivityManageRule extends Activity
|
||||
else if(requestCode == requestCodeTriggerTimeframeAdd)
|
||||
{
|
||||
//add TimeFrame
|
||||
if(resultCode == RESULT_OK && ActivityManageTimeFrame.editedTimeFrameTrigger != null)
|
||||
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
|
||||
{
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
@ -1100,7 +1126,7 @@ public class ActivityManageRule extends Activity
|
||||
else if(requestCode == requestCodeTriggerTimeframeEdit)
|
||||
{
|
||||
//edit TimeFrame
|
||||
if(resultCode == RESULT_OK && ActivityManageTimeFrame.editedTimeFrameTrigger != null)
|
||||
if(resultCode == RESULT_OK && ActivityManageTriggerTimeFrame.editedTimeFrameTrigger != null)
|
||||
{
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
@ -1112,7 +1138,7 @@ public class ActivityManageRule extends Activity
|
||||
// manage start of other activity
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction = ActivityManageStartActivity.resultingAction;
|
||||
newAction = ActivityManageActionStartActivity.resultingAction;
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
@ -1122,7 +1148,7 @@ public class ActivityManageRule extends Activity
|
||||
// manage start of other activity
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction = ActivityManageStartActivity.resultingAction;
|
||||
newAction = ActivityManageActionStartActivity.resultingAction;
|
||||
// ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
@ -1130,21 +1156,49 @@ public class ActivityManageRule extends Activity
|
||||
else if(requestCode == requestCodeTriggerNfcTagAdd)
|
||||
{
|
||||
//add TimeFrame
|
||||
if(resultCode == RESULT_OK && ActivityManageNfc.generatedId != null)
|
||||
if(resultCode == RESULT_OK && ActivityManageTriggerNfc.generatedId != null)
|
||||
{
|
||||
newTrigger.setNfcTagId(ActivityManageNfc.generatedId);
|
||||
newTrigger.setNfcTagId(ActivityManageTriggerNfc.generatedId);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "ActivityManageNfc", "No nfc id returned. Assuming abort.", 5);
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerNotificationAdd)
|
||||
{
|
||||
//add notification
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
//newTrigger.setNfcTagId(ActivityManageNfc.generatedId);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
|
||||
newTrigger.setTriggerParameter2(
|
||||
data.getStringExtra("app") + Trigger.triggerParameter2Split +
|
||||
data.getStringExtra("titleDir") + Trigger.triggerParameter2Split +
|
||||
data.getStringExtra("title") + Trigger.triggerParameter2Split +
|
||||
data.getStringExtra("textDir") + Trigger.triggerParameter2Split +
|
||||
data.getStringExtra("text")
|
||||
);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "ActivityManageNfc", "No nfc id returned. Assuming abort.", 5);
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerNfcNotificationEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger = ActivityManageTriggerNotification.resultingTrigger;
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSpeakTextAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
//add SpeakText
|
||||
ruleToEdit.getActionSet().add(ActivityEditSpeakText.resultingAction);
|
||||
ruleToEdit.getActionSet().add(ActivityManageActionSpeakText.resultingAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
@ -1153,14 +1207,14 @@ public class ActivityManageRule extends Activity
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
//add SpeakText
|
||||
ruleToEdit.getActionSet().add(ActivityEditSendTextMessage.resultingAction);
|
||||
ruleToEdit.getActionSet().add(ActivityManageActionSendTextMessage.resultingAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerBluetoothAdd)
|
||||
{
|
||||
//add bluetooth trigger
|
||||
if(resultCode == RESULT_OK && ActivityManageBluetoothTrigger.editedBluetoothTrigger != null)
|
||||
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
|
||||
{
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
@ -1171,7 +1225,7 @@ public class ActivityManageRule extends Activity
|
||||
else if(requestCode == requestCodeTriggerBluetoothEdit)
|
||||
{
|
||||
//edit bluetooth trigger
|
||||
if(resultCode == RESULT_OK && ActivityManageBluetoothTrigger.editedBluetoothTrigger != null)
|
||||
if(resultCode == RESULT_OK && ActivityManageTriggerBluetooth.editedBluetoothTrigger != null)
|
||||
{
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
@ -1201,6 +1255,29 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionPlaySoundAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction.setParameter1(data.getBooleanExtra("actionParameter1", false));
|
||||
newAction.setParameter2(data.getStringExtra("actionParameter2"));
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionPlaySoundEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
if(data.hasExtra("actionParameter1"))
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter1(data.getBooleanExtra("actionParameter1", false));
|
||||
|
||||
if(data.hasExtra("actionParameter2"))
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("actionParameter2"));
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Check with has data been changed or something like that.
|
||||
/*try
|
||||
@ -1253,6 +1330,8 @@ public class ActivityManageRule extends Activity
|
||||
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()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
|
||||
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
|
||||
{
|
||||
// if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageSpecificRule.this, "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(ActivityManageSpecificRule.this))
|
||||
@ -1263,13 +1342,6 @@ public class ActivityManageRule extends Activity
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.placeholder));
|
||||
}
|
||||
|
||||
// = {
|
||||
// new Item("Bluetooth", R.drawable.bluetooth),
|
||||
// new Item("Wifi", R.drawable.wifi),
|
||||
// new Item("...", 0), //no icon for this one
|
||||
// };
|
||||
|
||||
// ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items)
|
||||
ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items)
|
||||
{
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
@ -1302,8 +1374,8 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
//launch other activity to enter a url and parameters;
|
||||
newAction.setAction(Action_Enum.triggerUrl);
|
||||
ActivityEditTriggerUrl.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityEditTriggerUrl.class);
|
||||
ActivityManageActionTriggerUrl.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityManageActionTriggerUrl.class);
|
||||
startActivityForResult(editTriggerIntent, 1000);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifi.toString()))
|
||||
@ -1350,7 +1422,7 @@ public class ActivityManageRule extends Activity
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.startOtherActivity.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.startOtherActivity);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageStartActivity.class);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
|
||||
startActivityForResult(intent, 3000);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.waitBeforeNextAction.toString()))
|
||||
@ -1383,8 +1455,8 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
//launch other activity to enter a url and parameters;
|
||||
newAction.setAction(Action_Enum.speakText);
|
||||
ActivityEditSpeakText.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityEditSpeakText.class);
|
||||
ActivityManageActionSpeakText.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityManageActionSpeakText.class);
|
||||
startActivityForResult(editTriggerIntent, 5000);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString()))
|
||||
@ -1394,8 +1466,8 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
//launch other activity to enter parameters;
|
||||
newAction.setAction(Action_Enum.sendTextMessage);
|
||||
ActivityEditSendTextMessage.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityEditSendTextMessage.class);
|
||||
ActivityManageActionSendTextMessage.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityManageActionSendTextMessage.class);
|
||||
startActivityForResult(editTriggerIntent, 5001);
|
||||
}
|
||||
}
|
||||
@ -1408,9 +1480,15 @@ public class ActivityManageRule extends Activity
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setScreenBrightness.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
Intent actionScreenBrightnessIntent = new Intent(context, ActivityManageBrightnessSetting.class);
|
||||
Intent actionScreenBrightnessIntent = new Intent(context, ActivityManageActionBrightnessSetting.class);
|
||||
startActivityForResult(actionScreenBrightnessIntent, requestCodeActionScreenBrightnessAdd);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.playSound.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.playSound);
|
||||
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
|
||||
startActivityForResult(actionPlaySoundIntent, requestCodeActionPlaySoundAdd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
|
||||
public class ActivityManageBluetoothTrigger extends Activity
|
||||
public class ActivityManageTriggerBluetooth extends Activity
|
||||
{
|
||||
protected static Trigger editedBluetoothTrigger;
|
||||
RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange;
|
||||
@ -109,7 +109,7 @@ public class ActivityManageBluetoothTrigger extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(ActivityManageBluetoothTrigger.this, getResources().getString(R.string.selectDeviceOption), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerBluetooth.this, getResources().getString(R.string.selectDeviceOption), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ public class ActivityManageBluetoothTrigger extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(ActivityManageBluetoothTrigger.this, getResources().getString(R.string.selectConnectionOption), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerBluetooth.this, getResources().getString(R.string.selectConnectionOption), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import android.widget.Toast;
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityManageNfc extends Activity
|
||||
public class ActivityManageTriggerNfc extends Activity
|
||||
{
|
||||
public static String generatedId = null;
|
||||
private static Tag discoveredTag = null;
|
||||
@ -39,7 +39,7 @@ public class ActivityManageNfc extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_nfc);
|
||||
setContentView(R.layout.activity_manage_trigger_nfc);
|
||||
|
||||
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
|
||||
bReadNfcTag = (Button)findViewById(R.id.bReadNfcTag);
|
||||
@ -59,7 +59,7 @@ public class ActivityManageNfc extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
progressDialog = ProgressDialog.show(ActivityManageTriggerNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
@ -88,7 +88,7 @@ public class ActivityManageNfc extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
progressDialog = ProgressDialog.show(ActivityManageTriggerNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
@ -118,7 +118,7 @@ public class ActivityManageNfc extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
progressDialog = ProgressDialog.show(ActivityManageTriggerNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
@ -255,7 +255,7 @@ public class ActivityManageNfc extends Activity
|
||||
if(generatedId.length() == 0)
|
||||
{
|
||||
generatedId = null;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcEnterValidIdentifier), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerNfc.this, getResources().getString(R.string.nfcEnterValidIdentifier), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -267,14 +267,14 @@ public class ActivityManageNfc extends Activity
|
||||
if(NfcReceiver.writeTag(generatedId, discoveredTag))
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagWrittenSuccessfully), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerNfc.this, getResources().getString(R.string.nfcTagWrittenSuccessfully), Toast.LENGTH_LONG).show();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagWriteError), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerNfc.this, getResources().getString(R.string.nfcTagWriteError), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("e", "NFC", getResources().getString(R.string.nfcTagWriteError), 2);
|
||||
}
|
||||
}
|
||||
@ -285,14 +285,14 @@ public class ActivityManageNfc extends Activity
|
||||
if(checkEnteredText(false))
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagReadSuccessfully), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerNfc.this, getResources().getString(R.string.nfcTagReadSuccessfully), Toast.LENGTH_LONG).show();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcValueNotSuitable), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(ActivityManageTriggerNfc.this, getResources().getString(R.string.nfcValueNotSuitable), Toast.LENGTH_LONG).show();
|
||||
generatedId = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,399 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class ActivityManageTriggerNotification extends Activity
|
||||
{
|
||||
public static Trigger editedNotificationTrigger;
|
||||
EditText etNotificationTitle, etNotificationText;
|
||||
Button bSelectApp, bSaveTriggerNotification;
|
||||
Spinner spinnerTitleDirection, spinnerTextDirection;
|
||||
TextView tvSelectedApplication;
|
||||
CheckBox chkNotificationDirection;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
public static Trigger resultingTrigger;
|
||||
|
||||
private static String[] directions;
|
||||
|
||||
ArrayAdapter<String> directionSpinnerAdapter;
|
||||
|
||||
public static void getActivityList(final Context context)
|
||||
{
|
||||
if(pInfos == null)
|
||||
{
|
||||
pInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
|
||||
Collections.sort(pInfos, new Comparator<PackageInfo>()
|
||||
{
|
||||
public int compare(PackageInfo obj1, PackageInfo obj2)
|
||||
{
|
||||
String name1 = "";
|
||||
String name2 = "";
|
||||
|
||||
ApplicationInfo aInfo1 = obj1.applicationInfo;
|
||||
if (aInfo1 != null)
|
||||
{
|
||||
name1 = (String) context.getPackageManager().getApplicationLabel(aInfo1);
|
||||
}
|
||||
ApplicationInfo aInfo2 = obj2.applicationInfo;
|
||||
if (aInfo2 != null)
|
||||
{
|
||||
name2 = (String) context.getPackageManager().getApplicationLabel(aInfo2);
|
||||
}
|
||||
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getApplicationNameListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ApplicationInfo aInfo = pInfo.applicationInfo;
|
||||
if (aInfo != null)
|
||||
{
|
||||
String aLabel;
|
||||
|
||||
aLabel = (String) myContext.getPackageManager().getApplicationLabel(aInfo);
|
||||
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0) // Only put Applications into the list that have packages.
|
||||
{
|
||||
if(!returnList.contains(aLabel))
|
||||
returnList.add(aLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext, String applicationLabel)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo).equals(applicationLabel))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Empty Application", "Application " + myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo) + " doesn\'t have packages.", 5);
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getActivityListForPackageName(String packageName)
|
||||
{
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
returnList.add(activityInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static ActivityInfo getActivityInfoForPackageNameAndActivityName(String packageName, String activityName)
|
||||
{
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
if(activityInfo.name.equals(activityName))
|
||||
return activityInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AlertDialog getActionStartActivityDialog1()
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
|
||||
final String[] applicationArray = ActivityManageTriggerNotification.getApplicationNameListString(this);
|
||||
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
getActionStartActivityDialog2(applicationArray[which]).show();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog2(String applicationName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageTriggerNotification.getPackageListString(this, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
//getActionStartActivityDialog3(packageArray[which]).show();
|
||||
//Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageNotificationTrigger.this).show();
|
||||
tvSelectedApplication.setText(packageArray[which]);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog3(final String packageName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
|
||||
final String activityArray[] = ActivityManageTriggerNotification.getActivityListForPackageName(packageName);
|
||||
alertDialogBuilder.setItems(activityArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageTriggerNotification.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
tvSelectedApplication.setText(ai.packageName + ";" + ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_trigger_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bSaveTriggerNotification = (Button)findViewById(R.id.bSaveTriggerNotification);
|
||||
spinnerTitleDirection = (Spinner)findViewById(R.id.spinnerTitleDirection);
|
||||
spinnerTextDirection = (Spinner)findViewById(R.id.spinnerTextDirection);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etSelectedApplication);
|
||||
chkNotificationDirection = (CheckBox)findViewById(R.id.chkNotificationDirection);
|
||||
|
||||
directions = new String[] {
|
||||
getResources().getString(R.string.directionStringEquals),
|
||||
getResources().getString(R.string.directionStringContains),
|
||||
getResources().getString(R.string.directionStringStartsWith),
|
||||
getResources().getString(R.string.directionStringEndsWith),
|
||||
getResources().getString(R.string.directionStringNotEquals)
|
||||
};
|
||||
|
||||
directionSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageTriggerNotification.directions);
|
||||
spinnerTitleDirection.setAdapter(directionSpinnerAdapter);
|
||||
spinnerTextDirection.setAdapter(directionSpinnerAdapter);
|
||||
directionSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageTriggerNotification.this, "", ActivityManageTriggerNotification.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
});
|
||||
|
||||
chkNotificationDirection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
chkNotificationDirection.setText(getResources().getString(R.string.notificationAppears));
|
||||
else
|
||||
chkNotificationDirection.setText(getResources().getString(R.string.notificationDisappears));
|
||||
}
|
||||
});
|
||||
|
||||
bSaveTriggerNotification.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
String app;
|
||||
if(tvSelectedApplication.getText().toString().equalsIgnoreCase(getResources().getString(R.string.anyApp)))
|
||||
app = "-1";
|
||||
else
|
||||
app = tvSelectedApplication.getText().toString();
|
||||
|
||||
String titleDir = Trigger.getMatchCode(spinnerTitleDirection.getSelectedItem().toString());
|
||||
String title = etNotificationTitle.getText().toString();
|
||||
String textDir = Trigger.getMatchCode(spinnerTextDirection.getSelectedItem().toString());
|
||||
String text = etNotificationText.getText().toString();
|
||||
|
||||
if(edit)
|
||||
{
|
||||
editedNotificationTrigger.setTriggerParameter(chkNotificationDirection.isChecked());
|
||||
editedNotificationTrigger.setTriggerParameter2(app + triggerParameter2Split + titleDir + triggerParameter2Split + title + triggerParameter2Split + textDir + triggerParameter2Split + text);
|
||||
ActivityManageTriggerNotification.this.setResult(RESULT_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent data = new Intent();
|
||||
data.putExtra("direction", chkNotificationDirection.isChecked());
|
||||
data.putExtra("app", app);
|
||||
data.putExtra("titleDir", titleDir);
|
||||
data.putExtra("title", title);
|
||||
data.putExtra("textDir", textDir);
|
||||
data.putExtra("text", text);
|
||||
ActivityManageTriggerNotification.this.setResult(RESULT_OK, data);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
chkNotificationDirection.setChecked(editedNotificationTrigger.getTriggerParameter());
|
||||
|
||||
String[] params = editedNotificationTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
String app = params[0];
|
||||
String titleDir = params[1];
|
||||
String title = params[2];
|
||||
String textDir = params[3];
|
||||
String text;
|
||||
if (params.length >= 5)
|
||||
text = params[4];
|
||||
else
|
||||
text = "";
|
||||
|
||||
if(!app.equals("-1"))
|
||||
tvSelectedApplication.setText(app);
|
||||
|
||||
for(int i = 0; i < directions.length; i++)
|
||||
{
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(titleDir))
|
||||
spinnerTitleDirection.setSelection(i);
|
||||
|
||||
if(Trigger.getMatchCode(directions[i]).equalsIgnoreCase(textDir))
|
||||
spinnerTextDirection.setSelection(i);
|
||||
}
|
||||
|
||||
if(title.length() > 0)
|
||||
etNotificationTitle.setText(title);
|
||||
|
||||
if(text.length() > 0)
|
||||
etNotificationText.setText(text);
|
||||
}
|
||||
|
||||
private class GetActivityListTask extends AsyncTask<Void, Void, Void>
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
getActivityList(ActivityManageTriggerNotification.this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class ActivityManageTimeFrame extends Activity
|
||||
public class ActivityManageTriggerTimeFrame extends Activity
|
||||
{
|
||||
Button bSaveTimeFrame;
|
||||
TimePicker startPicker, stopPicker;
|
||||
@ -27,7 +27,7 @@ public class ActivityManageTimeFrame extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.trigger_timeframe_editor);
|
||||
setContentView(R.layout.manage_trigger_timeframe);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
|
@ -2,6 +2,7 @@ package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
@ -15,6 +16,8 @@ import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -34,12 +37,13 @@ public class ActivityPermissions extends Activity
|
||||
private static final int requestCodeForPermissionsWriteSettings = 12043;
|
||||
private static final int requestCodeForPermissionsNotificationPolicy = 12044;
|
||||
private static final int requestCodeForPermissionsBackgroundLocation = 12045;
|
||||
private static final int requestCodeForPermissionsNotifications = 12046;
|
||||
protected String[] specificPermissionsToRequest = null;
|
||||
|
||||
public static String intentExtraName = "permissionsToBeRequested";
|
||||
|
||||
Button bCancelPermissions, bRequestPermissions;
|
||||
TextView tvPermissionsExplanation, tvPermissionosExplanationSystemSettings, tvPermissionsExplanationLong;
|
||||
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong;
|
||||
static ActivityPermissions instance = null;
|
||||
|
||||
public static final String writeSystemSettingsPermissionName = "android.permission.WRITE_SETTINGS";
|
||||
@ -50,6 +54,7 @@ public class ActivityPermissions extends Activity
|
||||
public static final String permissionNameLocationBackground = "android.permission.ACCESS_BACKGROUND_LOCATION";
|
||||
public static final String permissionNameCall = "android.permission.PROCESS_OUTGOING_CALLS";
|
||||
public static final String permissionNameStartService = "android.permission.FOREGROUND_SERVICE";
|
||||
public static final String permissionNameReadNotifications = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
|
||||
|
||||
public static ActivityPermissions getInstance()
|
||||
{
|
||||
@ -72,7 +77,7 @@ public class ActivityPermissions extends Activity
|
||||
bCancelPermissions = (Button)findViewById(R.id.bCancelPermissions);
|
||||
bRequestPermissions = (Button)findViewById(R.id.bRequestPermissions);
|
||||
tvPermissionsExplanation = (TextView)findViewById(R.id.tvPermissionsExplanation);
|
||||
tvPermissionosExplanationSystemSettings = (TextView)findViewById(R.id.tvPermissionsExplanationSystemSettings);
|
||||
tvPermissionsExplanationSystemSettings = (TextView)findViewById(R.id.tvPermissionsExplanationSystemSettings);
|
||||
tvPermissionsExplanationLong = (TextView)findViewById(R.id.tvPermissionsExplanationLong);
|
||||
|
||||
bCancelPermissions.setOnClickListener(new View.OnClickListener()
|
||||
@ -168,8 +173,6 @@ public class ActivityPermissions extends Activity
|
||||
explanation.append(
|
||||
|
||||
"<br />" +
|
||||
|
||||
|
||||
"<u>" +
|
||||
getResources().getString(R.string.readLocation)
|
||||
+ "</u>"
|
||||
@ -188,8 +191,6 @@ public class ActivityPermissions extends Activity
|
||||
explanation.append(
|
||||
|
||||
"<br />" +
|
||||
|
||||
|
||||
"<u>" +
|
||||
getResources().getString(getResources().getIdentifier(s, "string", getPackageName()))
|
||||
+ "</u>"
|
||||
@ -208,9 +209,9 @@ public class ActivityPermissions extends Activity
|
||||
if (s.equalsIgnoreCase(writeSystemSettingsPermissionName))
|
||||
{
|
||||
if (requiredPerms.length == 1)
|
||||
tvPermissionosExplanationSystemSettings.setText(getResources().getString(R.string.systemSettingsNote1));
|
||||
tvPermissionsExplanationSystemSettings.setText(getResources().getString(R.string.systemSettingsNote1));
|
||||
else if (requiredPerms.length > 1)
|
||||
tvPermissionosExplanationSystemSettings.setText(getResources().getString(R.string.systemSettingsNote1) + getResources().getString(R.string.systemSettingsNote2));
|
||||
tvPermissionsExplanationSystemSettings.setText(getResources().getString(R.string.systemSettingsNote1) + getResources().getString(R.string.systemSettingsNote2));
|
||||
|
||||
break;
|
||||
}
|
||||
@ -231,7 +232,25 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
for (String s : getRequiredPermissions(false))
|
||||
{
|
||||
if(!s.equalsIgnoreCase(permissionNameLocationBackground) && !s.equalsIgnoreCase(permissionNameLocationFine) && !s.equalsIgnoreCase(permissionNameLocationCoarse) && Miscellaneous.googleToBlameForLocation(true))
|
||||
if(
|
||||
s.equalsIgnoreCase(permissionNameLocationBackground)
|
||||
||
|
||||
s.equalsIgnoreCase(permissionNameLocationFine)
|
||||
||
|
||||
s.equalsIgnoreCase(permissionNameLocationCoarse)
|
||||
)
|
||||
{
|
||||
if (!Miscellaneous.googleToBlameForLocation(true))
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
else if(s.equalsIgnoreCase("android.permission.ACTIVITY_RECOGNITION") || s.equalsIgnoreCase("com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
|
||||
{
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
@ -256,6 +275,10 @@ public class ActivityPermissions extends Activity
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else if (s.equals(permissionNameReadNotifications))
|
||||
{
|
||||
return verifyNotificationPermission();
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = context.checkCallingOrSelfPermission(s);
|
||||
@ -285,11 +308,14 @@ public class ActivityPermissions extends Activity
|
||||
// if (!havePermission(ActivityPermissions.writeExternalStoragePermissionName, workingContext))
|
||||
// addToArrayListUnique(ActivityPermissions.writeExternalStoragePermissionName, requiredPermissions);
|
||||
|
||||
if(!havePermission(writeSystemSettingsPermissionName, workingContext))
|
||||
{
|
||||
for (Profile profile : Profile.getProfileCollection())
|
||||
{
|
||||
if (profile.changeIncomingCallsRingtone)
|
||||
{
|
||||
addToArrayListUnique("android.permission.WRITE_SETTINGS", requiredPermissions);
|
||||
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,7 +326,24 @@ public class ActivityPermissions extends Activity
|
||||
for (String singlePermission : getPermissionsForRule(rule))
|
||||
if (!havePermission(singlePermission, workingContext))
|
||||
{
|
||||
if(!singlePermission.equalsIgnoreCase(permissionNameLocationBackground) && !singlePermission.equalsIgnoreCase(permissionNameLocationFine) && !singlePermission.equalsIgnoreCase(permissionNameLocationCoarse) && Miscellaneous.googleToBlameForLocation(true))
|
||||
if(
|
||||
|
||||
singlePermission.equalsIgnoreCase(permissionNameLocationBackground)
|
||||
||
|
||||
singlePermission.equalsIgnoreCase(permissionNameLocationFine)
|
||||
||
|
||||
singlePermission.equalsIgnoreCase(permissionNameLocationCoarse)
|
||||
)
|
||||
{
|
||||
if (!Miscellaneous.googleToBlameForLocation(true))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
else if(singlePermission.equalsIgnoreCase("android.permission.ACTIVITY_RECOGNITION") || singlePermission.equalsIgnoreCase("com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
|
||||
{
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
else
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
}
|
||||
@ -360,7 +403,7 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
|
||||
break;
|
||||
case batteryLevel:
|
||||
addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
|
||||
// addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
|
||||
// addToArrayListUnique("android.permission.BATTERY_STATS", requiredPermissions);
|
||||
break;
|
||||
case bluetoothConnection:
|
||||
@ -425,6 +468,9 @@ public class ActivityPermissions extends Activity
|
||||
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
|
||||
addToArrayListUnique("android.permission.ACCESS_WIFI_STATE", requiredPermissions);
|
||||
break;
|
||||
case notification:
|
||||
addToArrayListUnique(permissionNameReadNotifications, requiredPermissions);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -600,6 +646,11 @@ public class ActivityPermissions extends Activity
|
||||
break;
|
||||
case "android.permission.WRITE_EXTERNAL_STORAGE":
|
||||
usingElements.add(getResources().getString(R.string.storeSettings));
|
||||
break;
|
||||
case permissionNameReadNotifications:
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.notification))
|
||||
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
|
||||
|
||||
break;
|
||||
case "com.google.android.gms.permission.ACTIVITY_RECOGNITION":
|
||||
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
@ -783,6 +834,10 @@ public class ActivityPermissions extends Activity
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (requestCode == requestCodeForPermissionsNotifications)
|
||||
if(havePermission(permissionNameReadNotifications, ActivityPermissions.this))
|
||||
requestPermissions(cachedPermissionsToRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -842,6 +897,14 @@ public class ActivityPermissions extends Activity
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
|
||||
return;
|
||||
}
|
||||
else if (s.equalsIgnoreCase(permissionNameReadNotifications))
|
||||
{
|
||||
requiredPermissions.remove(s);
|
||||
cachedPermissionsToRequest = requiredPermissions;
|
||||
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
|
||||
startActivityForResult(intent, requestCodeForPermissionsNotifications);
|
||||
return;
|
||||
}
|
||||
// else if (s.equalsIgnoreCase(permissionNameLocationBackground) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
// {
|
||||
// requiredPermissions.remove(s);
|
||||
@ -1392,4 +1455,24 @@ public class ActivityPermissions extends Activity
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Boolean verifyNotificationPermission()
|
||||
{
|
||||
try
|
||||
{
|
||||
String theList = android.provider.Settings.Secure.getString(Miscellaneous.getAnyContext().getContentResolver(), "enabled_notification_listeners");
|
||||
String[] theListList = theList.split(":");
|
||||
String me = (new ComponentName(Miscellaneous.getAnyContext(), NotificationListener.class)).flattenToString();
|
||||
for (String next : theListList)
|
||||
{
|
||||
if (me.equals(next))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,8 @@ public class CompensateCrappyAndroidPaths
|
||||
* @param uri The Uri to query.
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
public static String getPath(final Context context, final Uri uri) {
|
||||
public static String getPath(final Context context, final Uri uri)
|
||||
{
|
||||
// check here to KITKAT or new version
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
String selection = null;
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.security.Provider;
|
||||
|
||||
public class FileShareProvider extends ContentProvider
|
||||
{
|
||||
@Override
|
||||
public boolean onCreate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType(@NonNull Uri uri)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
|
||||
{
|
||||
File cacheDir = getContext().getCacheDir();
|
||||
File privateFile = new File(cacheDir, Settings.zipFileName);
|
||||
|
||||
return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@ -22,6 +23,7 @@ import android.provider.MediaStore;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
@ -42,6 +44,8 @@ import org.w3c.dom.Element;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
@ -71,6 +75,9 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Scanner;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
@ -84,6 +91,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import static android.provider.CalendarContract.CalendarCache.URI;
|
||||
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
||||
import static com.jens.automation2.AutomationService.channelName;
|
||||
|
||||
@ -441,6 +449,25 @@ public class Miscellaneous extends Service
|
||||
return isEmulator;
|
||||
}
|
||||
|
||||
public static boolean compare(String direction, String needle, String haystack)
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case Trigger.directionEquals:
|
||||
return haystack.equalsIgnoreCase(needle);
|
||||
case Trigger.directionNotEquals:
|
||||
return !haystack.equalsIgnoreCase(needle);
|
||||
case Trigger.directionContains:
|
||||
return haystack.toLowerCase().contains(needle.toLowerCase());
|
||||
case Trigger.directionStartsWith:
|
||||
return haystack.toLowerCase().startsWith(needle.toLowerCase());
|
||||
case Trigger.directionEndsWith:
|
||||
return haystack.toLowerCase().endsWith(needle.toLowerCase());
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static int compareTimes(Time time1, Time time2)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
|
||||
@ -848,7 +875,7 @@ public class Miscellaneous extends Service
|
||||
mNotificationManager.notify(0, dismissableNotification);*/
|
||||
}
|
||||
|
||||
public static void createDismissableNotificationSdk26(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
static void createDismissableNotificationSdk26(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
@ -1207,4 +1234,103 @@ public class Miscellaneous extends Service
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void zip(String[] _files, String zipFileName)
|
||||
{
|
||||
int BUFFER = 2048;
|
||||
try
|
||||
{
|
||||
BufferedInputStream origin = null;
|
||||
FileOutputStream dest = new FileOutputStream(zipFileName);
|
||||
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
|
||||
dest));
|
||||
byte data[] = new byte[BUFFER];
|
||||
|
||||
for (int i = 0; i < _files.length; i++)
|
||||
{
|
||||
Log.v("Compress", "Adding: " + _files[i]);
|
||||
FileInputStream fi = new FileInputStream(_files[i]);
|
||||
origin = new BufferedInputStream(fi, BUFFER);
|
||||
|
||||
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
|
||||
out.putNextEntry(entry);
|
||||
int count;
|
||||
|
||||
while ((count = origin.read(data, 0, BUFFER)) != -1)
|
||||
{
|
||||
out.write(data, 0, count);
|
||||
}
|
||||
origin.close();
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unzip(String _zipFile, String _targetLocation)
|
||||
{
|
||||
int BUFFER = 2048;
|
||||
|
||||
try
|
||||
{
|
||||
FileInputStream fin = new FileInputStream(_zipFile);
|
||||
ZipInputStream zin = new ZipInputStream(fin);
|
||||
ZipEntry ze = null;
|
||||
while ((ze = zin.getNextEntry()) != null)
|
||||
{
|
||||
//create dir if required while unzipping
|
||||
if (ze.isDirectory())
|
||||
{
|
||||
// dirChecker(ze.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
|
||||
for (int c = zin.read(); c != -1; c = zin.read())
|
||||
{
|
||||
fout.write(c);
|
||||
}
|
||||
|
||||
zin.closeEntry();
|
||||
fout.close();
|
||||
}
|
||||
|
||||
}
|
||||
zin.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendEmail(Context context, String targetAddress, String subject, String message, Uri fileAttachment)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
emailIntent.setType("plain/text");
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{targetAddress});
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
|
||||
if (fileAttachment != null)
|
||||
{
|
||||
emailIntent.putExtra(Intent.EXTRA_STREAM, fileAttachment);
|
||||
}
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);
|
||||
context.startActivity(Intent.createChooser(emailIntent, "Sending email..."));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
Toast.makeText(context, "Request failed try again: "+ t.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean doesActivityExist(Intent intent, Context context)
|
||||
{
|
||||
return intent.resolveActivityInfo(context.getPackageManager(), 0) != null;
|
||||
}
|
||||
}
|
@ -68,7 +68,13 @@ public class News
|
||||
Calendar now = Calendar.getInstance();
|
||||
String newsContent;
|
||||
|
||||
String filePath = context.getFilesDir() + "/appNews.xml";
|
||||
String newsFileName = "appNews.xml";
|
||||
|
||||
String filePath = context.getCacheDir() + "/" + newsFileName;
|
||||
|
||||
File oldFilePath = new File(context.getFilesDir() + "/" + newsFileName);
|
||||
if(oldFilePath.exists())
|
||||
oldFilePath.delete();
|
||||
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == -1 || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
@ -80,14 +86,14 @@ public class News
|
||||
{
|
||||
Settings.lastNewsPolltime = now.getTimeInMillis();
|
||||
Settings.writeSettings(context);
|
||||
Miscellaneous.logEvent("i", "appNews.xml", "File stored to " + filePath, 5);
|
||||
Miscellaneous.logEvent("i", newsFileName, "File stored to " + filePath, 5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just read local cache file
|
||||
newsContent = Miscellaneous.readFileToString(filePath);
|
||||
Miscellaneous.logEvent("i", "appNews.xml", "Using cache to retrieve news: " + filePath, 5);
|
||||
Miscellaneous.logEvent("i", newsFileName, "Using cache to retrieve news: " + filePath, 5);
|
||||
}
|
||||
|
||||
ArrayList<News> returnList = new ArrayList<>();
|
||||
|
@ -273,24 +273,24 @@ public class ReceiverCoordinator
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
{
|
||||
Object runResult = Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "isActivityDetectionReceiverRunning", null);;
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);;
|
||||
if(runResult instanceof Boolean)
|
||||
{
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
if (isRunning)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "haveAllPermission", null);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "restartActivityDetectionReceiver", null);
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "restartActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.restartActivityDetectionReceiver();
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "haveAllPermission", null);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "startActivityDetectionReceiver", null);
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.startActivityDetectionReceiver();
|
||||
}
|
||||
}
|
||||
@ -304,7 +304,7 @@ public class ReceiverCoordinator
|
||||
if (isRunning)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4);
|
||||
Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null);
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "stopActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ public class Settings implements SharedPreferences
|
||||
public static final int newsPollEveryXDays = 3;
|
||||
public static final int newsDisplayForXDays = 3;
|
||||
public static final String folderName = "Automation";
|
||||
public static final String zipFileName = "automation.zip";
|
||||
|
||||
public static final String constNewsOptInDone ="newsOptInDone";
|
||||
|
||||
|
@ -21,7 +21,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, 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, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy
|
||||
|
||||
public String getFullName(Context context)
|
||||
{
|
||||
@ -59,6 +59,8 @@ public class Trigger
|
||||
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);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -67,6 +69,9 @@ public class Trigger
|
||||
};
|
||||
|
||||
private boolean triggerParameter; //if true->started event, if false->stopped
|
||||
private String triggerParameter2;
|
||||
|
||||
public static final String triggerParameter2Split = "tp2split";
|
||||
|
||||
private Trigger_Enum triggerType = null;
|
||||
private PointOfInterest pointOfInterest = null;
|
||||
@ -206,6 +211,16 @@ public class Trigger
|
||||
this.triggerParameter = triggerParameter;
|
||||
}
|
||||
|
||||
public String getTriggerParameter2()
|
||||
{
|
||||
return triggerParameter2;
|
||||
}
|
||||
|
||||
public void setTriggerParameter2(String triggerParameter2)
|
||||
{
|
||||
this.triggerParameter2 = triggerParameter2;
|
||||
}
|
||||
|
||||
public TimeFrame getTimeFrame()
|
||||
{
|
||||
return timeFrame;
|
||||
@ -216,7 +231,6 @@ public class Trigger
|
||||
this.timeFrame = timeFrame;
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
@ -440,6 +454,46 @@ public class Trigger
|
||||
else
|
||||
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.headsetDisconnected), type));
|
||||
break;
|
||||
case notification:
|
||||
if(this.getTriggerParameter2().contains(triggerParameter2Split))
|
||||
{
|
||||
String[] params = getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
String app = params[0];
|
||||
String titleDir = params[1];
|
||||
String title = params[2];
|
||||
String textDir = params[3];
|
||||
String text;
|
||||
if (params.length >= 5)
|
||||
text = params[4];
|
||||
else
|
||||
text = "";
|
||||
StringBuilder triggerBuilder = new StringBuilder();
|
||||
|
||||
String appString;
|
||||
if (app.equalsIgnoreCase("-1"))
|
||||
appString = Miscellaneous.getAnyContext().getResources().getString(R.string.anyApp);
|
||||
else
|
||||
appString = "app " + app;
|
||||
|
||||
if(triggerParameter)
|
||||
triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.postsNotification), appString));
|
||||
else
|
||||
triggerBuilder.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.removedNotification), appString));
|
||||
|
||||
if (title.length() > 0)
|
||||
triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.title) + " " + Trigger.getMatchString(titleDir) + " " + title);
|
||||
|
||||
if (text.length() > 0)
|
||||
triggerBuilder.append(", " + Miscellaneous.getAnyContext().getString(R.string.text) + " " + Trigger.getMatchString(textDir) + " " + text);
|
||||
|
||||
returnString.append(triggerBuilder.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
setTriggerParameter2("-1" + triggerParameter2Split + directionEquals + triggerParameter2Split + triggerParameter2Split + directionEquals + triggerParameter2Split + triggerParameter2Split);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
returnString.append("error");
|
||||
break;
|
||||
@ -448,6 +502,46 @@ public class Trigger
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
public static final String directionEquals = "eq";
|
||||
public static final String directionContains = "ct";
|
||||
public static final String directionStartsWith = "sw";
|
||||
public static final String directionEndsWith = "ew";
|
||||
public static final String directionNotEquals = "ne";
|
||||
|
||||
public static String getMatchString(String direction)
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case directionEquals:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.directionStringEquals);
|
||||
case directionContains:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.directionStringContains);
|
||||
case directionStartsWith:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith);
|
||||
case directionEndsWith:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.directionStringEndsWith);
|
||||
case directionNotEquals:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.directionStringNotEquals);
|
||||
default:
|
||||
return Miscellaneous.getAnyContext().getString(R.string.error);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMatchCode(String direction)
|
||||
{
|
||||
if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringEquals)))
|
||||
return directionEquals;
|
||||
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringContains)))
|
||||
return directionContains;
|
||||
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringStartsWith)))
|
||||
return directionStartsWith;
|
||||
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringEndsWith)))
|
||||
return directionEndsWith;
|
||||
else if(direction.equalsIgnoreCase(Miscellaneous.getAnyContext().getString(R.string.directionStringNotEquals)))
|
||||
return directionNotEquals;
|
||||
else
|
||||
return Miscellaneous.getAnyContext().getString(R.string.error);
|
||||
}
|
||||
|
||||
public static String[] getTriggerTypesAsArray()
|
||||
{
|
||||
|
@ -271,6 +271,8 @@ public class XmlFileInterface
|
||||
}
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.headsetPlugged)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getHeadphoneType()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.notification)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2()));
|
||||
serializer.endTag(null, "TriggerParameter2");
|
||||
serializer.endTag(null, "Trigger");
|
||||
}
|
||||
@ -377,7 +379,7 @@ public class XmlFileInterface
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch(FileNotFoundException e)
|
||||
{
|
||||
@ -392,12 +394,12 @@ public class XmlFileInterface
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -532,11 +534,11 @@ public class XmlFileInterface
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -749,13 +751,11 @@ public class XmlFileInterface
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
else if (name.equals("ActionCollection"))
|
||||
@ -766,13 +766,11 @@ public class XmlFileInterface
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -863,38 +861,45 @@ public class XmlFileInterface
|
||||
if (name.equals("TriggerEvent"))
|
||||
{
|
||||
String triggerEventString = readTag(parser, "TriggerEvent");
|
||||
if(triggerEventString.equals("pointOfInterest"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.pointOfInterest);
|
||||
else if(triggerEventString.equals("timeFrame"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.timeFrame);
|
||||
else if(triggerEventString.equals("charging"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.charging);
|
||||
else if(triggerEventString.equals("usb_host_connection"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.usb_host_connection);
|
||||
else if(triggerEventString.equals("batteryLevel"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
|
||||
else if(triggerEventString.equals("speed"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.speed);
|
||||
else if(triggerEventString.equals("noiseLevel"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.noiseLevel);
|
||||
else if(triggerEventString.equals("wifiConnection"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
else if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
|
||||
// if(triggerEventString.equals("pointOfInterest"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.pointOfInterest);
|
||||
// else if(triggerEventString.equals("timeFrame"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.timeFrame);
|
||||
// else if(triggerEventString.equals("charging"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.charging);
|
||||
// else if(triggerEventString.equals("usb_host_connection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.usb_host_connection);
|
||||
// else if(triggerEventString.equals("batteryLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
|
||||
// else if(triggerEventString.equals("speed"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.speed);
|
||||
// else if(triggerEventString.equals("noiseLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.noiseLevel);
|
||||
// else if(triggerEventString.equals("wifiConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
// else
|
||||
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
|
||||
else if(triggerEventString.equals("airplaneMode"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.airplaneMode);
|
||||
else if(triggerEventString.equals("roaming"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.roaming);
|
||||
else if(triggerEventString.equals("phoneCall"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
|
||||
else if(triggerEventString.equals("nfcTag"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.nfcTag);
|
||||
else if(triggerEventString.equals("activityDetection"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||
else if(triggerEventString.equals("bluetoothConnection"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
|
||||
else if(triggerEventString.equals("headsetPlugged"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.headsetPlugged);
|
||||
// else if(triggerEventString.equals("airplaneMode"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.airplaneMode);
|
||||
// else if(triggerEventString.equals("roaming"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.roaming);
|
||||
// else if(triggerEventString.equals("phoneCall"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.phoneCall);
|
||||
// else if(triggerEventString.equals("nfcTag"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.nfcTag);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
// else if(triggerEventString.equals("activityDetection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||
// else if(triggerEventString.equals("bluetoothConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
|
||||
// else if(triggerEventString.equals("headsetPlugged"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.headsetPlugged);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
else
|
||||
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
|
||||
}
|
||||
else if (name.equals("TriggerParameter1"))
|
||||
{
|
||||
@ -985,6 +990,8 @@ public class XmlFileInterface
|
||||
newTrigger.setHeadphoneType(-1);
|
||||
}
|
||||
}
|
||||
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1072,19 +1079,20 @@ public class XmlFileInterface
|
||||
{
|
||||
String actionNameString = readTag(parser, "ActionName");
|
||||
|
||||
if(actionNameString.equals("setWifi"))
|
||||
newAction.setAction(Action_Enum.setWifi);
|
||||
else if(actionNameString.equals("setBluetooth"))
|
||||
newAction.setAction(Action_Enum.setBluetooth);
|
||||
else if(actionNameString.equals("setUsbTethering"))
|
||||
newAction.setAction(Action_Enum.setUsbTethering);
|
||||
else if(actionNameString.equals("setWifiTethering"))
|
||||
newAction.setAction(Action_Enum.setWifiTethering);
|
||||
else if(actionNameString.equals("setDisplayRotation"))
|
||||
newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
// if(actionNameString.equals("setWifi"))
|
||||
// newAction.setAction(Action_Enum.setWifi);
|
||||
// else if(actionNameString.equals("setBluetooth"))
|
||||
// newAction.setAction(Action_Enum.setBluetooth);
|
||||
// else if(actionNameString.equals("setUsbTethering"))
|
||||
// newAction.setAction(Action_Enum.setUsbTethering);
|
||||
// else if(actionNameString.equals("setWifiTethering"))
|
||||
// newAction.setAction(Action_Enum.setWifiTethering);
|
||||
// else if(actionNameString.equals("setDisplayRotation"))
|
||||
// newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
|
||||
// *** deprecated
|
||||
else if(actionNameString.equals("turnWifiOn"))
|
||||
//else
|
||||
if(actionNameString.equals("turnWifiOn"))
|
||||
newAction.setAction(Action_Enum.turnWifiOn);
|
||||
else if(actionNameString.equals("turnWifiOff"))
|
||||
newAction.setAction(Action_Enum.turnWifiOff);
|
||||
@ -1106,28 +1114,30 @@ public class XmlFileInterface
|
||||
newAction.setAction(Action_Enum.disableScreenRotation);
|
||||
// *** deprecated
|
||||
|
||||
else if(actionNameString.equals("triggerUrl"))
|
||||
newAction.setAction(Action_Enum.triggerUrl);
|
||||
else if(actionNameString.equals("changeSoundProfile"))
|
||||
newAction.setAction(Action_Enum.changeSoundProfile);
|
||||
else if(actionNameString.equals("startOtherActivity"))
|
||||
newAction.setAction(Action_Enum.startOtherActivity);
|
||||
else if(actionNameString.equals("waitBeforeNextAction"))
|
||||
newAction.setAction(Action_Enum.waitBeforeNextAction);
|
||||
else if(actionNameString.equals("wakeupDevice"))
|
||||
newAction.setAction(Action_Enum.wakeupDevice);
|
||||
else if(actionNameString.equals("setAirplaneMode"))
|
||||
newAction.setAction(Action_Enum.setAirplaneMode);
|
||||
else if(actionNameString.equals("setDataConnection"))
|
||||
newAction.setAction(Action_Enum.setDataConnection);
|
||||
else if(actionNameString.equals("speakText"))
|
||||
newAction.setAction(Action_Enum.speakText);
|
||||
else if(actionNameString.equals("sendTextMessage"))
|
||||
newAction.setAction(Action_Enum.sendTextMessage);
|
||||
else if(actionNameString.equals("playMusic"))
|
||||
newAction.setAction(Action_Enum.playMusic);
|
||||
else if(actionNameString.equals("setScreenBrightness"))
|
||||
newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
// else if(actionNameString.equals("triggerUrl"))
|
||||
// newAction.setAction(Action_Enum.triggerUrl);
|
||||
// else if(actionNameString.equals("changeSoundProfile"))
|
||||
// newAction.setAction(Action_Enum.changeSoundProfile);
|
||||
// else if(actionNameString.equals("startOtherActivity"))
|
||||
// newAction.setAction(Action_Enum.startOtherActivity);
|
||||
// else if(actionNameString.equals("waitBeforeNextAction"))
|
||||
// newAction.setAction(Action_Enum.waitBeforeNextAction);
|
||||
// else if(actionNameString.equals("wakeupDevice"))
|
||||
// newAction.setAction(Action_Enum.wakeupDevice);
|
||||
// else if(actionNameString.equals("setAirplaneMode"))
|
||||
// newAction.setAction(Action_Enum.setAirplaneMode);
|
||||
// else if(actionNameString.equals("setDataConnection"))
|
||||
// newAction.setAction(Action_Enum.setDataConnection);
|
||||
// else if(actionNameString.equals("speakText"))
|
||||
// newAction.setAction(Action_Enum.speakText);
|
||||
// else if(actionNameString.equals("sendTextMessage"))
|
||||
// newAction.setAction(Action_Enum.sendTextMessage);
|
||||
// else if(actionNameString.equals("playMusic"))
|
||||
// newAction.setAction(Action_Enum.playMusic);
|
||||
// else if(actionNameString.equals("setScreenBrightness"))
|
||||
// newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
else
|
||||
newAction.setAction(Action_Enum.valueOf(actionNameString));
|
||||
}
|
||||
else if (name.equals("ActionParameter1"))
|
||||
{
|
||||
|
@ -0,0 +1,178 @@
|
||||
package com.jens.automation2.receivers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.Rule;
|
||||
import com.jens.automation2.Trigger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
// See here for reference: http://gmariotti.blogspot.com/2013/11/notificationlistenerservice-and-kitkat.html
|
||||
|
||||
@SuppressLint("OverrideAbstract")
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||
public class NotificationListener extends NotificationListenerService
|
||||
{
|
||||
static Calendar lastResponseToNotification = null;
|
||||
static NotificationListener instance;
|
||||
static SimpleNotification lastNotification = null;
|
||||
|
||||
// the title of the notification,
|
||||
public static final String EXTRA_TITLE = "android.title";
|
||||
|
||||
// the main text payload
|
||||
public static final String EXTRA_TEXT = "android.text";
|
||||
|
||||
// a third line of text, as supplied to
|
||||
public static final String EXTRA_SUB_TEXT = "android.subText";
|
||||
|
||||
// a bitmap to be used instead of the small icon when showing the notification payload
|
||||
public static final String EXTRA_LARGE_ICON = "android.largeIcon";
|
||||
|
||||
public static SimpleNotification getLastNotification()
|
||||
{
|
||||
return lastNotification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static NotificationListener getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
@Override
|
||||
public void onNotificationPosted(StatusBarNotification sbn)
|
||||
{
|
||||
super.onNotificationPosted(sbn);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(NotificationListener.this))
|
||||
checkNotification(true, sbn);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
@Override
|
||||
public void onNotificationRemoved(StatusBarNotification sbn)
|
||||
{
|
||||
super.onNotificationRemoved(sbn);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(NotificationListener.this))
|
||||
checkNotification(false, sbn);
|
||||
}
|
||||
|
||||
synchronized boolean checkNotification(boolean created, StatusBarNotification sbn)
|
||||
{
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
|
||||
lastNotification = new SimpleNotification();
|
||||
lastNotification.publishTime = Miscellaneous.calendarFromLong(sbn.getPostTime());
|
||||
lastNotification.created = created;
|
||||
lastNotification.app = app;
|
||||
lastNotification.title = title;
|
||||
lastNotification.text = text;
|
||||
|
||||
// if(lastResponseToNotification == null || lastResponseToNotification.getTimeInMillis() < lastNotification.publishTime.getTimeInMillis())
|
||||
// {
|
||||
// lastResponseToNotification = Calendar.getInstance();
|
||||
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||
{
|
||||
if (ruleCandidates.get(i).applies(NotificationListener.this))
|
||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("e", "NotificationCheck", "Ignoring notification as it is old.", 5);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class SimpleNotification
|
||||
{
|
||||
boolean created;
|
||||
Calendar publishTime;
|
||||
String app, title, text;
|
||||
|
||||
public Calendar getPublishTime()
|
||||
{
|
||||
return publishTime;
|
||||
}
|
||||
|
||||
public void setPublishTime(Calendar publishTime)
|
||||
{
|
||||
this.publishTime = publishTime;
|
||||
}
|
||||
|
||||
public boolean isCreated()
|
||||
{
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(boolean created)
|
||||
{
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getApp()
|
||||
{
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp(String app)
|
||||
{
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text)
|
||||
{
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListenerConnected()
|
||||
{
|
||||
super.onListenerConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListenerDisconnected()
|
||||
{
|
||||
super.onListenerDisconnected();
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable-hdpi/notification.png
Normal file
BIN
app/src/main/res/drawable-hdpi/notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -2,15 +2,21 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp" >
|
||||
android:layout_margin="@dimen/default_margin" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:stretchColumns="1"
|
||||
android:shrinkColumns="1" >
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@ -20,42 +26,56 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectApplication" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSelectedActivity"
|
||||
<EditText
|
||||
android:id="@+id/etSelectedApplication"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="10dp"
|
||||
android:background="#aa000000"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/parameterType"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
android:inputType="textMultiLine"
|
||||
android:text="@string/startAppChoiceNote" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/parameterType" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerParameterType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrentNfcIdValue"
|
||||
android:layout_width="wrap_content"
|
||||
@ -64,18 +84,15 @@
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etParameterName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" >
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
@ -84,10 +101,12 @@
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etParameterValue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
</LinearLayout>
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bAddIntentPair"
|
||||
@ -109,9 +128,11 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveActionStartOtherActivity"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
46
app/src/main/res/layout/activity_manage_play_sound.xml
Normal file
46
app/src/main/res/layout/activity_manage_play_sound.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/default_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="40dp"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/playSound" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkPlaySoundAlwaysPlay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alwaysPlay" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/alwaysPlayExplanation" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etSelectedSoundFile"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSelectSoundFile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectSoundFile" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSavePlaySound"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
@ -17,7 +17,7 @@
|
||||
android:background="@color/barBackgroundColor" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSelectedActivity"
|
||||
android:id="@+id/etSelectedApplication"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/general"
|
||||
|
@ -377,6 +377,13 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bShareConfigAndLog"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shareConfigAndLogFilesWithDev" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -84,18 +84,21 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/cmdTriggerAdd"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addTrigger" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cmdActionAdd"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/addAction" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cmdSaveRule"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/saveRule" />
|
||||
|
148
app/src/main/res/layout/manage_trigger_notification.xml
Normal file
148
app/src/main/res/layout/manage_trigger_notification.xml
Normal file
@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notification"
|
||||
android:textSize="25dp"
|
||||
android:layout_marginBottom="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
android:text="@string/notificationTriggerExplanation" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/direction"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chkNotificationDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notificationAppears"
|
||||
android:checked="true"/>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/application" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/etSelectedApplication"
|
||||
android:layout_marginHorizontal="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/anyApp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSelectApp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectApplication" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/title" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerTitleDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/text" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerTextDirection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotificationText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSaveTriggerNotification"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -31,7 +31,7 @@
|
||||
<CheckBoxPreference
|
||||
android:key="writeLogFile"
|
||||
android:summary="@string/onOff"
|
||||
android:title="@string/writeLogFileToSd" />
|
||||
android:title="@string/writeLogFile" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="logLevel"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20sp">
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
||||
<string name="generalSettings">Allgemeine Einstellungen</string>
|
||||
<string name="startAtSystemBoot">Beim Gerätestart mitstarten</string>
|
||||
<string name="onOff">Ein/aus</string>
|
||||
<string name="writeLogFileToSd">Protokoll auf SD Karte schreiben</string>
|
||||
<string name="writeLogFile">Protokoll schreiben</string>
|
||||
<string name="useTextToSpeechOnNormalSummary">TTS auf normal</string>
|
||||
<string name="useTextToSpeechOnVibrateSummary">TTS auf vibration</string>
|
||||
<string name="useTextToSpeechOnSilentSummary">TTS auf stumm</string>
|
||||
@ -598,4 +598,40 @@
|
||||
<string name="locationEngineDisabledShort">Die Position kann nicht mehr bestimmt werden.</string>
|
||||
<string name="locationEngineDisabledLong">Leider kann die Position nicht mehr bestimmt werden. Großer Dank dafür geht an Google für seine unendliche Weisheit und Großzügigkeit.\\n\\nBeginnend mit Android 10 wurde eine neue Berechtigung eingeführt, die benötigt wird, um als App die Position auch im Hintergrund bestimmen zu können, was, für eine App wie diese, natürlich notwendig ist.\\n\\nWährend ich das grundsätzlich für eine gute Idee halte, gilt das nicht für die Schikanen, die man Entwicklern damit zumutet.\\n\\nWenn man eine App entwickelt, kann man versuchen sich für diese Berechtigung zu qualifizieren, indem man einen Katalog von Bedingungen erfüllt. Leider wurden neue Versionen meiner Anwendung über einen Zeitraum von drei Monaten immer wieder abgelehnt.\\n\\nDas lief auf die immer gleiche Art ab:\\n\\nIch habe eine neue Version eingereicht, die all diese Anforderungen erfüllt hat.\\n\\nGoogles miserabler Entwickler-Support behauptete ich würde sie nicht einhalten.\\n\\nIch habe Beweise geliefert, daß ich alles einhalte.<br />Ich bekam eine Antwort wie "Ich kann Ihnen nicht weiterhelfen.\\n\\nIrgendwann habe ich aufgegeben.\\n\\nDie Folge davon ist nun, daß die Google Play Version keine Positionsbestimmung mehr im Hintergrund durchführen kann. Meine einzige Alternative wäre es gewesen, daß die ganze Anwendung aus dem Store fliegt.\\n\\nDas tut mir sehr leid, aber ich habe mein Bestes gegeben mit einem Kunden\"dienst\" zu diskutieren, der mehrfach beim Turing-Test durchgefallen ist.\\n\\nDie gute Nachricht: Die Anwendung kann es immer noch!\\n\\nAutomation ist nun Open Source Software und kann ab sofort bei F-Droid heruntergeladen werden. F-Droid ist ein freier Appstore, der Ihre Privatsphäre respektiert - statt nur so zu tun wie Google das macht.\\n\\nSichern Sie Ihre Konfiguratinsdatei, deinstallieren Sie dazu diese Anwendung, installieren sie von F-Droid neu, Konfigurationsdatei zurückspielen und fertig.\\n\\nKlicken Sie hier, um mehr herauszufinden:</string>
|
||||
<string name="filesStoredAt">Konfigurations- und Logdateien werden hier gespeichert: %1$s</string>
|
||||
<string name="directionStringEquals">ist gleich</string>
|
||||
<string name="directionStringContains">enthält</string>
|
||||
<string name="directionStringStartsWith">beginnt mit</string>
|
||||
<string name="directionStringEndsWith">endet mit</string>
|
||||
<string name="directionStringNotEquals">ist nicht gleich</string>
|
||||
<string name="positioningEngine">Ortungsroutine</string>
|
||||
<string name="googleSarcasm">Dank Google\'s unendlicher Weisheit und konstantem Unterfangen jederman\'s Privatsphäre zu schützen (Sarkasmus) müssen Auslöser und Aktionen, die SMS oder den Telefoniestatus betreffen, entfernt werden.</string>
|
||||
<string name="screenLockSoundNotice">Die Töne bei der Bildschirmsperre können ab Android 6 nicht mehr verändert werden. Was immer Sie hier einstellen, wird voraussichtlich nicht mehr funktionieren.</string>
|
||||
<string name="googleLocationChicaneryOld">Diese Anwendung sammelt Positionsdaten, um festzustellen, ob Sie sich gerade an einem der Orte aufhalten, die Sie definiert haben. Außerdem wird es benutzt, um Ihre Geschwindigkeit zu ermitteln, falls Sie diese in Regeln verwenden. Das wird auch dann gemacht, wenn das Programm nicht im Vordergrund ist (aber nur, wenn der Dienst aktiv ist).</string>
|
||||
<string name="error">Fehler</string>
|
||||
<string name="featureNotInFdroidVersion">Diese Funktion basiert auf nicht-freier Software (Google Bibliotheken). Daher ist sie in der F-Droid Version nicht verfügbar.</string>
|
||||
<string name="settingsReferringToRestrictedFeatures">Ihre Einstellungen und Regeln verwenden derzeit nicht-freie Funktionen (Google Bibliotheken). Diese sind in der F-Droid Version nicht funktionsfähig. Das schließt die Erkennung Ihrer gegenwärtigen körperlichen Aktivität ein.</string>
|
||||
<string name="displayNewsOnMainScreen">Nachrichten auf dem Hauptbildschirm anzeigen</string>
|
||||
<string name="displayNewsOnMainScreenDescription">Nachrichten ausschließlich über diese Anwendung, wir sprechen von 1-2 pro Jahr, nicht mehr.</string>
|
||||
<string name="newsOptIn">Möchten Sie wichtige Nachrichten über diese Anwendung auf dem Hauptbildschirm angezeigt bekommen? Diese werden von der Webseite des Entwicklers heruntergeladen. Es gibt keine aufdringliche Benachrichtigung, etc., lediglich eine stille Anzeige auf dem Hauptbildschirm.</string>
|
||||
<string name="locationDisabled">Ortung deaktiviert</string>
|
||||
<string name="notification">Benachrichtigung</string>
|
||||
<string name="title">Titel</string>
|
||||
<string name="text">Text</string>
|
||||
<string name="anyApp">Irgendeine Anwendung</string>
|
||||
<string name="postsNotification">%1$s zeigt eine Benachrichtung an</string>
|
||||
<string name="removedNotification">Benachrichtigung von %1$s wurde entfernt</string>
|
||||
<string name="notificationAppears">Benachrichtigung wird angezeigt</string>
|
||||
<string name="notificationDisappears">Benachrichtigung wird entfernt</string>
|
||||
<string name="direction">Richtung</string>
|
||||
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Systembenachrichtigungen lesen</string>
|
||||
<string name="playSound">Tondatei abspielen</string>
|
||||
<string name="alwaysPlay">immer abspielen</string>
|
||||
<string name="selectSoundFile">Tondatei auswählen</string>
|
||||
<string name="fileDoesNotExist">Datei existiert nicht.</string>
|
||||
<string name="noFileManageInstalled">Kein Dateimanager installiert.</string>
|
||||
<string name="alwaysPlayExplanation">Wenn diese Einstellung aktiv ist, wird der Ton immer abgespielt. Wenn die Einstellung inaktiv ist, wird der Ton nur dann abgespielt, wenn das Telefon weder auf stumm noch auf Vibration steht, d.h. Klingeltöne aktiv sind. Allerdings hat es keinen Einfluß auf die Medien-Lautstärke. D.h., wenn diese stumm ist, werden Sie so oder so nichts zu hören bekommen.</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Konfigurations- und Logdatei mit Entwickler teilen (via email).</string>
|
||||
<string name="shareConfigAndLogExplanation">Dies wird eine neue Email öffnen mit Konfigurations- und Logdateien als Zip-Anhang. Sie wird nicht automatisch versendet. D.h. Sie können so z.B. auch den Adressaten zu sich selbst ändern.</string>
|
||||
<string name="notificationTriggerExplanation">Dieser Auslöser reagiert auf Benachrichtigungen anderer Anwendung im Benachrichtigungsbereich von Android (oder wenn diese geschlossen werden). Sie können eine bestimmte Anwendung festlegen, von die Nachricht stammen muß. Wenn nicht, zählt jede Benachrichtigung. Sie können auch Zeichenketten für Titel oder Nachrichteninhalt festlegen, die enthalten sein müssen. Die Groß-/Kleinschreibung wird hierbei nicht berücksichtigt.</string>
|
||||
<string name="ruleActivationComplete">Regel \"%1$s\" wurde fertig ausgeführt.</string>
|
||||
</resources>
|
@ -98,7 +98,7 @@
|
||||
<string name="generalSettings">General settings</string>
|
||||
<string name="startAtSystemBoot">Start at system boot</string>
|
||||
<string name="onOff">On/Off</string>
|
||||
<string name="writeLogFileToSd">Write log file to SD card</string>
|
||||
<string name="writeLogFile">Write log file</string>
|
||||
<string name="useTextToSpeechOnNormalSummary">Use TextToSpeech on normal</string>
|
||||
<string name="useTextToSpeechOnVibrateSummary">Use TextToSpeech on vibrate</string>
|
||||
<string name="useTextToSpeechOnSilentSummary">Use TextToSpeech on silent</string>
|
||||
|
@ -562,7 +562,7 @@ Selezionare su “Continua” quando si è pronti a procedere.</string>
|
||||
<string name="wifiState">Stato Wifi</string>
|
||||
<string name="with">con</string>
|
||||
<string name="withLabel">con etichetta</string>
|
||||
<string name="writeLogFileToSd">Memorizza un file di log su SD card</string>
|
||||
<string name="writeLogFile">Memorizza un file di log</string>
|
||||
<string name="writingSettingsToPersistentMemory">Scrivo le impostazioni nella memoria di massa.</string>
|
||||
<string name="yes">Si</string>
|
||||
<string name="edit">Elaborare</string>
|
||||
|
@ -10,5 +10,9 @@
|
||||
<color name="teal_200">#008080</color>
|
||||
<color name="teal_700">#008080</color>
|
||||
<color name="black">#000000</color>
|
||||
<color name="brightScreenBackgroundColor">#F3F3F3</color>
|
||||
<color name="brightScreenTextColor">#FFFFFF</color>
|
||||
<color name="darkScreenBackgroundColor">#FFFFFF</color>
|
||||
<color name="darkScreenTextColor">#F3F3F3</color>
|
||||
|
||||
</resources>
|
||||
|
@ -91,14 +91,14 @@
|
||||
<string name="selectPoi">Select location</string>
|
||||
<string name="selectTypeOfAction">Select type of action</string>
|
||||
<string name="selectSoundProfile">Select sound profile</string>
|
||||
<string name="whatToDoWithTrigger">What to do with it trigger?</string>
|
||||
<string name="whatToDoWithAction">What to do with it action?</string>
|
||||
<string name="whatToDoWithTrigger">What to do with trigger?</string>
|
||||
<string name="whatToDoWithAction">What to do with action?</string>
|
||||
<string name="radiusHasToBePositive">Radius has to be a positive number.</string>
|
||||
<string name="poiStillReferenced">There are still rules that reference this location (%1$s). I can\'t delete it, yet.</string>
|
||||
<string name="generalSettings">General settings</string>
|
||||
<string name="startAtSystemBoot">Start at system boot</string>
|
||||
<string name="onOff">On/Off</string>
|
||||
<string name="writeLogFileToSd">Write log file to SD card</string>
|
||||
<string name="writeLogFile">Write log file</string>
|
||||
<string name="useTextToSpeechOnNormalSummary">Use TextToSpeech on normal</string>
|
||||
<string name="useTextToSpeechOnVibrateSummary">Use TextToSpeech on vibrate</string>
|
||||
<string name="useTextToSpeechOnSilentSummary">Use TextToSpeech on silent</string>
|
||||
@ -601,7 +601,7 @@
|
||||
<string name="manageLocations">Create or edit locations</string>
|
||||
<string name="error">Error</string>
|
||||
<string name="featureNotInFdroidVersion">This feature is based on non-free software. Therefore is is not available in the F-Droid version.</string>
|
||||
<string name="settingsReferringToRestrictedFeatures">Your settings and or rules are currently referencing non-free features that cannot be provided in the F-Droid version.</string>
|
||||
<string name="settingsReferringToRestrictedFeatures">Your settings and or rules are currently referencing non-free features that cannot be provided in the F-Droid version. That includes detecting your current physical activity.</string>
|
||||
<string name="publishedOn">published on</string>
|
||||
<string name="displayNewsOnMainScreen">Display application news on main screen</string>
|
||||
<string name="displayNewsOnMainScreenDescription">Announcements about this app only, we\'re probably talking about 1-2 per year, not more.</string>
|
||||
@ -609,6 +609,33 @@
|
||||
<string name="newsOptIn">Would you like to receive (only important) news about this app on the main screen? Those are downloaded from the developer\'s website. There will be no intrusive notification, just a text on the main screen when you open the app.</string>
|
||||
<string name="locationDisabled">Location disabled</string>
|
||||
<string name="locationEngineDisabledShort">Location cannot be determined anymore. Click here to find out why.</string>
|
||||
<string name="locationEngineDisabledLong">Unfortunately your location cannot be determined anymore. A debt of gratitude is owed to Google for its infinite wisdom and amiableness.\\n\\nLet me explain this further. Starting with Android 10 a new permission was introduced that is needed to determine your location in the background (which of course is required for an app like this). Whilst I consider that a good idea in general the chicanery it involves for developers are not.\\n\\nWhen developing an app you can try to qualify for this permission by abiding to a catalog of requirements. Unfortunately new versions of my app have been rejected over a period of three months. I fulfilled all these requirements, Google\'s shitty development support claimed I would not. After giving them proof that I did after all - I got a response like \"I cannot help you anymore\". Eventually I gave up. \\n\\nAs a consequence the Google Play version can NOT use your location as a trigger anymore. My only alternative option would have been to have this application removed from the store entirely.\\n\\nI\'m very sorry about that, but I\'ve tried my best arguing with a \"support\" that repeatedly failed to pass the Turing test.\\n\\nThe good news: You can still have it all!\\n\\nAutomation is now open source and can be found in F-Droid. That is an app store that really cares about your privacy - rather than just acting like that. Simply backup your config file, uninstall this app, install it again from F-Droid, restore your config file - done.\\n\\nClick here to find out more:</string>
|
||||
<string name="filesStoredAt">Config and log files are stored in folder %1$s</string>
|
||||
<string name="locationEngineDisabledLong">Unfortunately your location cannot be determined anymore. A debt of gratitude is owed to Google for its infinite wisdom and amiableness.\\n\\nLet me explain this further. Starting with Android 10 a new permission was introduced that is needed to determine your location in the background (which of course is required for an app like this). Whilst I consider that a good idea in general the chicanery it involves for developers is not.\\n\\nWhen developing an app you can try to qualify for this permission by abiding to a catalog of requirements. Unfortunately new versions of my app have been rejected over a period of three months. I fulfilled all those requirements, Google\'s shitty development support claimed I would not. After giving them proof that I did after all - I got a response like \"I cannot help you anymore\". Eventually I gave up. \\n\\nAs a consequence the Google Play version can NOT use your location as a trigger anymore. My only alternative option would have been to have this application removed from the store entirely.\\n\\nI\'m very sorry about that, but I\'ve tried my best arguing with a \"support\" that repeatedly failed to pass the Turing test.\\n\\nThe good news: You can still have it all!\\n\\nAutomation is now open source and can be found in F-Droid. That is an app store that really cares about your privacy - rather than just acting like that. Simply backup your config file, uninstall this app, install it again from F-Droid, restore your config file - done.\\n\\nClick here to find out more:</string>
|
||||
<string name="filesStoredAt">Config and log files are stored in folder %1$s. Click on this text to open a file explorer. Unfortunately this will only work with a rooted device or a debug version. If you want to send me or yourself the config- and logfiles you can use the below button.</string>
|
||||
<string name="notification">Notification</string>
|
||||
<string name="title">Title</string>
|
||||
<string name="text">Text</string>
|
||||
<string name="directionStringEquals">equals</string>
|
||||
<string name="directionStringContains">contains</string>
|
||||
<string name="directionStringStartsWith">starts with</string>
|
||||
<string name="directionStringEndsWith">ends with</string>
|
||||
<string name="directionStringNotEquals">not equals</string>
|
||||
<string name="anyApp">Any app</string>
|
||||
<string name="notificationTriggerExplanation">This trigger will respond to other applications opening notifications in the notification area (or such being closed). You can specify another application from which the notification has to come from. If you don\'t the notifications from any other application will count. You can also specify strings that must be or must not be in their title or notification body. The comparison is done case-INsensitive.</string>
|
||||
<string name="postsNotification">%1$s posts notification</string>
|
||||
<string name="removedNotification">notification from %1$s removed</string>
|
||||
<string name="notificationAppears">Notification appears</string>
|
||||
<string name="notificationDisappears">Notification disappears</string>
|
||||
<string name="direction">Direction</string>
|
||||
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Read system notifications</string>
|
||||
<string name="playSound">Play sound</string>
|
||||
<string name="alwaysPlay">always play</string>
|
||||
<string name="alwaysPlayExplanation">If this settings is active the sound will always be played. If it is deactivated it will only play if your phone is neither on mute nor vibrate. However if active it will not have an effect on the volume. So if your phone is on ring mode it will not increase the media volume for example. So if media volume is on mute you won\'t hear anything either.</string>
|
||||
<string name="selectSoundFile">Select sound file</string>
|
||||
<string name="fileDoesNotExist">File does not exist.</string>
|
||||
<string name="noFileManageInstalled">No file manager installed.</string>
|
||||
<string name="shareConfigAndLogFilesWithDev">Share config and log files with developer (via email).</string>
|
||||
<string name="shareConfigAndLogExplanation">This will start a new email with your config and log files attached as zip file. It will not be sent automatically, you still need to hit \"send\". You can also change the recipient to yourself for example.</string>
|
||||
<string name="startAppChoiceNote">You can enter an activity path manually, but it\'s recommended to use the \"Select\" button.\nIf you choose to enter something manually keep in mind no variables will be resolved. If you want to start the camera for example \"MediaStore.ACTION_IMAGE_CAPTURE\" will not work. You have to look at the Android documentation and use its value instead which would be \"android.media.action.IMAGE_CAPTURE\".</string>
|
||||
<string name="errorRunningRule">There was an error running a rule.</string>
|
||||
<string name="cantFindSoundFile">Cannot find sound file %1$s and therefore not play it.</string>
|
||||
</resources>
|
1
fastlane/metadata/android/de-DE/changelogs/101.txt
Normal file
1
fastlane/metadata/android/de-DE/changelogs/101.txt
Normal file
@ -0,0 +1 @@
|
||||
Fehler behoben, bei dem die App abgestürzt ist, wenn eine Regel gespeichert wurde während der Dienst lief.
|
3
fastlane/metadata/android/de-DE/changelogs/102.txt
Normal file
3
fastlane/metadata/android/de-DE/changelogs/102.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Neuer Auslöser: Benachrichtigungen anderer Anwendungen auswerten.
|
||||
Neue Aktion: Sounddatei abspielen.
|
||||
Die üblichen Aufräumarbeiten und Fehlerbehebungen.
|
1
fastlane/metadata/android/de-DE/changelogs/97.txt
Normal file
1
fastlane/metadata/android/de-DE/changelogs/97.txt
Normal file
@ -0,0 +1 @@
|
||||
Initiale F-Droid Version
|
2
fastlane/metadata/android/de-DE/changelogs/99.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/99.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ort verschoben, an dem die Konfigurationsdatei gespeichert wird (nun ein Programm-spezifisches Verzeichnis unterhalb von Android/data).
|
||||
Wenn Sie das Programm bisher schon verwendet haben, d.h. Ihre Dateien am alten Ort angelegt wurden, werden sie beim ersten Start verschoben. Wenn das erfolgreich war, ist die Berechtigung android.permission.WRITE_EXTERNAL_STORAGE nicht länger notwendig.
|
89
fastlane/metadata/android/de-DE/full_description.txt
Normal file
89
fastlane/metadata/android/de-DE/full_description.txt
Normal file
@ -0,0 +1,89 @@
|
||||
Erstellen Sie Regeln, die aus Auslösern und Aktionen bestehen. Ein typisches Beispiel wäre etwas wie "Telefon auf stumm stellen, wenn ich auf der Arbeit bin."
|
||||
|
||||
Hier ist eine Liste der möglichen Auslöser und Aktionen:
|
||||
|
||||
Mögliche Auslöser:
|
||||
* Ort
|
||||
* Tag/Uhrzeit
|
||||
* Ladezustand (lädt/lädt nicht)
|
||||
* Akkustand
|
||||
* USB Verbindung zu einem Computer besteht
|
||||
* Die gegenwärtige Geschwindigkeit (km/h)
|
||||
* Hintergrundlautstärke (nur bis Android 7)
|
||||
* WLAN Verbindung
|
||||
* Anwendere Anwendung wurde gestartet
|
||||
* Flugzeugmodus
|
||||
* Roaming aktiv oder nicht
|
||||
* NFC tags
|
||||
* Bluetooth Gerät verbunden
|
||||
* Headset verbunden
|
||||
* Telefongespräch im Gange
|
||||
* Benachrichtigungen anderer Anwendungen
|
||||
|
||||
Mögliche Aktionen:
|
||||
* WLAN ein-/ausschalten
|
||||
* Bluetooth ein-/ausschalten
|
||||
* USB Router ein-/ausschalten
|
||||
* WLAN Router ein-/ausschalten
|
||||
* Bildschirmdrehung ein-/ausschalten
|
||||
* HTTP Request im Hintergrund auslösen
|
||||
* Klingelton und Toneinstellungen ändern
|
||||
* Eine andere Anwendung starten
|
||||
* Warten (zwischen anderen Aktionen)
|
||||
* Den Bildschirm des Geräts einschalten
|
||||
* Flugzeugmodus ein-/ausschalten
|
||||
* Datenverbindung ein-/ausschalten
|
||||
* Text sprechen (TTS)
|
||||
* Musikplayer öffnen
|
||||
* Bildschirmhelligkeit ändern
|
||||
* SMS verschicken
|
||||
* Sounddatei abspielen.
|
||||
|
||||
Es ist ziemlich schwierig diese Anwendung über die vielen verschiedenen Geräte sowie die vielen Änderungen an Android Versionen am Funktionen zu halten. Ich kann vieles im Emulator testen, aber eben nicht alles.
|
||||
Wenn also eine bestimmte Funktion nicht so tut wie sie sollte - lassen Sie es mich wissen. Über die Jahre habe ich noch alle Fehler behoben, die mir gemeldet wurden. Aber dafür bin ich auf Ihre Mithilfe angewiesen.
|
||||
|
||||
Ein Wort zu den vielen Berechtigungen....
|
||||
|
||||
Es liegt in der Natur einer Anwendung wie dieser, daß sie ziemlich viele Berechtigungen benötigt. Allerdings sind praktisch alle davon optional, und werden nur angefragt, wenn Sie eine Regel erstellen, die das erfordert.
|
||||
|
||||
Gehen wir sie mal schnell durch:
|
||||
ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE: Dinge wie Flugmodus oder Roaming prüfen.
|
||||
|
||||
ACCESS_WIFI_STATE, CHANGE_WIFI_STATE: WLAN ein-/ausschalten
|
||||
|
||||
INTERNET
|
||||
Das wird aus drei Gründen benötigt:
|
||||
- Sie verwenden eine Ortungsmethode, die Mobilfunktürme verwenden (Standardeinstellung)
|
||||
- Sie verwenden URL aufrufen als Aktion
|
||||
- Sie aktivieren den Newsdownload in den Einstellungen
|
||||
|
||||
BLUETOOTH, BLUETOOTH_ADMIN: Bluetooth Verbindungen prüfen oder Bluetooth ein-/ausschalten
|
||||
|
||||
NFC: NFC Tags als Auslöser verwenden
|
||||
|
||||
Location (ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, ACCESS_BACKGROUND_LOCATION): Das sollte selbsterklärend sein - verwenden Sie Orte oder Geschwindigkeit als Auslöser?
|
||||
|
||||
PROCESS_OUTGOING_CALLS: Sie können ausgehende Anrufen als Auslöser verwenden. Z.B. "wenn die Frau anruft, dann..."
|
||||
|
||||
SEND_SMS: Sie können SMS verschicken lassen. Hier kann eine Zielnummer direkt eingegeben werden oder optional eine aus den Kontakten ausgewählt werden, was uns zu READ_CONTACTS bringt
|
||||
|
||||
READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE: Wenn Sie die Anwendung vor März 2021 installiert haben, war das nötig, um die Konfigurationsdatei zu speichern (unter sdcard). Seitdem ist sie nicht mehr notwendig. Die Berechtigung ist noch da, um bei Benutzern, die noch nicht geupdatet haben, ein Migrieren der Dateien zu ermöglichen. Weiterhin ist das Lesen jetzt notwendig, um eine Sounddatei abzuspielen.
|
||||
|
||||
GET_TASKS: Für den Auslöser, der prüft, ob eine andere Anwendung läuft.
|
||||
|
||||
BATTERY_STATS: Akkustand lesen.
|
||||
|
||||
MODIFY_AUDIO_SETTINGS, ACCESS_NOTIFICATION_POLICY:
|
||||
Für höhere Android Versionen ist das nötig, um Toneinstellungen wie Klingeltöne zu ändern.
|
||||
https://stackoverflow.com/questions/43123650/android-request-access-notification-policy-and-mute-phone/43127589#43127589
|
||||
ACCESS_NOTIFICATION_POLICY wird auch verwendet, um für den entsprechenden Auslöser Benachrichtigungen anderer Anwendungen lesen zu können.
|
||||
|
||||
RECORD_AUDIO: Für den Auslöser "Hintergrundlautstärke" notwendig. Nebenbei - meine persönliche Anwendung dafür ist: Mein Telefon stellt sich morgens auf laut. Während der Woche ist das recht fr<66>h. Was ist aber, wenn ich einen Tag frei habe? Hierzu wird als zusätzliche Bedingung die Hintergrundlautstärke ausgewertet, um festzustellen, ob ich wirklich schon wach bin. Leider hat Google diese Funktion mit Android 8 deaktiviert.
|
||||
|
||||
READ_PHONE_STATE: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
|
||||
RECEIVE_BOOT_COMPLETED, FOREGROUND_SERVICE, WAKE_LOCK: Den Dienst automatisch beim Systemstart starten.
|
||||
|
||||
WRITE_SETTINGS: Systemeinstellungen ändern.
|
||||
|
||||
ACCESS_SUPERUSER: root ist komplett optional. In der (weiter zurückliegenden) Vergangenheit war es möglich Dinge wie das Ein-/Ausschalten des USB Routers mit normalen Funktionen zu steuern. Leider ist das schon lange nur noch mit Root-Rechten möglich. D.h. root ist nur für wenige Funktionen notwendig.
|
BIN
fastlane/metadata/android/de-DE/images/icon.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 KiB |
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/3.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/4.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/phoneScreenshots/4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
@ -0,0 +1 @@
|
||||
Automatisieren Sie Dinge auf Ihrem Gerät, indem Sie Regeln anlegen.
|
1
fastlane/metadata/android/de-DE/title.txt
Normal file
1
fastlane/metadata/android/de-DE/title.txt
Normal file
@ -0,0 +1 @@
|
||||
Automation
|
3
fastlane/metadata/android/en-US/changelogs/102.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/102.txt
Normal file
@ -0,0 +1,3 @@
|
||||
New trigger: You can now use notifications of other apps.
|
||||
New action: Play a sound file.
|
||||
The usual cleanups and bugfixes.
|
@ -18,6 +18,7 @@ Supported triggers:
|
||||
* Bluetooth connection
|
||||
* Headset connected
|
||||
* Phone call running
|
||||
* Notifications of other apps
|
||||
|
||||
Supported actions:
|
||||
* Change wifi state
|
||||
@ -36,6 +37,7 @@ Supported actions:
|
||||
* Open music player
|
||||
* Change screen brightness
|
||||
* Send text message
|
||||
* Play sound file
|
||||
|
||||
It's quite hard to keep this app working across the many different hardwares as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs.
|
||||
So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reported to me. But for that I'm dependend on your input.
|
||||
@ -65,7 +67,7 @@ PROCESS_OUTGOING_CALLS: You can use current calls as trigger. E.g. if wife calls
|
||||
|
||||
SEND_SMS: You can have SMS sent as action. If you choose to do so you can enter the destination number manually or optionally pick one of your contacts which brings us to READ_CONTACTS
|
||||
|
||||
READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE: If you initially installed the app after March 2021 this is not required. In the past the app used to store its config file on the regular storage like "sdcard". The permission is still in there to ensure the app is also still working for legacy users. There the app will migrate the files to the new location.
|
||||
READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE: If you initially installed the app after March 2021 this is not required. In the past the app used to store its config file on the regular storage like "sdcard". The permission is still in there to ensure the app is also still working for legacy users. There the app will migrate the files to the new location. Reading is also required if you want to play sound files.
|
||||
|
||||
GET_TASKS: For trigger "check if another app is running"
|
||||
|
||||
@ -74,7 +76,7 @@ BATTERY_STATS: Check battery level as trigger
|
||||
MODIFY_AUDIO_SETTINGS, ACCESS_NOTIFICATION_POLICY:
|
||||
From higher versions on this is required to be able to change, e.g. the ringtone or generally the sound settings.
|
||||
https://stackoverflow.com/questions/43123650/android-request-access-notification-policy-and-mute-phone/43127589#43127589
|
||||
ACCESS_NOTIFICATION_POLICY is also included to prepare for a new trigger - to use notifications of other applications as trigger. But this feature has not been implemented, yet.
|
||||
ACCESS_NOTIFICATION_POLICY is also included for the trigger that reads other apps' notifications.
|
||||
|
||||
RECORD_AUDIO: For trigger "check background noise". Btw - my use case for this is: My phone will turn on sounds in the morning. During the week that is quite early. But what if I have a day off? Then it will monitor the background noise as an additional condition. If there's noise it's fairly certain I'm actually awake. Unfortunately Google deactivated this feature with Android 8.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user