diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java
index 56d64d918..d2f0fe4df 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java
@@ -56,7 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerActivity;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
@@ -498,7 +498,7 @@ public class SettingsActivity extends AbstractSettingsActivity {
}
});
- findPreference(TaskerConstants.TASKER).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ findPreference(TaskerConstants.ACTIVITY_TASKER).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent enableIntent = new Intent(SettingsActivity.this, TaskerActivity.class);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java
index 28763a18f..79edcf6c1 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchService.java
@@ -16,21 +16,10 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.devices.xwatch;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCharacteristic;
-
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.UUID;
-import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.AbstractTaskerSpec;
-import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerSpec;
-
public class XWatchService {
public static final UUID UUID_NOTIFY = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb");
public static final UUID UUID_SERVICE = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchTaskerSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchTaskerSpec.java
index d6acf2ede..2bdd696e1 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchTaskerSpec.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xwatch/XWatchTaskerSpec.java
@@ -7,7 +7,7 @@ import java.util.Arrays;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.AbstractTaskerSpec;
+import nodomain.freeyourgadget.gadgetbridge.tasker.spec.AbstractTaskerSpec;
public class XWatchTaskerSpec extends AbstractTaskerSpec {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java
index 5f289742f..5c48893e2 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xwatch/XWatchSupport.java
@@ -40,7 +40,6 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
-import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
@@ -60,12 +59,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSuppo
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.DeviceInfo;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerBleProfile;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
-import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerService;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerBleProfile;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerDevice;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class XWatchSupport extends AbstractBTLEDeviceSupport {
@@ -82,7 +78,7 @@ public class XWatchSupport extends AbstractBTLEDeviceSupport {
addSupportedService(XWatchService.UUID_SERVICE);
addSupportedService(XWatchService.UUID_WRITE);
addSupportedService(XWatchService.UUID_NOTIFY);
- addSupportedProfile(new TaskerBleProfile<>(this, TaskerConstants.TaskerDevice.XWATCH));
+ addSupportedProfile(new TaskerBleProfile<>(this, TaskerDevice.XWATCH));
}
public static byte[] crcChecksum(byte[] data) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEvent.java
index 7d180a5ee..66140911d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEvent.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEvent.java
@@ -1,5 +1,14 @@
package nodomain.freeyourgadget.gadgetbridge.tasker.event;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
+
+/**
+ * Tasker event that gets thrown if its corresponding {@link TaskerSettings#isEnabled()} is true.
+ *
+ * Provides {@link TaskerEventType} and a count.
+ *
+ * Count resets itself after {@link TaskerSettings#getThreshold()} is expired.
+ */
public class TaskerEvent {
private TaskerEventType type;
@@ -10,6 +19,11 @@ public class TaskerEvent {
this.count = count;
}
+ /**
+ * Tasker event type of this event.
+ *
+ * @return
+ */
public TaskerEventType getType() {
return type;
}
@@ -18,6 +32,11 @@ public class TaskerEvent {
this.type = type;
}
+ /**
+ * Count how often this event is thrown in the {@link TaskerSettings#getThreshold()}
+ *
+ * @return Fired times
+ */
public int getCount() {
return count;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEventType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEventType.java
index 6b9eb9e67..390699d6b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEventType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/TaskerEventType.java
@@ -7,6 +7,14 @@ import java.util.Objects;
import nodomain.freeyourgadget.gadgetbridge.R;
+/**
+ * Default set of tasker events.
+ *
+ * Extend here if you want to add more events. Use {@link TaskerEventType#create(String)}
+ * and configure {@link TaskerEventType#withLocalization(int)} for {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerEventsActivity}
+ *
+ * Don't forget to add the new event to {@link #getTypes()} method.
+ */
public class TaskerEventType implements Serializable {
public static TaskerEventType BUTTON = TaskerEventType.create("button").withLocalization(R.string.tasker_event_button);
@@ -63,12 +71,11 @@ public class TaskerEventType implements Serializable {
if (o == null || getClass() != o.getClass()) return false;
TaskerEventType that = (TaskerEventType) o;
return index == that.index &&
- type == that.type;
+ Objects.equals(type, that.type);
}
@Override
public int hashCode() {
-
return Objects.hash(type, index);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerActionCodes.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerActionCodes.java
similarity index 98%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerActionCodes.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerActionCodes.java
index d297442bb..157e83ca6 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerActionCodes.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerActionCodes.java
@@ -1,5 +1,10 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
+package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
+/**
+ * Tasker action codes.
+ *
+ * @see Tasker invoke tasks for more information.
+ */
public class TaskerActionCodes {
public static final int NONE = -1;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerBleProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerBleProfile.java
similarity index 79%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerBleProfile.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerBleProfile.java
index 815963a20..ed3968609 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerBleProfile.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerBleProfile.java
@@ -1,4 +1,4 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
+package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
@@ -6,7 +6,11 @@ import android.bluetooth.BluetoothGattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.service.NoTaskDefinedException;
+import nodomain.freeyourgadget.gadgetbridge.tasker.service.SpecTaskerService;
+import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerUtil;
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
+import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
/**
* Tasker plugin hook as BLE profile.
@@ -18,9 +22,9 @@ import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
public class TaskerBleProfile extends AbstractBleProfile {
private SpecTaskerService taskerService;
- private TaskerConstants.TaskerDevice taskerDevice;
+ private TaskerDevice taskerDevice;
- public TaskerBleProfile(T support, TaskerConstants.TaskerDevice taskerDevice) {
+ public TaskerBleProfile(T support, TaskerDevice taskerDevice) {
super(support);
this.taskerDevice = taskerDevice;
taskerService = new SpecTaskerService(taskerDevice.getSpec());
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerConstants.java
new file mode 100644
index 000000000..fd5c89b36
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerConstants.java
@@ -0,0 +1,84 @@
+package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
+
+/**
+ * Tasker constants.
+ */
+public class TaskerConstants {
+
+ /**
+ * Tasker intent's between {@link nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity}'s.
+ */
+ public static final String INTENT_DEVICE = "int_tasker_device";
+ public static final String INTENT_EVENT = "int_tasker_event";
+
+ /**
+ * Correspond to {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerActivity}
+ */
+ public static final String ACTIVITY_TASKER = "act_tasker";
+ public static final String ACTIVITY_TASKER_ENABLED = "act_tasker_enabled";
+ public static final String ACTIVITY_TASKER_GROUP = "act_tasker_group";
+ /**
+ * Correspond to {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerEventsActivity}
+ */
+ public static final String ACTIVITY_EVENT_GROUP = "act_event_group";
+
+ /**
+ * Correspond to {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerEventActivity}.
+ */
+ public static final String ACTIVITY_TASK_ADD = "act_tasker_task_add";
+ public static final ScopedString ACTIVITY_THRESHOLD = new ScopedString("act_tasker_threshold");
+ public static final ScopedString ACTIVITY_TASK = new ScopedString("act_tasker_task");
+ public static final ScopedString ACTIVITY_THRESHOLD_ENABLED = new ScopedString("act_tasker_threshold_enabled");
+ public static final ScopedString ACTIVITY_TASKS = new ScopedString("act_tasker_task_group");
+ public static final ScopedString ACTIVITY_EVENT_ENABLED = new ScopedString("act_tasker_event_enabled");
+
+ public static class ScopedString {
+
+ private String constant;
+ private List scopes;
+
+ private ScopedString(String constant) {
+ this.constant = constant;
+ }
+
+ public ScopedString withScope(String scope) {
+ ScopedString scoped = new ScopedString(constant);
+ List addScope;
+ if (scopes == null) {
+ addScope = new ArrayList<>();
+ } else {
+ addScope = new ArrayList<>(scopes);
+ }
+ addScope.add(scope);
+ scoped.scopes = addScope;
+ return scoped;
+ }
+
+ public String getConstant() {
+ return constant;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(constant);
+ if (scopes != null && !scopes.isEmpty()) {
+ for (String scope : scopes) {
+ if (!StringUtils.isEmpty(scope)) {
+ continue;
+ }
+ if (scopes.indexOf(scope) < scope.length() - 1) {
+ builder.append("_");
+ }
+ builder.append(scopes);
+ }
+ }
+ return builder.toString();
+ }
+ }
+
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerDevice.java
new file mode 100644
index 000000000..ce9efd5ee
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerDevice.java
@@ -0,0 +1,33 @@
+package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
+
+import java.io.Serializable;
+
+import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchTaskerSpec;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
+
+/**
+ * Tasker devices with corresponding {@link nodomain.freeyourgadget.gadgetbridge.impl.GBDevice}.
+ *
+ * Add new devices here! Provide a {@link TaskerSpec} and your ready to go.
+ */
+public enum TaskerDevice implements Serializable {
+
+ XWATCH(DeviceType.XWATCH, new XWatchTaskerSpec());
+
+ private DeviceType type;
+ private TaskerSpec spec;
+
+ TaskerDevice(DeviceType type, TaskerSpec spec) {
+ this.type = type;
+ this.spec = spec;
+ }
+
+ public DeviceType getType() {
+ return type;
+ }
+
+ public TaskerSpec getSpec() {
+ return spec;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerIntent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerIntent.java
new file mode 100644
index 000000000..5c677d14e
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/plugin/TaskerIntent.java
@@ -0,0 +1,452 @@
+// Version 1.3.3
+
+// Changelog
+
+// Version 1.3.3
+// - increased MAX_NO_ARGS to 10
+
+// Version 1.3.2
+// - bug setting app arg
+// - pulled provider column names out of function
+
+// For usage examples see http://tasker.dinglisch.net/invoketasks.html
+
+package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.PatternMatcher;
+import android.os.Process;
+import android.util.Log;
+
+/**
+ * Tasker {@link Intent}'s.
+ *
+ * @see Tasker invoke tasks for more information.
+ */
+public class TaskerIntent extends Intent {
+
+ // 3 Tasker versions
+ public final static String TASKER_PACKAGE = "net.dinglisch.android.tasker";
+ public final static String TASKER_PACKAGE_MARKET = TASKER_PACKAGE + "m";
+ public final static String TASKER_PACKAGE_CUPCAKE = TASKER_PACKAGE + "cupcake";
+
+ // Play Store download URLs
+ public final static String MARKET_DOWNLOAD_URL_PREFIX = "market://details?id=";
+ private final static String TASKER_MARKET_URL = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_MARKET;
+ private final static String TASKER_MARKET_URL_CUPCAKE = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_CUPCAKE;
+
+ // Direct-purchase version
+ private final static String TASKER_DOWNLOAD_URL = "http://tasker.dinglisch.net/download.html";
+
+ // Intent actions
+ public final static String ACTION_TASK = TASKER_PACKAGE + ".ACTION_TASK";
+ public final static String ACTION_TASK_COMPLETE = TASKER_PACKAGE + ".ACTION_TASK_COMPLETE";
+ public final static String ACTION_TASK_SELECT = TASKER_PACKAGE + ".ACTION_TASK_SELECT";
+
+ // Intent parameters
+ public final static String EXTRA_ACTION_INDEX_PREFIX = "action";
+ public final static String TASK_NAME_DATA_SCHEME = "task";
+ public final static String EXTRA_TASK_NAME = "task_name";
+ public final static String EXTRA_TASK_PRIORITY = "task_priority";
+ public final static String EXTRA_SUCCESS_FLAG = "success";
+ public final static String EXTRA_VAR_NAMES_LIST = "varNames";
+ public final static String EXTRA_VAR_VALUES_LIST = "varValues";
+ public final static String EXTRA_TASK_OUTPUT = "output";
+
+ // Content provider columns
+ public static final String PROVIDER_COL_NAME_EXTERNAL_ACCESS = "ext_access";
+ public static final String PROVIDER_COL_NAME_ENABLED = "enabled";
+
+ // DEPRECATED, use EXTRA_VAR_NAMES_LIST, EXTRA_VAR_VALUES_LIST
+ public final static String EXTRA_PARAM_LIST = "params";
+
+ // Intent data
+
+ public final static String TASK_ID_SCHEME = "id";
+
+ // For particular actions
+
+ public final static String DEFAULT_ENCRYPTION_KEY = "default";
+ public final static String ENCRYPTED_AFFIX = "tec";
+ public final static int MAX_NO_ARGS = 10;
+
+ // Bundle keys
+ // Only useful for Tasker
+ public final static String ACTION_CODE = "action";
+ public final static String APP_ARG_PREFIX = "app:";
+ public final static String ICON_ARG_PREFIX = "icn:";
+ public final static String ARG_INDEX_PREFIX = "arg:";
+ public static final String PARAM_VAR_NAME_PREFIX = "par";
+
+ // Misc
+ private final static String PERMISSION_RUN_TASKS = TASKER_PACKAGE + ".PERMISSION_RUN_TASKS";
+
+ public final static String ACTION_OPEN_PREFS = TASKER_PACKAGE + ".ACTION_OPEN_PREFS";
+ public final static String EXTRA_OPEN_PREFS_TAB_NO = "tno";
+ private final static int MISC_PREFS_TAB_NO = 3; // 0 based
+
+ // To query whether Tasker is enabled and external access is enabled
+ private final static String TASKER_PREFS_URI = "content://" + TASKER_PACKAGE + "/prefs";
+
+ private final static int CUPCAKE_SDK_VERSION = 3;
+
+ // result values for TestSend
+
+ // NotInstalled: Tasker package not found on device
+ // NoPermission: calling app does not have permission PERMISSION_RUN_TASKS
+ // NotEnabled: Tasker is not enabled
+ // AccessBlocked: user prefs disallow external access
+ // NoReceiver: Tasker has not created a listener for external access (probably a Tasker bug)
+ // OK: you should be able to send a task to run. Still need to listen for result
+ // for e.g. task not found
+
+ public static enum Status {NotInstalled, NoPermission, NotEnabled, AccessBlocked, NoReceiver, OK}
+
+ ;
+
+ // -------------------------- PRIVATE VARS ---------------------------- //
+
+ private final static String TAG = "TaskerIntent";
+
+ private final static String EXTRA_INTENT_VERSION_NUMBER = "version_number";
+ private final static String INTENT_VERSION_NUMBER = "1.1";
+
+ // Inclusive values
+ private final static int MIN_PRIORITY = 0;
+ private final static int MAX_PRIORITY = 10;
+
+ // For generating random names
+ private static Random rand = new Random();
+
+ // Tracking state
+ private int actionCount = 0;
+ private int argCount;
+
+ // -------------------------- PUBLIC METHODS ---------------------------- //
+
+ public static int getMaxPriority() {
+ return MAX_PRIORITY;
+ }
+
+ public static boolean validatePriority(int pri) {
+ return (
+ (pri >= MIN_PRIORITY) ||
+ (pri <= MAX_PRIORITY)
+ );
+ }
+
+ // Tasker has different package names for Play Store and non- versions
+ // for historical reasons
+
+ public static String getInstalledTaskerPackage(Context context) {
+
+ String foundPackage = null;
+
+ try {
+ context.getPackageManager().getPackageInfo(TASKER_PACKAGE, 0);
+ foundPackage = TASKER_PACKAGE;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+
+ try {
+ context.getPackageManager().getPackageInfo(TASKER_PACKAGE_MARKET, 0);
+ foundPackage = TASKER_PACKAGE_MARKET;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+
+ return foundPackage;
+ }
+
+ // test we can send a TaskerIntent to Tasker
+ // use *before* sending an intent
+ // still need to test the *result after* sending intent
+
+ public static Status testStatus(Context c) {
+
+ Status result;
+
+ if (!taskerInstalled(c))
+ result = Status.NotInstalled;
+ else if (!havePermission(c))
+ result = Status.NoPermission;
+ else if (!TaskerIntent.prefSet(c, PROVIDER_COL_NAME_ENABLED))
+ result = Status.NotEnabled;
+ else if (!TaskerIntent.prefSet(c, PROVIDER_COL_NAME_EXTERNAL_ACCESS))
+ result = Status.AccessBlocked;
+ else if (!new TaskerIntent("").receiverExists(c))
+ result = Status.NoReceiver;
+ else
+ result = Status.OK;
+
+ return result;
+ }
+
+ // Check if Tasker installed
+
+ public static boolean taskerInstalled(Context context) {
+ return (getInstalledTaskerPackage(context) != null);
+ }
+
+ // Use with startActivity to retrieve Tasker from Android market
+ public static Intent getTaskerInstallIntent(boolean marketFlag) {
+
+ return new Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse(
+ marketFlag ?
+ ((SDKVersion() == CUPCAKE_SDK_VERSION) ? TASKER_MARKET_URL_CUPCAKE : TASKER_MARKET_URL) :
+ TASKER_DOWNLOAD_URL
+ )
+ );
+ }
+
+ public static int SDKVersion() {
+ try {
+ Field f = android.os.Build.VERSION.class.getField("SDK_INT");
+ return f.getInt(null);
+ } catch (Exception e) {
+ return CUPCAKE_SDK_VERSION;
+ }
+ }
+
+ public static IntentFilter getCompletionFilter(String taskName) {
+
+ IntentFilter filter = new IntentFilter(TaskerIntent.ACTION_TASK_COMPLETE);
+
+ filter.addDataScheme(TASK_NAME_DATA_SCHEME);
+ filter.addDataPath(taskName, PatternMatcher.PATTERN_LITERAL);
+
+ return filter;
+ }
+
+ public static Intent getTaskSelectIntent() {
+ return new Intent(ACTION_TASK_SELECT).
+ setFlags(
+ Intent.FLAG_ACTIVITY_NO_USER_ACTION |
+ Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+ Intent.FLAG_ACTIVITY_NO_HISTORY
+ );
+ }
+
+ // public access deprecated, use TaskerIntent.testSend() instead
+
+ public static boolean havePermission(Context c) {
+ return c.checkPermission(PERMISSION_RUN_TASKS, Process.myPid(), Process.myUid()) ==
+ PackageManager.PERMISSION_GRANTED;
+ }
+
+ // Get an intent that will bring up the Tasker prefs screen with the External Access control(s)
+ // Probably you want to use startActivity or startActivityForResult with it
+
+ public static Intent getExternalAccessPrefsIntent() {
+ return new Intent(ACTION_OPEN_PREFS).putExtra(EXTRA_OPEN_PREFS_TAB_NO, MISC_PREFS_TAB_NO);
+ }
+
+ // ------------------------------------- INSTANCE METHODS ----------------------------- //
+
+ public TaskerIntent() {
+ super(ACTION_TASK);
+ setRandomData();
+ putMetaExtras(getRandomString());
+ }
+
+ public TaskerIntent(String taskName) {
+ super(ACTION_TASK);
+ setRandomData();
+ putMetaExtras(taskName);
+ }
+
+ public TaskerIntent setTaskPriority(int priority) {
+
+ if (validatePriority(priority))
+ putExtra(EXTRA_TASK_PRIORITY, priority);
+ else
+ Log.e(TAG, "priority out of range: " + MIN_PRIORITY + ":" + MAX_PRIORITY);
+
+ return this;
+ }
+
+ // Sets subsequently %par1, %par2 etc
+ public TaskerIntent addParameter(String value) {
+
+ int index = 1;
+
+ if (getExtras().containsKey(EXTRA_VAR_NAMES_LIST))
+ index = getExtras().getStringArrayList(EXTRA_VAR_NAMES_LIST).size() + 1;
+
+ Log.d(TAG, "index: " + index);
+
+ addLocalVariable("%" + PARAM_VAR_NAME_PREFIX + index, value);
+
+ return this;
+ }
+
+ // Arbitrary specification of (local) variable names and values
+ public TaskerIntent addLocalVariable(String name, String value) {
+
+ ArrayList names, values;
+
+ if (hasExtra(EXTRA_VAR_NAMES_LIST)) {
+ names = getStringArrayListExtra(EXTRA_VAR_NAMES_LIST);
+ values = getStringArrayListExtra(EXTRA_VAR_VALUES_LIST);
+ } else {
+ names = new ArrayList();
+ values = new ArrayList();
+
+ putStringArrayListExtra(EXTRA_VAR_NAMES_LIST, names);
+ putStringArrayListExtra(EXTRA_VAR_VALUES_LIST, values);
+ }
+
+ names.add(name);
+ values.add(value);
+
+ return this;
+ }
+
+ public TaskerIntent addAction(int code) {
+
+ actionCount++;
+ argCount = 1;
+
+ Bundle actionBundle = new Bundle();
+
+ actionBundle.putInt(ACTION_CODE, code);
+
+ // Add action bundle to intent
+ putExtra(EXTRA_ACTION_INDEX_PREFIX + Integer.toString(actionCount), actionBundle);
+
+ return this;
+ }
+
+ // string arg
+ public TaskerIntent addArg(String arg) {
+
+ Bundle b = getActionBundle();
+
+ if (b != null)
+ b.putString(ARG_INDEX_PREFIX + Integer.toString(argCount++), arg);
+
+ return this;
+ }
+
+ // int arg
+ public TaskerIntent addArg(int arg) {
+ Bundle b = getActionBundle();
+
+ if (b != null)
+ b.putInt(ARG_INDEX_PREFIX + Integer.toString(argCount++), arg);
+
+ return this;
+ }
+
+ // boolean arg
+ public TaskerIntent addArg(boolean arg) {
+ Bundle b = getActionBundle();
+
+ if (b != null)
+ b.putBoolean(ARG_INDEX_PREFIX + Integer.toString(argCount++), arg);
+
+ return this;
+ }
+
+ // Application arg
+ public TaskerIntent addArg(String pkg, String cls) {
+ Bundle b = getActionBundle();
+
+ if (b != null) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(APP_ARG_PREFIX).
+ append(pkg).append(",").append(cls);
+ b.putString(ARG_INDEX_PREFIX + Integer.toString(argCount++), builder.toString());
+ }
+
+ return this;
+ }
+
+ public IntentFilter getCompletionFilter() {
+ return getCompletionFilter(getTaskName());
+ }
+
+ public String getTaskName() {
+ return getStringExtra(EXTRA_TASK_NAME);
+ }
+
+ public boolean receiverExists(Context context) {
+ List recs = context.getPackageManager().queryBroadcastReceivers(this, 0);
+ return (
+ (recs != null) &&
+ (recs.size() > 0)
+ );
+ }
+
+ // -------------------- PRIVATE METHODS -------------------- //
+
+ private String getRandomString() {
+ return Long.toString(rand.nextLong());
+ }
+
+ // so that if multiple TaskerIntents are used in PendingIntents there's virtually no
+ // clash chance
+ private void setRandomData() {
+ setData(Uri.parse(TASK_ID_SCHEME + ":" + getRandomString()));
+ }
+
+ private Bundle getActionBundle() {
+
+ Bundle toReturn = null;
+
+ if (argCount > MAX_NO_ARGS)
+ Log.e(TAG, "maximum number of arguments exceeded (" + MAX_NO_ARGS + ")");
+ else {
+ String key = EXTRA_ACTION_INDEX_PREFIX + Integer.toString(actionCount);
+
+ if (this.hasExtra(key))
+ toReturn = getBundleExtra(key);
+ else
+ Log.e(TAG, "no actions added yet");
+ }
+
+ return toReturn;
+ }
+
+ private void putMetaExtras(String taskName) {
+ putExtra(EXTRA_INTENT_VERSION_NUMBER, INTENT_VERSION_NUMBER);
+ putExtra(EXTRA_TASK_NAME, taskName);
+ }
+
+ // for testing that Tasker is enabled and external access is allowed
+
+ private static boolean prefSet(Context context, String col) {
+
+ String[] proj = new String[]{col};
+
+ Cursor c = context.getContentResolver().query(Uri.parse(TASKER_PREFS_URI), proj, null, null, null);
+
+ boolean acceptingFlag = false;
+
+ if (c == null)
+ Log.w(TAG, "no cursor for " + TASKER_PREFS_URI);
+ else {
+ c.moveToFirst();
+
+ if (Boolean.TRUE.toString().equals(c.getString(0)))
+ acceptingFlag = true;
+
+ c.close();
+ }
+
+ return acceptingFlag;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerService.java
index 6e4c620cb..7dc2d967f 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerService.java
@@ -6,8 +6,10 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerIntent;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplier;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplierImpl;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTask;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
@@ -28,17 +30,28 @@ public abstract class AbstractTaskerService {
this.enabled = new SettingSupplierImpl() {
@Override
public Boolean get() {
- return GBApplication.getPrefs().getBoolean(TaskerConstants.TASKER_ENABLED, false);
+ return GBApplication.getPrefs().getBoolean(TaskerConstants.ACTIVITY_TASKER_ENABLED, false);
}
};
}
- public boolean isActive() {
+ public boolean isEnabled() {
return enabled.get();
}
+ /**
+ * Schedules tasker task for {@link TaskerEventType} if
+ * {@link #isEnabled()},
+ * {@link #isReady()} and
+ * event type is not {@link TaskerEventType#NO_OP}.
+ *
+ * Uses {@link #DEFAULT_THRESHOLD} of '50' milliseconds if threshold is not set.
+ *
+ * @param type
+ * @return
+ */
public boolean runForType(TaskerEventType type) {
- if (type != null && !TaskerEventType.NO_OP.equals(type) && isActive() && ready()) {
+ if (type != null && !TaskerEventType.NO_OP.equals(type) && isEnabled() && isReady()) {
if (!tasks.containsKey(type)) {
SettingSupplier taskProvider = taskProvider(type);
if (taskProvider.isPresent()) {
@@ -56,7 +69,12 @@ public abstract class AbstractTaskerService {
protected abstract SettingSupplier taskProvider(TaskerEventType type);
- public static boolean ready() {
+ /**
+ * Determines of tasker is installed and ready.
+ *
+ * @return True if installed and ready
+ */
+ public static boolean isReady() {
return TaskerIntent.testStatus(GBApplication.getContext()).equals(TaskerIntent.Status.OK);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/NoTaskDefinedException.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/NoTaskDefinedException.java
index d354aecb4..f9f8b7815 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/NoTaskDefinedException.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/NoTaskDefinedException.java
@@ -1,5 +1,8 @@
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
+/**
+ * Gets thrown if tasker is enabled but no task name is defined. Triggers {@link TaskerUtil#noTaskDefinedInformation()}.
+ */
public class NoTaskDefinedException extends RuntimeException {
public NoTaskDefinedException() {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/SpecTaskerService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/SpecTaskerService.java
index fe3c7a554..88ecaf98e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/SpecTaskerService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/SpecTaskerService.java
@@ -1,11 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplier;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
/**
- * {@link TaskerSpec} impl for {@link AbstractTaskerService}.
+ * {@link TaskerSpec} implementation for {@link TaskerService}.
*/
public class SpecTaskerService extends AbstractTaskerService {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerAbstractSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerAbstractSpec.java
deleted file mode 100644
index 40b92f342..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerAbstractSpec.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
-import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
-
-public abstract class TaskerAbstractSpec implements TaskerSpec {
-
- @Override
- public TaskerSettings getSettings(TaskerEventType eventType) {
- return null;
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerConstants.java
deleted file mode 100644
index afd8af24f..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerConstants.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-
-import java.io.Serializable;
-
-import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchConstants;
-import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
-import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchTaskerSpec;
-import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
-
-public class TaskerConstants {
-
-
- private static final String tasker = "tasker";
- public static final String TASKER = "pref_key_tasker";
- public static final String TASKER_SETTINGS = "pref_key_tasker_settings";
- public static final String TASKER_ENABLED = "tasker_enabled";
- public static final String TASKER_PREFERENCES = "tasker_preferences";
- public static final String TASKER_PREF_GROUP = "pref_key_tasker_group";
- public static final String DEVICE_INTENT = "intent_tasker_device";
- public static final String EVENT_INTENT = "intent_tasker_event";
- public static final String TASKER_TASK = "tasker-task";
- public static final String TASKER_PREFERENCE = "tasker_list";
- public static final String PREF_EVENT_GROUP = "pref_key_tasker_event_group";
-
- public static final String ACTIVITY_THRESHOLD = "act_tasker_threshold";
- public static final String ACTIVITY_TASK_ADD = "act_tasker_task_add";
- public static final String ACTIVITY_TASK = "act_tasker_task";
- public static final String ACTIVITY_THESHOLD_ENABELD = "act_tasker_threshold_enabled";
- public static final String ACTIVITY_TASKS = "act_tasker_task_group";
-
-
- public enum TaskerDevice implements Serializable {
-
- XWATCH(DeviceType.XWATCH, new XWatchTaskerSpec());
-
- private DeviceType type;
- private TaskerSpec spec;
-
- TaskerDevice(DeviceType type, TaskerSpec spec) {
- this.type = type;
- this.spec = spec;
- }
-
- public DeviceType getType() {
- return type;
- }
-
- public TaskerSpec getSpec() {
- return spec;
- }
- }
-
-// public static class Settings {
-//
-// private static final String setting = "setting";
-// public static final String ENABLED = concate(tasker, setting, "enabled");
-// public static final String ENABLED = "tasker_enabled";
-//
-// }
-//
-// public static class Preferences {
-// private static final String prefKey = "pref_key";
-// public static final String TASKER = concate(prefKey, "tasker");
-// public static final String TASKER_SETTINGS = concate(prefKey, "tasker", "settings");
-// }
-
- private static String concate(String... parts) {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < parts.length; i++) {
- builder.append(parts[i]);
- if (i < parts.length - 1) {
- builder.append("_");
- }
- }
- return builder.toString();
- }
-
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerIntent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerIntent.java
deleted file mode 100644
index 412d11a97..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerIntent.java
+++ /dev/null
@@ -1,449 +0,0 @@
-// Version 1.3.3
-
-// Changelog
-
-// Version 1.3.3
-// - increased MAX_NO_ARGS to 10
-
-// Version 1.3.2
-// - bug setting app arg
-// - pulled provider column names out of function
-
-// For usage examples see http://tasker.dinglisch.net/invoketasks.html
-
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.PatternMatcher;
-import android.os.Process;
-import android.util.Log;
-
-public class TaskerIntent extends Intent {
-
- // 3 Tasker versions
- public final static String TASKER_PACKAGE = "net.dinglisch.android.tasker";
- public final static String TASKER_PACKAGE_MARKET = TASKER_PACKAGE + "m";
- public final static String TASKER_PACKAGE_CUPCAKE = TASKER_PACKAGE + "cupcake";
-
- // Play Store download URLs
- public final static String MARKET_DOWNLOAD_URL_PREFIX = "market://details?id=";
- private final static String TASKER_MARKET_URL = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_MARKET;
- private final static String TASKER_MARKET_URL_CUPCAKE = MARKET_DOWNLOAD_URL_PREFIX + TASKER_PACKAGE_CUPCAKE;
-
- // Direct-purchase version
- private final static String TASKER_DOWNLOAD_URL = "http://tasker.dinglisch.net/download.html";
-
- // Intent actions
- public final static String ACTION_TASK = TASKER_PACKAGE + ".ACTION_TASK";
- public final static String ACTION_TASK_COMPLETE = TASKER_PACKAGE + ".ACTION_TASK_COMPLETE";
- public final static String ACTION_TASK_SELECT = TASKER_PACKAGE + ".ACTION_TASK_SELECT";
-
- // Intent parameters
- public final static String EXTRA_ACTION_INDEX_PREFIX = "action";
- public final static String TASK_NAME_DATA_SCHEME = "task";
- public final static String EXTRA_TASK_NAME = "task_name";
- public final static String EXTRA_TASK_PRIORITY = "task_priority";
- public final static String EXTRA_SUCCESS_FLAG = "success";
- public final static String EXTRA_VAR_NAMES_LIST = "varNames";
- public final static String EXTRA_VAR_VALUES_LIST = "varValues";
- public final static String EXTRA_TASK_OUTPUT = "output";
-
- // Content provider columns
- public static final String PROVIDER_COL_NAME_EXTERNAL_ACCESS = "ext_access";
- public static final String PROVIDER_COL_NAME_ENABLED = "enabled";
-
- // DEPRECATED, use EXTRA_VAR_NAMES_LIST, EXTRA_VAR_VALUES_LIST
- public final static String EXTRA_PARAM_LIST = "params";
-
- // Intent data
-
- public final static String TASK_ID_SCHEME = "id";
-
- // For particular actions
-
- public final static String DEFAULT_ENCRYPTION_KEY= "default";
- public final static String ENCRYPTED_AFFIX = "tec";
- public final static int MAX_NO_ARGS = 10;
-
- // Bundle keys
- // Only useful for Tasker
- public final static String ACTION_CODE = "action";
- public final static String APP_ARG_PREFIX = "app:";
- public final static String ICON_ARG_PREFIX = "icn:";
- public final static String ARG_INDEX_PREFIX = "arg:";
- public static final String PARAM_VAR_NAME_PREFIX = "par";
-
- // Misc
- private final static String PERMISSION_RUN_TASKS = TASKER_PACKAGE + ".PERMISSION_RUN_TASKS";
-
- public final static String ACTION_OPEN_PREFS = TASKER_PACKAGE + ".ACTION_OPEN_PREFS";
- public final static String EXTRA_OPEN_PREFS_TAB_NO = "tno";
- private final static int MISC_PREFS_TAB_NO = 3; // 0 based
-
- // To query whether Tasker is enabled and external access is enabled
- private final static String TASKER_PREFS_URI = "content://" + TASKER_PACKAGE + "/prefs";
-
- private final static int CUPCAKE_SDK_VERSION = 3;
-
- // result values for TestSend
-
- // NotInstalled: Tasker package not found on device
- // NoPermission: calling app does not have permission PERMISSION_RUN_TASKS
- // NotEnabled: Tasker is not enabled
- // AccessBlocked: user prefs disallow external access
- // NoReceiver: Tasker has not created a listener for external access (probably a Tasker bug)
- // OK: you should be able to send a task to run. Still need to listen for result
- // for e.g. task not found
-
- public static enum Status { NotInstalled, NoPermission, NotEnabled, AccessBlocked, NoReceiver, OK };
-
- // -------------------------- PRIVATE VARS ---------------------------- //
-
- private final static String TAG = "TaskerIntent";
-
- private final static String EXTRA_INTENT_VERSION_NUMBER = "version_number";
- private final static String INTENT_VERSION_NUMBER = "1.1";
-
- // Inclusive values
- private final static int MIN_PRIORITY = 0;
- private final static int MAX_PRIORITY = 10;
-
- // For generating random names
- private static Random rand = new Random();
-
- // Tracking state
- private int actionCount = 0;
- private int argCount;
-
- // -------------------------- PUBLIC METHODS ---------------------------- //
-
- public static int getMaxPriority() {
- return MAX_PRIORITY;
- }
-
- public static boolean validatePriority( int pri ) {
- return (
- ( pri >= MIN_PRIORITY ) ||
- ( pri <= MAX_PRIORITY )
- );
- }
-
- // Tasker has different package names for Play Store and non- versions
- // for historical reasons
-
- public static String getInstalledTaskerPackage( Context context ) {
-
- String foundPackage = null;
-
- try {
- context.getPackageManager().getPackageInfo( TASKER_PACKAGE, 0 );
- foundPackage = TASKER_PACKAGE;
- }
- catch ( PackageManager.NameNotFoundException e ) {
- }
-
- try {
- context.getPackageManager().getPackageInfo( TASKER_PACKAGE_MARKET, 0 );
- foundPackage = TASKER_PACKAGE_MARKET;
- }
- catch ( PackageManager.NameNotFoundException e ) {
- }
-
- return foundPackage;
- }
-
- // test we can send a TaskerIntent to Tasker
- // use *before* sending an intent
- // still need to test the *result after* sending intent
-
- public static Status testStatus( Context c ) {
-
- Status result;
-
- if ( ! taskerInstalled( c ) )
- result = Status.NotInstalled;
- else if ( ! havePermission( c ) )
- result = Status.NoPermission;
- else if ( ! TaskerIntent.prefSet( c, PROVIDER_COL_NAME_ENABLED ) )
- result = Status.NotEnabled;
- else if ( ! TaskerIntent.prefSet( c, PROVIDER_COL_NAME_EXTERNAL_ACCESS ) )
- result = Status.AccessBlocked;
- else if ( ! new TaskerIntent( "" ).receiverExists( c ) )
- result = Status.NoReceiver;
- else
- result = Status.OK;
-
- return result;
- }
-
- // Check if Tasker installed
-
- public static boolean taskerInstalled( Context context ) {
- return ( getInstalledTaskerPackage( context ) != null );
- }
-
- // Use with startActivity to retrieve Tasker from Android market
- public static Intent getTaskerInstallIntent( boolean marketFlag ) {
-
- return new Intent(
- Intent.ACTION_VIEW,
- Uri.parse(
- marketFlag ?
- ( ( SDKVersion() == CUPCAKE_SDK_VERSION ) ? TASKER_MARKET_URL_CUPCAKE : TASKER_MARKET_URL ) :
- TASKER_DOWNLOAD_URL
- )
- );
- }
-
- public static int SDKVersion() {
- try {
- Field f = android.os.Build.VERSION.class.getField( "SDK_INT" );
- return f.getInt( null );
- }
- catch ( Exception e ) {
- return CUPCAKE_SDK_VERSION;
- }
- }
-
- public static IntentFilter getCompletionFilter( String taskName ) {
-
- IntentFilter filter = new IntentFilter( TaskerIntent.ACTION_TASK_COMPLETE );
-
- filter.addDataScheme( TASK_NAME_DATA_SCHEME );
- filter.addDataPath( taskName, PatternMatcher.PATTERN_LITERAL );
-
- return filter;
- }
-
- public static Intent getTaskSelectIntent() {
- return new Intent( ACTION_TASK_SELECT ).
- setFlags(
- Intent.FLAG_ACTIVITY_NO_USER_ACTION |
- Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
- Intent.FLAG_ACTIVITY_NO_HISTORY
- );
- }
-
- // public access deprecated, use TaskerIntent.testSend() instead
-
- public static boolean havePermission( Context c ) {
- return c.checkPermission( PERMISSION_RUN_TASKS, Process.myPid(), Process.myUid() ) ==
- PackageManager.PERMISSION_GRANTED;
- }
-
- // Get an intent that will bring up the Tasker prefs screen with the External Access control(s)
- // Probably you want to use startActivity or startActivityForResult with it
-
- public static Intent getExternalAccessPrefsIntent() {
- return new Intent( ACTION_OPEN_PREFS ).putExtra( EXTRA_OPEN_PREFS_TAB_NO, MISC_PREFS_TAB_NO );
- }
-
- // ------------------------------------- INSTANCE METHODS ----------------------------- //
-
- public TaskerIntent() {
- super( ACTION_TASK );
- setRandomData();
- putMetaExtras( getRandomString() );
- }
-
- public TaskerIntent( String taskName ) {
- super( ACTION_TASK );
- setRandomData();
- putMetaExtras( taskName );
- }
-
- public TaskerIntent setTaskPriority( int priority ) {
-
- if ( validatePriority( priority ) )
- putExtra( EXTRA_TASK_PRIORITY, priority );
- else
- Log.e( TAG, "priority out of range: " + MIN_PRIORITY + ":" + MAX_PRIORITY );
-
- return this;
- }
-
- // Sets subsequently %par1, %par2 etc
- public TaskerIntent addParameter( String value ) {
-
- int index = 1;
-
- if ( getExtras().containsKey( EXTRA_VAR_NAMES_LIST ) )
- index = getExtras().getStringArrayList( EXTRA_VAR_NAMES_LIST ).size() + 1;
-
- Log.d(TAG, "index: " + index );
-
- addLocalVariable( "%" + PARAM_VAR_NAME_PREFIX + index, value );
-
- return this;
- }
-
- // Arbitrary specification of (local) variable names and values
- public TaskerIntent addLocalVariable( String name, String value ) {
-
- ArrayList names, values;
-
- if ( hasExtra( EXTRA_VAR_NAMES_LIST ) ) {
- names = getStringArrayListExtra( EXTRA_VAR_NAMES_LIST );
- values = getStringArrayListExtra( EXTRA_VAR_VALUES_LIST );
- }
- else {
- names = new ArrayList();
- values = new ArrayList();
-
- putStringArrayListExtra( EXTRA_VAR_NAMES_LIST, names );
- putStringArrayListExtra( EXTRA_VAR_VALUES_LIST, values );
- }
-
- names.add( name );
- values.add( value );
-
- return this;
- }
-
- public TaskerIntent addAction( int code ) {
-
- actionCount++;
- argCount = 1;
-
- Bundle actionBundle = new Bundle();
-
- actionBundle.putInt( ACTION_CODE, code );
-
- // Add action bundle to intent
- putExtra( EXTRA_ACTION_INDEX_PREFIX + Integer.toString( actionCount ), actionBundle );
-
- return this;
- }
-
- // string arg
- public TaskerIntent addArg( String arg ) {
-
- Bundle b = getActionBundle();
-
- if ( b != null )
- b.putString( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
-
- return this;
- }
-
- // int arg
- public TaskerIntent addArg( int arg ) {
- Bundle b = getActionBundle();
-
- if ( b != null )
- b.putInt( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
-
- return this;
- }
-
- // boolean arg
- public TaskerIntent addArg( boolean arg ) {
- Bundle b = getActionBundle();
-
- if ( b != null )
- b.putBoolean( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), arg );
-
- return this;
- }
-
- // Application arg
- public TaskerIntent addArg( String pkg, String cls ) {
- Bundle b = getActionBundle();
-
- if ( b != null ) {
- StringBuilder builder = new StringBuilder();
- builder.append( APP_ARG_PREFIX ).
- append( pkg ). append( "," ). append( cls );
- b.putString( ARG_INDEX_PREFIX + Integer.toString( argCount++ ), builder.toString() );
- }
-
- return this;
- }
-
- public IntentFilter getCompletionFilter() {
- return getCompletionFilter( getTaskName() );
- }
-
- public String getTaskName() {
- return getStringExtra( EXTRA_TASK_NAME );
- }
-
- public boolean receiverExists( Context context ) {
- List recs = context.getPackageManager().queryBroadcastReceivers( this, 0 );
- return (
- ( recs != null ) &&
- ( recs.size() > 0 )
- );
- }
-
- // -------------------- PRIVATE METHODS -------------------- //
-
- private String getRandomString() {
- return Long.toString( rand.nextLong() );
- }
-
- // so that if multiple TaskerIntents are used in PendingIntents there's virtually no
- // clash chance
- private void setRandomData() {
- setData( Uri.parse( TASK_ID_SCHEME + ":" + getRandomString() ) );
- }
-
- private Bundle getActionBundle() {
-
- Bundle toReturn = null;
-
- if ( argCount > MAX_NO_ARGS )
- Log.e( TAG, "maximum number of arguments exceeded (" + MAX_NO_ARGS + ")" );
- else {
- String key = EXTRA_ACTION_INDEX_PREFIX + Integer.toString( actionCount );
-
- if ( this.hasExtra( key ) )
- toReturn = getBundleExtra( key );
- else
- Log.e( TAG, "no actions added yet" );
- }
-
- return toReturn;
- }
-
- private void putMetaExtras( String taskName ) {
- putExtra( EXTRA_INTENT_VERSION_NUMBER, INTENT_VERSION_NUMBER );
- putExtra( EXTRA_TASK_NAME, taskName );
- }
-
- // for testing that Tasker is enabled and external access is allowed
-
- private static boolean prefSet( Context context, String col ) {
-
- String [] proj = new String [] { col };
-
- Cursor c = context.getContentResolver().query( Uri.parse( TASKER_PREFS_URI ), proj, null, null, null );
-
- boolean acceptingFlag = false;
-
- if ( c == null )
- Log.w( TAG, "no cursor for " + TASKER_PREFS_URI );
- else {
- c.moveToFirst();
-
- if ( Boolean.TRUE.toString().equals( c.getString( 0 ) ) )
- acceptingFlag = true;
-
- c.close();
- }
-
- return acceptingFlag;
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerService.java
index 1bd85dedc..0a80441b4 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerService.java
@@ -1,25 +1,18 @@
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-import android.widget.Toast;
-
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.function.Supplier;
-import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplier;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplierImpl;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
-import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTask;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
/**
- * Default impl for {@link AbstractTaskerService}.
+ * Default implementation for {@link AbstractTaskerService}.
*
- * One instance per thread/device! The service is not threadsafe.
+ * Preferred to use with java based configuration.
*/
public class TaskerService extends AbstractTaskerService {
@@ -30,11 +23,25 @@ public class TaskerService extends AbstractTaskerService {
this.enabled = new SettingSupplierImpl<>(enabled);
}
+ /**
+ * Set threshold between task calls for {@link TaskerEventType}.
+ *
+ * @param type Event
+ * @param threshold Threshold in milliseconds
+ * @return Itself
+ */
public TaskerService withThreshold(TaskerEventType type, long threshold) {
this.threshold.put(type, new SettingSupplierImpl<>(threshold));
return this;
}
+ /**
+ * Sets single task name for {@link TaskerEventType}.
+ *
+ * @param type Event
+ * @param task Single task name
+ * @return Itself
+ */
public TaskerService withTask(TaskerEventType type, final String task) {
typeProvider.put(type, new SettingSupplierImpl(new TaskerTaskProvider() {
@Override
@@ -45,13 +52,18 @@ public class TaskerService extends AbstractTaskerService {
return this;
}
+ /**
+ * Sets {@link TaskerTaskProvider} for {@link TaskerEventType}.
+ *
+ * @param type Event
+ * @param provider Task name provider
+ * @return Itself
+ */
public TaskerService withProvider(TaskerEventType type, TaskerTaskProvider provider) {
typeProvider.put(type, new SettingSupplierImpl<>(provider));
return this;
}
- // Private
-
protected SettingSupplier threshold(TaskerEventType type) {
return threshold.get(type);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerUtil.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerUtil.java
index d724536d6..f95f902ec 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerUtil.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerUtil.java
@@ -4,6 +4,7 @@ import android.widget.Toast;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerIntent;
/**
* Tasker convenience methods for direct access to tasker without {@link TaskerService}.
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplier.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplier.java
similarity index 54%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplier.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplier.java
index 8df8ff2a4..c3c1b4b95 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplier.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplier.java
@@ -1,7 +1,7 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.event;
+package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
/**
- * Simple supplier.
+ * Simple setting supplier. Can listen to changes throw {@link SettingListener}.
*
* @param Setting
*/
@@ -15,6 +15,11 @@ public interface SettingSupplier {
SettingSupplier onChanged(SettingListener onChanged);
+ /**
+ * Listen to changes in {@link SettingSupplier}.
+ *
+ * @param
+ */
interface SettingListener {
void changed(T object);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplierImpl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplierImpl.java
similarity index 74%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplierImpl.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplierImpl.java
index 1045cad69..d05b607c8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/event/SettingSupplierImpl.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/SettingSupplierImpl.java
@@ -1,5 +1,10 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.event;
+package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
+/**
+ * Default implementation for {@link SettingSupplier}.
+ *
+ * @param
+ */
public class SettingSupplierImpl implements SettingSupplier {
private T object;
@@ -20,7 +25,9 @@ public class SettingSupplierImpl implements SettingSupplier {
@Override
public void set(T object) {
this.object = object;
- onChanged.changed(object);
+ if (onChanged != null) {
+ onChanged.changed(object);
+ }
}
@Override
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/TaskerSettings.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/TaskerSettings.java
index 085c38be2..0eb16cf1f 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/TaskerSettings.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/TaskerSettings.java
@@ -1,16 +1,45 @@
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
+import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
+/**
+ * Tasker settings. There is one setting per {@link nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType}.
+ * This is usually wrapped in {@link TaskerSpec}
+ * and used by {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerEventActivity} to let the user customize the settings.
+ * {@link nodomain.freeyourgadget.gadgetbridge.tasker.service.SpecTaskerService} is the out of the box implementation that uses this settings to call tasker.
+ *
+ * Extend here for more settings.
+ */
public interface TaskerSettings {
+ /**
+ * Consumes events or just listens to them.
+ *
+ * @return True if consumes events.
+ */
SettingSupplier isConsumingEvents();
+ /**
+ * Enables the settings.
+ *
+ * @return True if settings are enabled.
+ */
SettingSupplier isEnabled();
+ /**
+ * Threshold for tasker calls. Determines the delay between {@link nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent}'s
+ * and is therefore the main attribute to determine which tasker task is called.
+ *
+ * @return Threshold in milliseconds
+ */
SettingSupplier getThreshold();
+ /**
+ * {@link TaskerTaskProvider} determines the task names for {@link nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent}.
+ *
+ * @return Task provider
+ */
SettingSupplier getTaskProvider();
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/ButtonPreference.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/ButtonPreference.java
index 4b383a36a..8784185a3 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/ButtonPreference.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/ButtonPreference.java
@@ -8,6 +8,11 @@ import android.widget.Button;
import nodomain.freeyourgadget.gadgetbridge.R;
+/**
+ * Simple {@link EditTextPreference} with an button.
+ *
+ * Exposes only {@link Button#setOnClickListener(View.OnClickListener)} and {@link Button#setText(int)}
+ */
public class ButtonPreference extends EditTextPreference {
private View.OnClickListener onClickListener;
@@ -15,6 +20,7 @@ public class ButtonPreference extends EditTextPreference {
public ButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ setWidgetLayoutResource(R.layout.button_preference_layout);
}
public ButtonPreference(Context context, AttributeSet attrs) {
@@ -35,10 +41,20 @@ public class ButtonPreference extends EditTextPreference {
}
}
+ /**
+ * Sets an {@link View.OnClickListener} to the button.
+ *
+ * @param clickListener
+ */
public void setOnClickListener(View.OnClickListener clickListener) {
this.onClickListener = clickListener;
}
+ /**
+ * Set button text with resource id.
+ *
+ * @param resourceId {@link R.string}
+ */
public void setButtonText(int resourceId) {
if (button != null) {
button.setText(resourceId);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerActivity.java
index 8cc5dac3b..e13d970e0 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerActivity.java
@@ -7,16 +7,22 @@ import android.preference.PreferenceCategory;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerDevice;
+/**
+ * Tasker main {@link AbstractSettingsActivity} builds an supported list of {@link TaskerConstants.TaskerDevice}.
+ *
+ * If you extend {@link TaskerSettings} this is the point to implement the new features for user configuration.
+ */
public class TaskerEventActivity extends AbstractSettingsActivity {
- private TaskerConstants.TaskerDevice device;
+ private TaskerDevice device;
private TaskerEventType eventType;
private Prefs prefs = GBApplication.getPrefs();
-
- public TaskerEventActivity() {
- }
+ private List taskPreferences = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -34,16 +46,31 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- device = (TaskerConstants.TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.DEVICE_INTENT);
+ device = (TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.INTENT_DEVICE);
+ eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.INTENT_EVENT);
final TaskerSettings settings = device.getSpec().getSettings(eventType);
- eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.EVENT_INTENT);
- final PreferenceScreen tasks = (PreferenceScreen) findPreference(TaskerConstants.ACTIVITY_TASKS);
+ SwitchPreference enabled = (SwitchPreference) findPreference(scoped(TaskerConstants.ACTIVITY_EVENT_ENABLED));
+ settings.isEnabled().set(prefs.getBoolean(scoped(TaskerConstants.ACTIVITY_EVENT_ENABLED), false));
+ enabled.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ settings.isEnabled().set((Boolean) newValue);
+ return true;
+ }
+ });
+ eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.INTENT_EVENT);
+ final PreferenceScreen tasks = (PreferenceScreen) findPreference(scoped(TaskerConstants.ACTIVITY_TASKS));
initThreshold(settings, tasks);
initTasks(settings, tasks);
}
+ private String scoped(TaskerConstants.ScopedString scopedString) {
+ return scopedString.withScope(device.name()).withScope(eventType.getType()).toString();
+ }
+
private void initThreshold(final TaskerSettings settings, final PreferenceScreen tasks) {
- EditTextPreference threshold = (EditTextPreference) findPreference(TaskerConstants.ACTIVITY_THRESHOLD);
+ final EditTextPreference threshold = (EditTextPreference) findPreference(scoped(TaskerConstants.ACTIVITY_THRESHOLD));
+ setThresholdIfDefined(settings);
threshold.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -51,28 +78,43 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
return true;
}
});
- final Preference thresholdEnabled = findPreference(TaskerConstants.ACTIVITY_THESHOLD_ENABELD);
+ final Preference thresholdEnabled = findPreference(scoped(TaskerConstants.ACTIVITY_THRESHOLD_ENABLED));
+ if (prefs.getBoolean(scoped(TaskerConstants.ACTIVITY_THRESHOLD_ENABLED), false)) {
+ settings.getThreshold().set(null);
+ }
thresholdEnabled.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.equals(Boolean.FALSE)) {
- for (int i = 2; i < tasks.getPreferenceCount(); i++) {
- tasks.removePreference(tasks.getPreference(tasks.getPreferenceCount()));
+ for (EditTextPreference taskPreference : taskPreferences) {
+ if (!taskPreference.getKey().equals(scoped(TaskerConstants.ACTIVITY_TASK))) {
+ tasks.removePreference(taskPreference);
+ }
}
+ settings.getThreshold().set(null);
+ return true;
}
- settings.getThreshold().set(null);
+ setThresholdIfDefined(settings);
return true;
}
});
}
+ private void setThresholdIfDefined(TaskerSettings settings) {
+ long thresholdValue = prefs.getLong(scoped(TaskerConstants.ACTIVITY_THRESHOLD), 0L);
+ if (thresholdValue != 0L) {
+ settings.getThreshold().set(prefs.getLong(scoped(TaskerConstants.ACTIVITY_THRESHOLD), 50L));
+ }
+ }
+
private void initTasks(final TaskerSettings settings, final PreferenceScreen tasks) {
ButtonPreference addTaskButton = (ButtonPreference) findPreference(TaskerConstants.ACTIVITY_TASK_ADD);
- final EditTextPreference taskNamePreference = (EditTextPreference) findPreference(TaskerConstants.ACTIVITY_TASK);
+ final EditTextPreference taskNamePreference = (EditTextPreference) findPreference(scoped(TaskerConstants.ACTIVITY_TASK));
+ taskPreferences.add(taskNamePreference);
addTaskButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (prefs.getBoolean(TaskerConstants.ACTIVITY_THESHOLD_ENABELD, false)) {
+ if (prefs.getBoolean(scoped(TaskerConstants.ACTIVITY_THRESHOLD_ENABLED), false)) {
tasks.addPreference(task(tasks, taskNamePreference));
}
}
@@ -80,10 +122,12 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
TaskerTaskProvider taskerTaskProvider = new TaskerTaskProvider() {
@Override
public String getTask(TaskerEvent event) {
- for (int i = 1; i < tasks.getPreferenceCount(); i++) {
- if (event.getCount() == i - 1) {
- return ((EditTextPreference) tasks.getPreference(i)).getText();
+ if (event.getCount() < taskPreferences.size()) {
+ String text = taskPreferences.get(event.getCount()).getText();
+ if (StringUtils.isEmpty(text)) {
+ throw new NoTaskDefinedException();
}
+ return text;
}
return null;
}
@@ -94,17 +138,18 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
private Preference task(final PreferenceScreen tasks, Preference build) {
final ButtonPreference task = new ButtonPreference(this);
- task.setKey(TaskerConstants.ACTIVITY_TASK + "_" + tasks.getPreferenceCount());
+ task.setKey(scoped(TaskerConstants.ACTIVITY_TASK) + "_" + tasks.getPreferenceCount());
task.setTitle(build.getTitle());
task.setSummary(build.getSummary());
task.setButtonText(R.string.tasker_remove);
- task.setWidgetLayoutResource(R.layout.tasker_add_button);
+ task.setWidgetLayoutResource(R.layout.button_preference_layout);
task.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tasks.removePreference(task);
}
});
+ taskPreferences.add(task);
return task;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerEventsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerEventsActivity.java
index 704dda355..302b1f908 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerEventsActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/settings/activities/TaskerEventsActivity.java
@@ -8,11 +8,17 @@ import android.preference.PreferenceCategory;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerDevice;
+/**
+ * Tasker events {@link AbstractSettingsActivity}. Lists supported {@link TaskerEventType}'s for the specific {@link TaskerDevice}
+ *
+ * Forwards to {@link TaskerEventActivity}.
+ */
public class TaskerEventsActivity extends AbstractSettingsActivity {
- private TaskerConstants.TaskerDevice device;
+ private TaskerDevice device;
public TaskerEventsActivity() {
}
@@ -21,8 +27,8 @@ public class TaskerEventsActivity extends AbstractSettingsActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.tasker_events_preferences);
- device = (TaskerConstants.TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.DEVICE_INTENT);
- PreferenceCategory category = (PreferenceCategory) findPreference(TaskerConstants.PREF_EVENT_GROUP);
+ device = (TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.INTENT_DEVICE);
+ PreferenceCategory category = (PreferenceCategory) findPreference(TaskerConstants.ACTIVITY_EVENT_GROUP);
for (final TaskerEventType eventType : device.getSpec().getSupportedTypes()) {
Preference preference = new Preference(this);
preference.setTitle(eventType.getLocalization());
@@ -30,8 +36,8 @@ public class TaskerEventsActivity extends AbstractSettingsActivity {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(TaskerEventsActivity.this, TaskerEventActivity.class);
- intent.putExtra(TaskerConstants.EVENT_INTENT, eventType);
- intent.putExtra(TaskerConstants.DEVICE_INTENT, device);
+ intent.putExtra(TaskerConstants.INTENT_EVENT, eventType);
+ intent.putExtra(TaskerConstants.INTENT_DEVICE, device);
startActivity(intent);
return true;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/AbstractTaskerSpec.java
similarity index 81%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerSpec.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/AbstractTaskerSpec.java
index bdc7c1239..e7adf16a9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/AbstractTaskerSpec.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/AbstractTaskerSpec.java
@@ -1,18 +1,21 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
+package nodomain.freeyourgadget.gadgetbridge.tasker.spec;
import java.util.HashMap;
import java.util.Map;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
-import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplier;
+import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplierImpl;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
+/**
+ * Abstract implementation that supplies a {@link TaskerSettings} object to gather user configuration
+ * via {@link nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerEventsActivity}.
+ *
+ * Its recommended to use this implementation so you don't have to take care of user configurations yourself.
+ * Always provides a non null {@link TaskerSettings} object regardless of the {@link TaskerEventType}.
+ */
public abstract class AbstractTaskerSpec implements TaskerSpec {
private Map settings = new HashMap<>();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/TaskerSpec.java
similarity index 60%
rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerSpec.java
rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/TaskerSpec.java
index eee05c2da..f1c540a5d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/service/TaskerSpec.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/spec/TaskerSpec.java
@@ -1,4 +1,4 @@
-package nodomain.freeyourgadget.gadgetbridge.tasker.service;
+package nodomain.freeyourgadget.gadgetbridge.tasker.spec;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
@@ -6,8 +6,14 @@ import android.bluetooth.BluetoothGattCharacteristic;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
+/**
+ * Tasker specification for a {@link TaskerConstants.TaskerDevice}.
+ *
+ * First and only thing to do if you want to support more {@link nodomain.freeyourgadget.gadgetbridge.impl.GBDevice}.
+ */
public interface TaskerSpec {
TaskerEventType getEventType(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTask.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTask.java
index d1eb8bdbf..fe9da7921 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTask.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTask.java
@@ -2,14 +2,22 @@ package nodomain.freeyourgadget.gadgetbridge.tasker.task;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerIntent;
+import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerIntent;
+import nodomain.freeyourgadget.gadgetbridge.tasker.service.NoTaskDefinedException;
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerService;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
+import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerUtil;
+/**
+ * Tasker task used by {@link TaskerService} to run a scheduled asynchronous task.
+ *
+ * Uses {@link ScheduledExecutorService} with {@link Future} for scheduling.
+ */
public class TaskerTask implements Runnable {
private Future task;
@@ -39,10 +47,14 @@ public class TaskerTask implements Runnable {
@Override
public void run() {
- if (TaskerService.ready()) {
- if (task != null) {
- GBApplication.getContext().sendBroadcast(new TaskerIntent(provider.getTask(new TaskerEvent(type, count))));
+ try {
+ if (TaskerService.isReady()) {
+ if (task != null) {
+ GBApplication.getContext().sendBroadcast(new TaskerIntent(provider.getTask(new TaskerEvent(type, count))));
+ }
}
+ } catch (NoTaskDefinedException e) {
+ TaskerUtil.noTaskDefinedInformation();
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTaskProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTaskProvider.java
index 66afa128e..525fb0b33 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTaskProvider.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/tasker/task/TaskerTaskProvider.java
@@ -2,8 +2,17 @@ package nodomain.freeyourgadget.gadgetbridge.tasker.task;
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
+/**
+ * Tasker task provider provides task names {@link TaskerEvent} based.
+ */
public interface TaskerTaskProvider {
+ /**
+ * Task name for specific {@link TaskerEvent}
+ *
+ * @param event
+ * @return Task name
+ */
String getTask(TaskerEvent event);
}
diff --git a/app/src/main/res/layout/tasker_add_button.xml b/app/src/main/res/layout/button_preference_layout.xml
similarity index 100%
rename from app/src/main/res/layout/tasker_add_button.xml
rename to app/src/main/res/layout/button_preference_layout.xml
diff --git a/app/src/main/res/layout/tasker_remove_button.xml b/app/src/main/res/layout/tasker_remove_button.xml
deleted file mode 100644
index 2d5e79188..000000000
--- a/app/src/main/res/layout/tasker_remove_button.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 1a00dc6ae..a1ac049b2 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -625,14 +625,26 @@
Sprach- und Gebietseinstellungen
-
Tasker
- Aktiv
- Aktiviert Tasker aber deaktiviert die Steuerung der Medien
- Task für einzelnes drücken
- Task für doppeltes drücken
- Task für dreifaches drücken
+ Aktiviert
+ Aktiviert die Tasker-Unterstützung
+ Hinzufügen
+ Entfernen
+ Ereignisse
+ Knopfdruck-Ereignis
+ Verbindungs-Ereignis
+ Daten-Ereignis
+ Ereignistyp aktiviert
+ Schwellenwert aktiviert
+ Aktiviert eine Verzögerung zwischen den Aufgaben
+ Schwellenwert in Millisekunden
+ Verzögerung zwischen den Aufrufen der Aufgaben. Z.B. für Schwellenwert 1000: Doppelter Knopfdruck innerhalb einer Sekunde ruft die Aufgabe an zweiter Stelle auf.
+ Aufgabe
+ Fügt eine Weitere Schwellwert-Aufgahinzube
+ Aufgabenname
+ Tasker ist eine Applikation für Android die Aufgaben (Ein Set von Aktionen)
+ anhand eines Kontexts (Applikation, Zeit, Datum, Ort, Ereignis, Geste) über benutzerdefinierte
+ Profile oder klickbare oder zeitgesteuerte Widgets ausfürt.
+ Tasker ist aktiviert aber es wurde keine Aufgabe angegeben! Bitte gehen sie in die Tasker Einstellungen und definieren sie Aufgaben.
-
- XWatch Einstellungen
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6aa624374..cd7ddbd78 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -677,9 +677,11 @@
Enables Tasker supportAddRemove
+ EventsButton EventsConnection EventsData Events
+ Enable event typeEnable thresholdEnables delay between taskThreshold in milliseconds
@@ -691,7 +693,4 @@
(application, time, date, location, event, gesture) in user-defined profiles or in clickable or timer home screen widgets.
No task defined! Please define a task in settings.
-
- XWatch settings
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 080d5929d..8ae010ead 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -746,7 +746,7 @@
diff --git a/app/src/main/res/xml/tasker_event_preferences.xml b/app/src/main/res/xml/tasker_event_preferences.xml
index 03290a80b..3b573a1b1 100644
--- a/app/src/main/res/xml/tasker_event_preferences.xml
+++ b/app/src/main/res/xml/tasker_event_preferences.xml
@@ -1,26 +1,21 @@
-
-
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/xml/tasker_events_preferences.xml b/app/src/main/res/xml/tasker_events_preferences.xml
index c84939d22..e87f236ea 100644
--- a/app/src/main/res/xml/tasker_events_preferences.xml
+++ b/app/src/main/res/xml/tasker_events_preferences.xml
@@ -1,5 +1,6 @@
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/tasker_preferences.xml b/app/src/main/res/xml/tasker_preferences.xml
index 2c7f6b87e..971d4ca25 100644
--- a/app/src/main/res/xml/tasker_preferences.xml
+++ b/app/src/main/res/xml/tasker_preferences.xml
@@ -1,13 +1,13 @@
-
+