mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-02-11 08:00:11 +01:00
TaskerSettings now binded to TaskerActivities.
This commit is contained in:
parent
9dee59f61a
commit
c6b20ea534
@ -417,16 +417,16 @@
|
|||||||
android:name=".activities.FindPhoneActivity"
|
android:name=".activities.FindPhoneActivity"
|
||||||
android:label="Find Phone" />
|
android:label="Find Phone" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".tasker.settings.TaskerActivity"
|
android:name=".tasker.settings.activities.TaskerActivity"
|
||||||
android:label="@string/tasker" />
|
android:label="@string/tasker" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".tasker.settings.TaskerEventActivity"
|
android:name=".tasker.settings.activities.TaskerEventActivity"
|
||||||
android:label="@string/tasker"
|
android:label="@string/tasker"
|
||||||
android:parentActivityName=".tasker.settings.TaskerEventsActivity" />
|
android:parentActivityName=".tasker.settings.activities.TaskerEventsActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".tasker.settings.TaskerEventsActivity"
|
android:name=".tasker.settings.activities.TaskerEventsActivity"
|
||||||
android:label="@string/tasker"
|
android:label="@string/tasker"
|
||||||
android:parentActivityName=".tasker.settings.TaskerActivity" />
|
android:parentActivityName=".tasker.settings.activities.TaskerActivity" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".contentprovider.PebbleContentProvider"
|
android:name=".contentprovider.PebbleContentProvider"
|
||||||
|
@ -57,7 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerActivity;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.TaskerActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
@ -25,7 +25,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
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.settings.TaskerSettings;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerSpec;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerSpec;
|
||||||
|
|
||||||
@ -49,10 +51,6 @@ public class XWatchService {
|
|||||||
XWATCH_DEBUG.put(UUID_SERVICE, "Get service");
|
XWATCH_DEBUG.put(UUID_SERVICE, "Get service");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TaskerSpec getTaskerSpec() {
|
|
||||||
return new XWatchTaskerSpec();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String lookup(UUID uuid, String fallback) {
|
public static String lookup(UUID uuid, String fallback) {
|
||||||
String name = XWATCH_DEBUG.get(uuid);
|
String name = XWATCH_DEBUG.get(uuid);
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
@ -61,33 +59,4 @@ public class XWatchService {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class XWatchTaskerSpec implements TaskerSpec {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TaskerEventType getEventType(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
|
||||||
if (UUID_NOTIFY.equals(characteristic.getUuid())) {
|
|
||||||
byte[] data = characteristic.getValue();
|
|
||||||
if (data[0] == XWatchService.COMMAND_ACTIVITY_DATA) {
|
|
||||||
return TaskerEventType.DATA;
|
|
||||||
}
|
|
||||||
if (data[0] == XWatchService.COMMAND_ACTION_BUTTON) {
|
|
||||||
return TaskerEventType.BUTTON;
|
|
||||||
}
|
|
||||||
if (data[0] == XWatchService.COMMAND_CONNECTED) {
|
|
||||||
return TaskerEventType.CONNECTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TaskerEventType.NO_OP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TaskerEventType> getSupportedTypes() {
|
|
||||||
return Arrays.asList(TaskerEventType.BUTTON, TaskerEventType.DATA, TaskerEventType.CONNECTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TaskerSettings getTaskerSettings(TaskerEventType eventType) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.xwatch;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.AbstractTaskerSpec;
|
||||||
|
|
||||||
|
public class XWatchTaskerSpec extends AbstractTaskerSpec {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskerEventType getEventType(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||||
|
if (XWatchService.UUID_NOTIFY.equals(characteristic.getUuid())) {
|
||||||
|
byte[] data = characteristic.getValue();
|
||||||
|
if (data[0] == XWatchService.COMMAND_ACTIVITY_DATA) {
|
||||||
|
return TaskerEventType.DATA;
|
||||||
|
}
|
||||||
|
if (data[0] == XWatchService.COMMAND_ACTION_BUTTON) {
|
||||||
|
return TaskerEventType.BUTTON;
|
||||||
|
}
|
||||||
|
if (data[0] == XWatchService.COMMAND_CONNECTED) {
|
||||||
|
return TaskerEventType.CONNECTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TaskerEventType.NO_OP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TaskerEventType> getSupportedTypes() {
|
||||||
|
return Arrays.asList(TaskerEventType.BUTTON, TaskerEventType.DATA, TaskerEventType.CONNECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -61,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.DeviceInfo;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.DeviceInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerBleProfile;
|
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.task.TaskerTaskProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerService;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
||||||
@ -81,7 +82,7 @@ public class XWatchSupport extends AbstractBTLEDeviceSupport {
|
|||||||
addSupportedService(XWatchService.UUID_SERVICE);
|
addSupportedService(XWatchService.UUID_SERVICE);
|
||||||
addSupportedService(XWatchService.UUID_WRITE);
|
addSupportedService(XWatchService.UUID_WRITE);
|
||||||
addSupportedService(XWatchService.UUID_NOTIFY);
|
addSupportedService(XWatchService.UUID_NOTIFY);
|
||||||
addSupportedProfile(new TaskerBleProfile<>(this, XWatchService.getTaskerSpec()));
|
addSupportedProfile(new TaskerBleProfile<>(this, TaskerConstants.TaskerDevice.XWATCH));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] crcChecksum(byte[] data) {
|
public static byte[] crcChecksum(byte[] data) {
|
||||||
|
@ -9,6 +9,14 @@ public interface SettingSupplier<T> {
|
|||||||
|
|
||||||
T get();
|
T get();
|
||||||
|
|
||||||
|
void set(T object);
|
||||||
|
|
||||||
boolean isPresent();
|
boolean isPresent();
|
||||||
|
|
||||||
|
SettingSupplier<T> onChanged(SettingListener<T> onChanged);
|
||||||
|
|
||||||
|
interface SettingListener<T> {
|
||||||
|
void changed(T object);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.tasker.event;
|
||||||
|
|
||||||
|
public class SettingSupplierImpl<T> implements SettingSupplier<T> {
|
||||||
|
|
||||||
|
private T object;
|
||||||
|
private SettingListener<T> onChanged;
|
||||||
|
|
||||||
|
public SettingSupplierImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SettingSupplierImpl(T object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(T object) {
|
||||||
|
this.object = object;
|
||||||
|
onChanged.changed(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPresent() {
|
||||||
|
return object != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<T> onChanged(SettingListener<T> onChanged) {
|
||||||
|
this.onChanged = onChanged;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
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.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTask;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tasker service for scheduling task with specific thresholds.
|
||||||
|
* <p>
|
||||||
|
* One instance per thread/device! The service is not threadsafe.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractTaskerService {
|
||||||
|
|
||||||
|
protected SettingSupplier<Boolean> enabled;
|
||||||
|
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
private Map<TaskerEventType, TaskerTask> tasks = new HashMap<>();
|
||||||
|
private static final long DEFAULT_THRESHOLD = 50L;
|
||||||
|
|
||||||
|
public AbstractTaskerService() {
|
||||||
|
this.enabled = new SettingSupplierImpl<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean get() {
|
||||||
|
return GBApplication.getPrefs().getBoolean(TaskerConstants.TASKER_ENABLED, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return enabled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean runForType(TaskerEventType type) {
|
||||||
|
if (type != null && !TaskerEventType.NO_OP.equals(type) && isActive() && ready()) {
|
||||||
|
if (!tasks.containsKey(type)) {
|
||||||
|
SettingSupplier<TaskerTaskProvider> taskProvider = taskProvider(type);
|
||||||
|
if (taskProvider.isPresent()) {
|
||||||
|
SettingSupplier<Long> threshold = threshold(type);
|
||||||
|
tasks.put(type, new TaskerTask(type, taskProvider.get(), threshold.isPresent() ? threshold.get() : DEFAULT_THRESHOLD));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks.get(type).schedule(executor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract SettingSupplier<Long> threshold(TaskerEventType type);
|
||||||
|
|
||||||
|
protected abstract SettingSupplier<TaskerTaskProvider> taskProvider(TaskerEventType type);
|
||||||
|
|
||||||
|
public static boolean ready() {
|
||||||
|
return TaskerIntent.testStatus(GBApplication.getContext()).equals(TaskerIntent.Status.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
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.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
|
public abstract class AbstractTaskerSpec implements TaskerSpec {
|
||||||
|
|
||||||
|
private Map<TaskerEventType, TaskerSettings> settings = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskerSettings getSettings(TaskerEventType eventType) {
|
||||||
|
if (!settings.containsKey(eventType)) {
|
||||||
|
if (!getSupportedTypes().contains(eventType)) {
|
||||||
|
settings.put(eventType, new NoOpTaskerSettings());
|
||||||
|
} else {
|
||||||
|
settings.put(eventType, new SimpleTaskerSettings());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return settings.get(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SimpleTaskerSettings implements TaskerSettings {
|
||||||
|
private SettingSupplier<Boolean> consumingEvents = new SettingSupplierImpl<>();
|
||||||
|
private SettingSupplier<Boolean> enabled = new SettingSupplierImpl<>();
|
||||||
|
private SettingSupplier<Long> threshold = new SettingSupplierImpl<>();
|
||||||
|
private SettingSupplier<TaskerTaskProvider> taskProvider = new SettingSupplierImpl<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Boolean> isConsumingEvents() {
|
||||||
|
return consumingEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Boolean> isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Long> getThreshold() {
|
||||||
|
return threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<TaskerTaskProvider> getTaskProvider() {
|
||||||
|
return taskProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class NoOpTaskerSettings implements TaskerSettings {
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Boolean> isConsumingEvents() {
|
||||||
|
return new NoOpSupplier<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Boolean> isEnabled() {
|
||||||
|
return new NoOpSupplier<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<Long> getThreshold() {
|
||||||
|
return new NoOpSupplier<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<TaskerTaskProvider> getTaskProvider() {
|
||||||
|
return new NoOpSupplier<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoOpSupplier<T> implements SettingSupplier<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(T object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPresent() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingSupplier<T> onChanged(SettingListener<T> onChanged) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TaskerSpec} impl for {@link AbstractTaskerService}.
|
||||||
|
*/
|
||||||
|
public class SpecTaskerService extends AbstractTaskerService {
|
||||||
|
|
||||||
|
private TaskerSpec spec;
|
||||||
|
|
||||||
|
public SpecTaskerService(TaskerSpec spec) {
|
||||||
|
this.spec = spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SettingSupplier<Long> threshold(TaskerEventType type) {
|
||||||
|
return spec.getSettings(type).getThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SettingSupplier<TaskerTaskProvider> taskProvider(TaskerEventType type) {
|
||||||
|
return spec.getSettings(type).getTaskProvider();
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
|||||||
public abstract class TaskerAbstractSpec implements TaskerSpec {
|
public abstract class TaskerAbstractSpec implements TaskerSpec {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskerSettings getTaskerSettings(TaskerEventType eventType) {
|
public TaskerSettings getSettings(TaskerEventType eventType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,33 +17,26 @@ import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
|||||||
*/
|
*/
|
||||||
public class TaskerBleProfile<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
|
public class TaskerBleProfile<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
|
||||||
|
|
||||||
private TaskerService taskerService;
|
private SpecTaskerService taskerService;
|
||||||
private TaskerSpec taskerSpec;
|
private TaskerConstants.TaskerDevice taskerDevice;
|
||||||
|
|
||||||
public TaskerBleProfile(T support, TaskerSpec taskerSpec) {
|
public TaskerBleProfile(T support, TaskerConstants.TaskerDevice taskerDevice) {
|
||||||
super(support);
|
super(support);
|
||||||
this.taskerSpec = taskerSpec;
|
this.taskerDevice = taskerDevice;
|
||||||
taskerService = new TaskerService();
|
taskerService = new SpecTaskerService(taskerDevice.getSpec());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||||
TaskerEventType eventType = taskerSpec.getEventType(gatt, characteristic);
|
TaskerEventType eventType = taskerDevice.getSpec().getEventType(gatt, characteristic);
|
||||||
if (TaskerEventType.NO_OP.equals(eventType)) {
|
if (TaskerEventType.NO_OP.equals(eventType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TaskerSettings settings = taskerSpec.getTaskerSettings(eventType);
|
TaskerSettings settings = taskerDevice.getSpec().getSettings(eventType);
|
||||||
if (settings.isEnabled().isPresent() && settings.isEnabled().get()) {
|
if (settings.isEnabled().isPresent() && settings.isEnabled().get()) {
|
||||||
TaskerService service = taskerService;
|
|
||||||
if (settings.getThreshold().isPresent()) {
|
|
||||||
service = service.withThreshold(eventType, settings.getThreshold().get());
|
|
||||||
}
|
|
||||||
if (settings.getTaskProvider().isPresent()) {
|
|
||||||
service = service.withProvider(eventType, settings.getTaskProvider().get());
|
|
||||||
}
|
|
||||||
boolean run = false;
|
boolean run = false;
|
||||||
try {
|
try {
|
||||||
run = service.runForType(eventType);
|
run = taskerService.runForType(eventType);
|
||||||
} catch (NoTaskDefinedException e) {
|
} catch (NoTaskDefinedException e) {
|
||||||
TaskerUtil.noTaskDefinedInformation().show();
|
TaskerUtil.noTaskDefinedInformation().show();
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import java.io.Serializable;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
|
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchTaskerSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class TaskerConstants {
|
public class TaskerConstants {
|
||||||
@ -30,7 +31,7 @@ public class TaskerConstants {
|
|||||||
|
|
||||||
public enum TaskerDevice implements Serializable {
|
public enum TaskerDevice implements Serializable {
|
||||||
|
|
||||||
XWATCH(DeviceType.XWATCH, XWatchService.getTaskerSpec());
|
XWATCH(DeviceType.XWATCH, new XWatchTaskerSpec());
|
||||||
|
|
||||||
private DeviceType type;
|
private DeviceType type;
|
||||||
private TaskerSpec spec;
|
private TaskerSpec spec;
|
||||||
|
@ -10,61 +10,33 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTask;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTask;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tasker service for scheduling task with specific thresholds.
|
* Default impl for {@link AbstractTaskerService}.
|
||||||
* <p>
|
* <p>
|
||||||
* One instance per thread/device! The service is not threadsafe.
|
* One instance per thread/device! The service is not threadsafe.
|
||||||
*/
|
*/
|
||||||
public class TaskerService {
|
public class TaskerService extends AbstractTaskerService {
|
||||||
|
|
||||||
private SettingSupplier<Boolean> enabled;
|
|
||||||
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
private Map<TaskerEventType, TaskerTask> tasks = new HashMap<>();
|
|
||||||
private Map<TaskerEventType, SettingSupplier<Long>> threshold = new HashMap<>();
|
private Map<TaskerEventType, SettingSupplier<Long>> threshold = new HashMap<>();
|
||||||
private Map<TaskerEventType, SettingSupplier<TaskerTaskProvider>> typeProvider = new HashMap<>();
|
private Map<TaskerEventType, SettingSupplier<TaskerTaskProvider>> typeProvider = new HashMap<>();
|
||||||
private long defaultThreshold = 50L;
|
|
||||||
|
|
||||||
// Builder
|
|
||||||
|
|
||||||
public TaskerService() {
|
|
||||||
this.enabled = new SettingSupplier<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean get() {
|
|
||||||
return GBApplication.getPrefs().getBoolean(TaskerConstants.TASKER_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPresent() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskerService(SettingSupplier<Boolean> enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskerService(boolean enabled) {
|
public TaskerService(boolean enabled) {
|
||||||
this.enabled = new StaticSettingSupplier<>(enabled);
|
this.enabled = new SettingSupplierImpl<>(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskerService withThreshold(TaskerEventType type, long threshold) {
|
public TaskerService withThreshold(TaskerEventType type, long threshold) {
|
||||||
this.threshold.put(type, new StaticSettingSupplier<>(threshold));
|
this.threshold.put(type, new SettingSupplierImpl<>(threshold));
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskerService withThreshold(TaskerEventType type, SettingSupplier<Long> threshold) {
|
|
||||||
this.threshold.put(type, threshold);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskerService withTask(TaskerEventType type, final String task) {
|
public TaskerService withTask(TaskerEventType type, final String task) {
|
||||||
typeProvider.put(type, new StaticSettingSupplier<TaskerTaskProvider>(new TaskerTaskProvider() {
|
typeProvider.put(type, new SettingSupplierImpl<TaskerTaskProvider>(new TaskerTaskProvider() {
|
||||||
@Override
|
@Override
|
||||||
public String getTask(TaskerEvent event) {
|
public String getTask(TaskerEvent event) {
|
||||||
return task;
|
return task;
|
||||||
@ -74,83 +46,22 @@ public class TaskerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TaskerService withProvider(TaskerEventType type, TaskerTaskProvider provider) {
|
public TaskerService withProvider(TaskerEventType type, TaskerTaskProvider provider) {
|
||||||
typeProvider.put(type, new StaticSettingSupplier<>(provider));
|
typeProvider.put(type, new SettingSupplierImpl<>(provider));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskerService withProvider(TaskerEventType type, SettingSupplier<TaskerTaskProvider> provider) {
|
|
||||||
typeProvider.put(type, provider);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
|
|
||||||
public boolean isActive() {
|
|
||||||
return enabled.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean buttonPressed(int index) {
|
|
||||||
return runForType(TaskerEventType.BUTTON.withIndex(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean deviceConnected(int index) {
|
|
||||||
return runForType(TaskerEventType.CONNECTION.withIndex(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean dataReceived(int index) {
|
|
||||||
return runForType(TaskerEventType.DATA.withIndex(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean runForType(TaskerEventType type) {
|
|
||||||
if (type != null && !TaskerEventType.NO_OP.equals(type) && isActive() && ready()) {
|
|
||||||
if (!tasks.containsKey(type)) {
|
|
||||||
if (taskProvider(type) != null) {
|
|
||||||
tasks.put(type, new TaskerTask(type, taskProvider(type), threshold(type)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks.get(type).schedule(executor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
private long threshold(TaskerEventType type) {
|
protected SettingSupplier<Long> threshold(TaskerEventType type) {
|
||||||
return threshold.containsKey(type) && threshold.get(type).isPresent() ? threshold.get(type).get() : defaultThreshold;
|
return threshold.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskerTaskProvider taskProvider(TaskerEventType type) {
|
protected SettingSupplier<TaskerTaskProvider> taskProvider(TaskerEventType type) {
|
||||||
if (typeProvider.containsKey(type) && typeProvider.get(type).isPresent()) {
|
if (typeProvider.containsKey(type) && typeProvider.get(type).isPresent()) {
|
||||||
return typeProvider.get(type).get();
|
return typeProvider.get(type);
|
||||||
}
|
}
|
||||||
throw new NoTaskDefinedException();
|
throw new NoTaskDefinedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static
|
|
||||||
|
|
||||||
public static boolean ready() {
|
|
||||||
return TaskerIntent.testStatus(GBApplication.getContext()).equals(TaskerIntent.Status.OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class StaticSettingSupplier<T> implements SettingSupplier<T> {
|
|
||||||
|
|
||||||
private T setting;
|
|
||||||
|
|
||||||
public StaticSettingSupplier(T setting) {
|
|
||||||
this.setting = setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T get() {
|
|
||||||
return setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPresent() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ public interface TaskerSpec {
|
|||||||
|
|
||||||
List<TaskerEventType> getSupportedTypes();
|
List<TaskerEventType> getSupportedTypes();
|
||||||
|
|
||||||
TaskerSettings getTaskerSettings(TaskerEventType eventType);
|
TaskerSettings getSettings(TaskerEventType eventType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
@ -1,14 +1,12 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceCategory;
|
import android.preference.PreferenceCategory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
||||||
|
|
||||||
public class TaskerActivity extends AbstractSettingsActivity {
|
public class TaskerActivity extends AbstractSettingsActivity {
|
@ -1,18 +1,19 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceCategory;
|
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
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.event.TaskerEventType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
public class TaskerEventActivity extends AbstractSettingsActivity {
|
public class TaskerEventActivity extends AbstractSettingsActivity {
|
||||||
@ -34,19 +35,23 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
device = (TaskerConstants.TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.DEVICE_INTENT);
|
device = (TaskerConstants.TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.DEVICE_INTENT);
|
||||||
|
final TaskerSettings settings = device.getSpec().getSettings(eventType);
|
||||||
eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.EVENT_INTENT);
|
eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.EVENT_INTENT);
|
||||||
final PreferenceScreen tasks = (PreferenceScreen) findPreference(TaskerConstants.ACTIVITY_TASKS);
|
final PreferenceScreen tasks = (PreferenceScreen) findPreference(TaskerConstants.ACTIVITY_TASKS);
|
||||||
ButtonPreference addTaskButton = (ButtonPreference) findPreference(TaskerConstants.ACTIVITY_TASK_ADD);
|
initThreshold(settings, tasks);
|
||||||
final EditTextPreference taskNamePreference = (EditTextPreference) findPreference(TaskerConstants.ACTIVITY_TASK);
|
initTasks(settings, tasks);
|
||||||
final Preference thresholdEnabled = findPreference(TaskerConstants.ACTIVITY_THESHOLD_ENABELD);
|
}
|
||||||
addTaskButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
|
private void initThreshold(final TaskerSettings settings, final PreferenceScreen tasks) {
|
||||||
|
EditTextPreference threshold = (EditTextPreference) findPreference(TaskerConstants.ACTIVITY_THRESHOLD);
|
||||||
|
threshold.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
if (prefs.getBoolean(thresholdEnabled.getKey(), false)) {
|
settings.getThreshold().set(Long.valueOf(newValue.toString()));
|
||||||
tasks.addPreference(task(tasks, taskNamePreference));
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
final Preference thresholdEnabled = findPreference(TaskerConstants.ACTIVITY_THESHOLD_ENABELD);
|
||||||
thresholdEnabled.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
thresholdEnabled.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
@ -55,11 +60,38 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
tasks.removePreference(tasks.getPreference(tasks.getPreferenceCount()));
|
tasks.removePreference(tasks.getPreference(tasks.getPreferenceCount()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
settings.getThreshold().set(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
addTaskButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (prefs.getBoolean(TaskerConstants.ACTIVITY_THESHOLD_ENABELD, false)) {
|
||||||
|
tasks.addPreference(task(tasks, taskNamePreference));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
settings.getTaskProvider().set(taskerTaskProvider);
|
||||||
|
}
|
||||||
|
|
||||||
private Preference task(final PreferenceScreen tasks, Preference build) {
|
private Preference task(final PreferenceScreen tasks, Preference build) {
|
||||||
final ButtonPreference task = new ButtonPreference(this);
|
final ButtonPreference task = new ButtonPreference(this);
|
||||||
task.setKey(TaskerConstants.ACTIVITY_TASK + "_" + tasks.getPreferenceCount());
|
task.setKey(TaskerConstants.ACTIVITY_TASK + "_" + tasks.getPreferenceCount());
|
@ -1,4 +1,4 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -7,7 +7,6 @@ import android.preference.PreferenceCategory;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
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.event.TaskerEventType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
||||||
|
|
@ -15,11 +15,11 @@
|
|||||||
android:key="act_tasker_threshold"
|
android:key="act_tasker_threshold"
|
||||||
android:summary="@string/tasker_threshold_sum"
|
android:summary="@string/tasker_threshold_sum"
|
||||||
android:title="@string/tasker_threshold" />
|
android:title="@string/tasker_threshold" />
|
||||||
<nodomain.freeyourgadget.gadgetbridge.tasker.settings.ButtonPreference
|
<nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference
|
||||||
android:key="act_tasker_task_add"
|
android:key="act_tasker_task_add"
|
||||||
android:summary="@string/tasker_task_sum"
|
android:summary="@string/tasker_task_sum"
|
||||||
android:title="@string/tasker_task"
|
android:title="@string/tasker_task"
|
||||||
android:widgetLayout="@layout/tasker_add_button"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.ButtonPreference>
|
android:widgetLayout="@layout/tasker_add_button"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:key="act_tasker_task"
|
android:key="act_tasker_task"
|
||||||
|
Loading…
Reference in New Issue
Block a user