mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-02-10 15:57:00 +01:00
Finished activities. Fixed some bugs. Added scopes for preferences. Sill need to implement dynamic event activity.
This commit is contained in:
parent
c6b20ea534
commit
85c3d40f52
@ -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);
|
||||
|
@ -16,21 +16,10 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
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");
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* Provides {@link TaskerEventType} and a count.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
|
@ -7,6 +7,14 @@ import java.util.Objects;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
|
||||
/**
|
||||
* Default set of tasker events.
|
||||
* <p>
|
||||
* 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}
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
||||
package nodomain.freeyourgadget.gadgetbridge.tasker.plugin;
|
||||
|
||||
/**
|
||||
* Tasker action codes.
|
||||
*
|
||||
* @see <a herf="https://tasker.joaoapps.com/invoketasks.html">Tasker invoke tasks</a> for more information.
|
||||
*/
|
||||
public class TaskerActionCodes {
|
||||
|
||||
public static final int NONE = -1;
|
@ -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<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
|
||||
|
||||
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());
|
@ -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<String> scopes;
|
||||
|
||||
private ScopedString(String constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public ScopedString withScope(String scope) {
|
||||
ScopedString scoped = new ScopedString(constant);
|
||||
List<String> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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}.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -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 <a herf="https://tasker.joaoapps.com/invoketasks.html">Tasker invoke tasks</a> 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<String> names, values;
|
||||
|
||||
if (hasExtra(EXTRA_VAR_NAMES_LIST)) {
|
||||
names = getStringArrayListExtra(EXTRA_VAR_NAMES_LIST);
|
||||
values = getStringArrayListExtra(EXTRA_VAR_VALUES_LIST);
|
||||
} else {
|
||||
names = new ArrayList<String>();
|
||||
values = new ArrayList<String>();
|
||||
|
||||
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<ResolveInfo> 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;
|
||||
}
|
||||
}
|
@ -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<Boolean>() {
|
||||
@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}.
|
||||
* <p>
|
||||
* 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<TaskerTaskProvider> taskProvider = taskProvider(type);
|
||||
if (taskProvider.isPresent()) {
|
||||
@ -56,7 +69,12 @@ public abstract class AbstractTaskerService {
|
||||
|
||||
protected abstract SettingSupplier<TaskerTaskProvider> 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);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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<String> names, values;
|
||||
|
||||
if ( hasExtra( EXTRA_VAR_NAMES_LIST ) ) {
|
||||
names = getStringArrayListExtra( EXTRA_VAR_NAMES_LIST );
|
||||
values = getStringArrayListExtra( EXTRA_VAR_VALUES_LIST );
|
||||
}
|
||||
else {
|
||||
names = new ArrayList<String>();
|
||||
values = new ArrayList<String>();
|
||||
|
||||
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<ResolveInfo> 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;
|
||||
}
|
||||
}
|
@ -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}.
|
||||
* <p>
|
||||
* 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<TaskerTaskProvider>(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<Long> threshold(TaskerEventType type) {
|
||||
return threshold.get(type);
|
||||
}
|
||||
|
@ -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}.
|
||||
|
@ -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 <T> Setting
|
||||
*/
|
||||
@ -15,6 +15,11 @@ public interface SettingSupplier<T> {
|
||||
|
||||
SettingSupplier<T> onChanged(SettingListener<T> onChanged);
|
||||
|
||||
/**
|
||||
* Listen to changes in {@link SettingSupplier}.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
interface SettingListener<T> {
|
||||
void changed(T object);
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.tasker.event;
|
||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link SettingSupplier}.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class SettingSupplierImpl<T> implements SettingSupplier<T> {
|
||||
|
||||
private T object;
|
||||
@ -20,7 +25,9 @@ public class SettingSupplierImpl<T> implements SettingSupplier<T> {
|
||||
@Override
|
||||
public void set(T object) {
|
||||
this.object = object;
|
||||
onChanged.changed(object);
|
||||
if (onChanged != null) {
|
||||
onChanged.changed(object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
@ -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.
|
||||
* <p>
|
||||
* Extend here for more settings.
|
||||
*/
|
||||
public interface TaskerSettings {
|
||||
|
||||
/**
|
||||
* Consumes events or just listens to them.
|
||||
*
|
||||
* @return True if consumes events.
|
||||
*/
|
||||
SettingSupplier<Boolean> isConsumingEvents();
|
||||
|
||||
/**
|
||||
* Enables the settings.
|
||||
*
|
||||
* @return True if settings are enabled.
|
||||
*/
|
||||
SettingSupplier<Boolean> 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<Long> getThreshold();
|
||||
|
||||
/**
|
||||
* {@link TaskerTaskProvider} determines the task names for {@link nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent}.
|
||||
*
|
||||
* @return Task provider
|
||||
*/
|
||||
SettingSupplier<TaskerTaskProvider> getTaskProvider();
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,11 @@ import android.widget.Button;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
|
||||
/**
|
||||
* Simple {@link EditTextPreference} with an button.
|
||||
* <p>
|
||||
* 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);
|
||||
|
@ -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}.
|
||||
* <p>
|
||||
* Forwards to {@link TaskerEventsActivity}.
|
||||
*/
|
||||
public class TaskerActivity extends AbstractSettingsActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.tasker_preferences);
|
||||
final PreferenceCategory group = (PreferenceCategory) findPreference(TaskerConstants.TASKER_PREF_GROUP);
|
||||
for (TaskerConstants.TaskerDevice device : TaskerConstants.TaskerDevice.values()) {
|
||||
final PreferenceCategory group = (PreferenceCategory) findPreference(TaskerConstants.ACTIVITY_TASKER_GROUP);
|
||||
for (TaskerDevice device : TaskerDevice.values()) {
|
||||
group.addPreference(preference(device));
|
||||
}
|
||||
}
|
||||
@ -26,14 +32,14 @@ public class TaskerActivity extends AbstractSettingsActivity {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
private Preference preference(final TaskerConstants.TaskerDevice device) {
|
||||
private Preference preference(final TaskerDevice device) {
|
||||
Preference devicePreference = new Preference(this);
|
||||
devicePreference.setTitle(device.getType().getName());
|
||||
devicePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
Intent intent = new Intent(TaskerActivity.this, TaskerEventsActivity.class);
|
||||
intent.putExtra(TaskerConstants.DEVICE_INTENT, device);
|
||||
intent.putExtra(TaskerConstants.INTENT_DEVICE, device);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
@ -4,26 +4,38 @@ import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
||||
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;
|
||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.NoTaskDefinedException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
||||
import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Tasker event {@link AbstractSettingsActivity} takes {@link TaskerSpec} from {@link TaskerDevice#getSpec()}
|
||||
* to configure its {@link TaskerSettings} via {@link TaskerSpec#getSettings(TaskerEventType)}.
|
||||
* <p>
|
||||
* 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<EditTextPreference> 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;
|
||||
}
|
||||
|
||||
|
@ -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}
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
|
@ -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}.
|
||||
* <p>
|
||||
* 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<TaskerEventType, TaskerSettings> settings = new HashMap<>();
|
@ -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}.
|
||||
* <p>
|
||||
* 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);
|
@ -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.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/tasker_remove_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="@string/tasker_remove">
|
||||
</Button>
|
||||
</RelativeLayout >
|
@ -625,14 +625,26 @@
|
||||
<string name="language_and_region_prefs">Sprach- und Gebietseinstellungen</string>
|
||||
|
||||
<!-- Tasker -->
|
||||
|
||||
<string name="tasker">Tasker</string>
|
||||
<string name="tasker_enabled">Aktiv</string>
|
||||
<string name="tasker_enabled_sum">Aktiviert Tasker aber deaktiviert die Steuerung der Medien</string>
|
||||
<string name="tasker_task_single">Task für einzelnes drücken</string>
|
||||
<string name="tasker_task_double">Task für doppeltes drücken</string>
|
||||
<string name="tasker_task_triple">Task für dreifaches drücken</string>
|
||||
<string name="tasker_enabled">Aktiviert</string>
|
||||
<string name="tasker_enabled_sum">Aktiviert die Tasker-Unterstützung</string>
|
||||
<string name="tasker_add">Hinzufügen</string>
|
||||
<string name="tasker_remove">Entfernen</string>
|
||||
<string name="tasker_events">Ereignisse</string>
|
||||
<string name="tasker_event_button">Knopfdruck-Ereignis</string>
|
||||
<string name="tasker_event_connection">Verbindungs-Ereignis</string>
|
||||
<string name="tasker_event_data">Daten-Ereignis</string>
|
||||
<string name="tasker_event_enabled">Ereignistyp aktiviert</string>
|
||||
<string name="tasker_threshold_enable">Schwellenwert aktiviert</string>
|
||||
<string name="tasker_threshold_enable_sum">Aktiviert eine Verzögerung zwischen den Aufgaben</string>
|
||||
<string name="tasker_threshold">Schwellenwert in Millisekunden</string>
|
||||
<string name="tasker_threshold_sum">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.</string>
|
||||
<string name="tasker_task">Aufgabe</string>
|
||||
<string name="tasker_task_sum">Fügt eine Weitere Schwellwert-Aufgahinzube </string>
|
||||
<string name="tasker_task_name">Aufgabenname</string>
|
||||
<string name="tasker_info">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.</string>
|
||||
<string name="tasker_no_task_defined">Tasker ist aktiviert aber es wurde keine Aufgabe angegeben! Bitte gehen sie in die Tasker Einstellungen und definieren sie Aufgaben.</string>
|
||||
|
||||
<!-- XWatch -->
|
||||
<string name="xwatch_settings">XWatch Einstellungen</string>
|
||||
</resources>
|
||||
|
@ -677,9 +677,11 @@
|
||||
<string name="tasker_enabled_sum">Enables Tasker support</string>
|
||||
<string name="tasker_add">Add</string>
|
||||
<string name="tasker_remove">Remove</string>
|
||||
<string name="tasker_events">Events</string>
|
||||
<string name="tasker_event_button">Button Events</string>
|
||||
<string name="tasker_event_connection">Connection Events</string>
|
||||
<string name="tasker_event_data">Data Events</string>
|
||||
<string name="tasker_event_enabled">Enable event type</string>
|
||||
<string name="tasker_threshold_enable">Enable threshold</string>
|
||||
<string name="tasker_threshold_enable_sum">Enables delay between task</string>
|
||||
<string name="tasker_threshold">Threshold in milliseconds</string>
|
||||
@ -691,7 +693,4 @@
|
||||
(application, time, date, location, event, gesture) in user-defined profiles or in clickable or timer home screen widgets.</string>
|
||||
<string name="tasker_no_task_defined">No task defined! Please define a task in settings.</string>
|
||||
|
||||
<!-- XWatch -->
|
||||
<string name="xwatch_settings">XWatch settings</string>
|
||||
|
||||
</resources>
|
@ -746,7 +746,7 @@
|
||||
</PreferenceCategory>
|
||||
<!--<PreferenceCategory android:key="pref_key_tasker_group">-->
|
||||
<Preference
|
||||
android:key="pref_key_tasker"
|
||||
android:key="act_tasker"
|
||||
android:title="@string/tasker" />
|
||||
<!--</PreferenceCategory>-->
|
||||
</PreferenceScreen>
|
||||
|
@ -1,26 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="act_tasker_task_group">
|
||||
<PreferenceCategory android:key="tasker_event">
|
||||
<Preference
|
||||
android:key="tasker_info"
|
||||
android:persistent="false"
|
||||
android:selectable="false"
|
||||
android:summary="@string/tasker_info" />
|
||||
<SwitchPreference
|
||||
android:key="act_tasker_threshold_enabled"
|
||||
android:title="@string/tasker_threshold_enable" />
|
||||
<EditTextPreference
|
||||
android:inputType="number"
|
||||
android:key="act_tasker_threshold"
|
||||
android:summary="@string/tasker_threshold_sum"
|
||||
android:title="@string/tasker_threshold" />
|
||||
<nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference
|
||||
android:key="act_tasker_task_add"
|
||||
android:summary="@string/tasker_task_sum"
|
||||
android:title="@string/tasker_task"
|
||||
android:widgetLayout="@layout/tasker_add_button"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference>
|
||||
</PreferenceCategory>
|
||||
<SwitchPreference
|
||||
android:key="act_tasker_event_enabled"
|
||||
android:title="@string/tasker_event_enabled" />
|
||||
<SwitchPreference
|
||||
android:key="act_tasker_threshold_enabled"
|
||||
android:title="@string/tasker_threshold_enable" />
|
||||
<EditTextPreference
|
||||
android:inputType="number"
|
||||
android:key="act_tasker_threshold"
|
||||
android:summary="@string/tasker_threshold_sum"
|
||||
android:title="@string/tasker_threshold" />
|
||||
<nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference
|
||||
android:key="act_tasker_task_add"
|
||||
android:summary="@string/tasker_task_sum"
|
||||
android:title="@string/tasker_task"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference>
|
||||
<EditTextPreference
|
||||
android:key="act_tasker_task"
|
||||
android:summary="@string/tasker_task_name" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:key="pref_key_tasker_event_group" android:title="@string/tasker">
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="act_event_group"
|
||||
android:title="@string/tasker_events"></PreferenceCategory>
|
||||
</PreferenceScreen>
|
@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:key="pref_key_tasker_group" android:title="@string/tasker">
|
||||
<PreferenceCategory android:key="act_tasker_group" android:title="@string/tasker">
|
||||
<Preference
|
||||
android:persistent="false"
|
||||
android:selectable="false"
|
||||
android:summary="@string/tasker_info" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="tasker_enabled"
|
||||
android:key="act_tasker_enabled"
|
||||
android:summary="@string/tasker_enabled_sum"
|
||||
android:title="@string/tasker_enabled" />
|
||||
</PreferenceCategory>
|
||||
|
Loading…
Reference in New Issue
Block a user