mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-02-11 08:00:11 +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.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.plugin.TaskerConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.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;
|
||||||
@ -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
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
Intent enableIntent = new Intent(SettingsActivity.this, TaskerActivity.class);
|
Intent enableIntent = new Intent(SettingsActivity.this, TaskerActivity.class);
|
||||||
|
@ -16,21 +16,10 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.devices.xwatch;
|
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.HashMap;
|
||||||
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.service.AbstractTaskerSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerSpec;
|
|
||||||
|
|
||||||
public class XWatchService {
|
public class XWatchService {
|
||||||
public static final UUID UUID_NOTIFY = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb");
|
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");
|
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 java.util.List;
|
||||||
|
|
||||||
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.spec.AbstractTaskerSpec;
|
||||||
|
|
||||||
public class XWatchTaskerSpec extends 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.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
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.XWatchSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
|
import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
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.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.plugin.TaskerBleProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.service.TaskerConstants;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerDevice;
|
||||||
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.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class XWatchSupport extends AbstractBTLEDeviceSupport {
|
public class XWatchSupport extends AbstractBTLEDeviceSupport {
|
||||||
@ -82,7 +78,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, TaskerConstants.TaskerDevice.XWATCH));
|
addSupportedProfile(new TaskerBleProfile<>(this, TaskerDevice.XWATCH));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] crcChecksum(byte[] data) {
|
public static byte[] crcChecksum(byte[] data) {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.event;
|
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 {
|
public class TaskerEvent {
|
||||||
|
|
||||||
private TaskerEventType type;
|
private TaskerEventType type;
|
||||||
@ -10,6 +19,11 @@ public class TaskerEvent {
|
|||||||
this.count = count;
|
this.count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tasker event type of this event.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public TaskerEventType getType() {
|
public TaskerEventType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -18,6 +32,11 @@ public class TaskerEvent {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count how often this event is thrown in the {@link TaskerSettings#getThreshold()}
|
||||||
|
*
|
||||||
|
* @return Fired times
|
||||||
|
*/
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,14 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
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 class TaskerEventType implements Serializable {
|
||||||
|
|
||||||
public static TaskerEventType BUTTON = TaskerEventType.create("button").withLocalization(R.string.tasker_event_button);
|
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;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
TaskerEventType that = (TaskerEventType) o;
|
TaskerEventType that = (TaskerEventType) o;
|
||||||
return index == that.index &&
|
return index == that.index &&
|
||||||
type == that.type;
|
Objects.equals(type, that.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
|
||||||
return Objects.hash(type, index);
|
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 class TaskerActionCodes {
|
||||||
|
|
||||||
public static final int NONE = -1;
|
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.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
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.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
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.settings.TaskerSettings;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tasker plugin hook as BLE profile.
|
* 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> {
|
public class TaskerBleProfile<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
|
||||||
|
|
||||||
private SpecTaskerService taskerService;
|
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);
|
super(support);
|
||||||
this.taskerDevice = taskerDevice;
|
this.taskerDevice = taskerDevice;
|
||||||
taskerService = new SpecTaskerService(taskerDevice.getSpec());
|
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 java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
|
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.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;
|
||||||
@ -28,17 +30,28 @@ public abstract class AbstractTaskerService {
|
|||||||
this.enabled = new SettingSupplierImpl<Boolean>() {
|
this.enabled = new SettingSupplierImpl<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean get() {
|
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();
|
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) {
|
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)) {
|
if (!tasks.containsKey(type)) {
|
||||||
SettingSupplier<TaskerTaskProvider> taskProvider = taskProvider(type);
|
SettingSupplier<TaskerTaskProvider> taskProvider = taskProvider(type);
|
||||||
if (taskProvider.isPresent()) {
|
if (taskProvider.isPresent()) {
|
||||||
@ -56,7 +69,12 @@ public abstract class AbstractTaskerService {
|
|||||||
|
|
||||||
protected abstract SettingSupplier<TaskerTaskProvider> taskProvider(TaskerEventType type);
|
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);
|
return TaskerIntent.testStatus(GBApplication.getContext()).equals(TaskerIntent.Status.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
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 class NoTaskDefinedException extends RuntimeException {
|
||||||
|
|
||||||
public NoTaskDefinedException() {
|
public NoTaskDefinedException() {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
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.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link TaskerSpec} impl for {@link AbstractTaskerService}.
|
* {@link TaskerSpec} implementation for {@link TaskerService}.
|
||||||
*/
|
*/
|
||||||
public class SpecTaskerService extends AbstractTaskerService {
|
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;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
||||||
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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.settings.SettingSupplier;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplierImpl;
|
||||||
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.TaskerTaskProvider;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default impl for {@link AbstractTaskerService}.
|
* Default implementation for {@link AbstractTaskerService}.
|
||||||
* <p>
|
* <p>
|
||||||
* One instance per thread/device! The service is not threadsafe.
|
* Preferred to use with java based configuration.
|
||||||
*/
|
*/
|
||||||
public class TaskerService extends AbstractTaskerService {
|
public class TaskerService extends AbstractTaskerService {
|
||||||
|
|
||||||
@ -30,11 +23,25 @@ public class TaskerService extends AbstractTaskerService {
|
|||||||
this.enabled = new SettingSupplierImpl<>(enabled);
|
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) {
|
public TaskerService withThreshold(TaskerEventType type, long threshold) {
|
||||||
this.threshold.put(type, new SettingSupplierImpl<>(threshold));
|
this.threshold.put(type, new SettingSupplierImpl<>(threshold));
|
||||||
return this;
|
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) {
|
public TaskerService withTask(TaskerEventType type, final String task) {
|
||||||
typeProvider.put(type, new SettingSupplierImpl<TaskerTaskProvider>(new TaskerTaskProvider() {
|
typeProvider.put(type, new SettingSupplierImpl<TaskerTaskProvider>(new TaskerTaskProvider() {
|
||||||
@Override
|
@Override
|
||||||
@ -45,13 +52,18 @@ public class TaskerService extends AbstractTaskerService {
|
|||||||
return this;
|
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) {
|
public TaskerService withProvider(TaskerEventType type, TaskerTaskProvider provider) {
|
||||||
typeProvider.put(type, new SettingSupplierImpl<>(provider));
|
typeProvider.put(type, new SettingSupplierImpl<>(provider));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
|
||||||
|
|
||||||
protected SettingSupplier<Long> threshold(TaskerEventType type) {
|
protected SettingSupplier<Long> threshold(TaskerEventType type) {
|
||||||
return threshold.get(type);
|
return threshold.get(type);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerIntent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tasker convenience methods for direct access to tasker without {@link TaskerService}.
|
* 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
|
* @param <T> Setting
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,11 @@ public interface SettingSupplier<T> {
|
|||||||
|
|
||||||
SettingSupplier<T> onChanged(SettingListener<T> onChanged);
|
SettingSupplier<T> onChanged(SettingListener<T> onChanged);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to changes in {@link SettingSupplier}.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
interface SettingListener<T> {
|
interface SettingListener<T> {
|
||||||
void changed(T object);
|
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> {
|
public class SettingSupplierImpl<T> implements SettingSupplier<T> {
|
||||||
|
|
||||||
private T object;
|
private T object;
|
||||||
@ -20,8 +25,10 @@ public class SettingSupplierImpl<T> implements SettingSupplier<T> {
|
|||||||
@Override
|
@Override
|
||||||
public void set(T object) {
|
public void set(T object) {
|
||||||
this.object = object;
|
this.object = object;
|
||||||
|
if (onChanged != null) {
|
||||||
onChanged.changed(object);
|
onChanged.changed(object);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPresent() {
|
public boolean isPresent() {
|
@ -1,16 +1,45 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.settings;
|
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;
|
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 {
|
public interface TaskerSettings {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes events or just listens to them.
|
||||||
|
*
|
||||||
|
* @return True if consumes events.
|
||||||
|
*/
|
||||||
SettingSupplier<Boolean> isConsumingEvents();
|
SettingSupplier<Boolean> isConsumingEvents();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the settings.
|
||||||
|
*
|
||||||
|
* @return True if settings are enabled.
|
||||||
|
*/
|
||||||
SettingSupplier<Boolean> isEnabled();
|
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();
|
SettingSupplier<Long> getThreshold();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TaskerTaskProvider} determines the task names for {@link nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent}.
|
||||||
|
*
|
||||||
|
* @return Task provider
|
||||||
|
*/
|
||||||
SettingSupplier<TaskerTaskProvider> getTaskProvider();
|
SettingSupplier<TaskerTaskProvider> getTaskProvider();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,11 @@ import android.widget.Button;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
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 {
|
public class ButtonPreference extends EditTextPreference {
|
||||||
|
|
||||||
private View.OnClickListener onClickListener;
|
private View.OnClickListener onClickListener;
|
||||||
@ -15,6 +20,7 @@ public class ButtonPreference extends EditTextPreference {
|
|||||||
|
|
||||||
public ButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
public ButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
|
setWidgetLayoutResource(R.layout.button_preference_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ButtonPreference(Context context, AttributeSet attrs) {
|
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) {
|
public void setOnClickListener(View.OnClickListener clickListener) {
|
||||||
this.onClickListener = clickListener;
|
this.onClickListener = clickListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set button text with resource id.
|
||||||
|
*
|
||||||
|
* @param resourceId {@link R.string}
|
||||||
|
*/
|
||||||
public void setButtonText(int resourceId) {
|
public void setButtonText(int resourceId) {
|
||||||
if (button != null) {
|
if (button != null) {
|
||||||
button.setText(resourceId);
|
button.setText(resourceId);
|
||||||
|
@ -7,16 +7,22 @@ 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.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 {
|
public class TaskerActivity extends AbstractSettingsActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.xml.tasker_preferences);
|
addPreferencesFromResource(R.xml.tasker_preferences);
|
||||||
final PreferenceCategory group = (PreferenceCategory) findPreference(TaskerConstants.TASKER_PREF_GROUP);
|
final PreferenceCategory group = (PreferenceCategory) findPreference(TaskerConstants.ACTIVITY_TASKER_GROUP);
|
||||||
for (TaskerConstants.TaskerDevice device : TaskerConstants.TaskerDevice.values()) {
|
for (TaskerDevice device : TaskerDevice.values()) {
|
||||||
group.addPreference(preference(device));
|
group.addPreference(preference(device));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,14 +32,14 @@ public class TaskerActivity extends AbstractSettingsActivity {
|
|||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Preference preference(final TaskerConstants.TaskerDevice device) {
|
private Preference preference(final TaskerDevice device) {
|
||||||
Preference devicePreference = new Preference(this);
|
Preference devicePreference = new Preference(this);
|
||||||
devicePreference.setTitle(device.getType().getName());
|
devicePreference.setTitle(device.getType().getName());
|
||||||
devicePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
devicePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
Intent intent = new Intent(TaskerActivity.this, TaskerEventsActivity.class);
|
Intent intent = new Intent(TaskerActivity.this, TaskerEventsActivity.class);
|
||||||
intent.putExtra(TaskerConstants.DEVICE_INTENT, device);
|
intent.putExtra(TaskerConstants.INTENT_DEVICE, device);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4,26 +4,38 @@ import android.os.Bundle;
|
|||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.preference.SwitchPreference;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
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.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.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.settings.TaskerSettings;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.spec.TaskerSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
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 {
|
public class TaskerEventActivity extends AbstractSettingsActivity {
|
||||||
|
|
||||||
private TaskerConstants.TaskerDevice device;
|
private TaskerDevice device;
|
||||||
private TaskerEventType eventType;
|
private TaskerEventType eventType;
|
||||||
private Prefs prefs = GBApplication.getPrefs();
|
private Prefs prefs = GBApplication.getPrefs();
|
||||||
|
private List<EditTextPreference> taskPreferences = new ArrayList<>();
|
||||||
public TaskerEventActivity() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -34,16 +46,31 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
@Override
|
@Override
|
||||||
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 = (TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.INTENT_DEVICE);
|
||||||
|
eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.INTENT_EVENT);
|
||||||
final TaskerSettings settings = device.getSpec().getSettings(eventType);
|
final TaskerSettings settings = device.getSpec().getSettings(eventType);
|
||||||
eventType = (TaskerEventType) getIntent().getSerializableExtra(TaskerConstants.EVENT_INTENT);
|
SwitchPreference enabled = (SwitchPreference) findPreference(scoped(TaskerConstants.ACTIVITY_EVENT_ENABLED));
|
||||||
final PreferenceScreen tasks = (PreferenceScreen) findPreference(TaskerConstants.ACTIVITY_TASKS);
|
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);
|
initThreshold(settings, tasks);
|
||||||
initTasks(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) {
|
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() {
|
threshold.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
@ -51,28 +78,43 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
return true;
|
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() {
|
thresholdEnabled.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
if (newValue.equals(Boolean.FALSE)) {
|
if (newValue.equals(Boolean.FALSE)) {
|
||||||
for (int i = 2; i < tasks.getPreferenceCount(); i++) {
|
for (EditTextPreference taskPreference : taskPreferences) {
|
||||||
tasks.removePreference(tasks.getPreference(tasks.getPreferenceCount()));
|
if (!taskPreference.getKey().equals(scoped(TaskerConstants.ACTIVITY_TASK))) {
|
||||||
|
tasks.removePreference(taskPreference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.getThreshold().set(null);
|
settings.getThreshold().set(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
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) {
|
private void initTasks(final TaskerSettings settings, final PreferenceScreen tasks) {
|
||||||
ButtonPreference addTaskButton = (ButtonPreference) findPreference(TaskerConstants.ACTIVITY_TASK_ADD);
|
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() {
|
addTaskButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
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));
|
tasks.addPreference(task(tasks, taskNamePreference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,10 +122,12 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
TaskerTaskProvider taskerTaskProvider = new TaskerTaskProvider() {
|
TaskerTaskProvider taskerTaskProvider = new TaskerTaskProvider() {
|
||||||
@Override
|
@Override
|
||||||
public String getTask(TaskerEvent event) {
|
public String getTask(TaskerEvent event) {
|
||||||
for (int i = 1; i < tasks.getPreferenceCount(); i++) {
|
if (event.getCount() < taskPreferences.size()) {
|
||||||
if (event.getCount() == i - 1) {
|
String text = taskPreferences.get(event.getCount()).getText();
|
||||||
return ((EditTextPreference) tasks.getPreference(i)).getText();
|
if (StringUtils.isEmpty(text)) {
|
||||||
|
throw new NoTaskDefinedException();
|
||||||
}
|
}
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -94,17 +138,18 @@ public class TaskerEventActivity extends AbstractSettingsActivity {
|
|||||||
|
|
||||||
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(scoped(TaskerConstants.ACTIVITY_TASK) + "_" + tasks.getPreferenceCount());
|
||||||
task.setTitle(build.getTitle());
|
task.setTitle(build.getTitle());
|
||||||
task.setSummary(build.getSummary());
|
task.setSummary(build.getSummary());
|
||||||
task.setButtonText(R.string.tasker_remove);
|
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() {
|
task.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
tasks.removePreference(task);
|
tasks.removePreference(task);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
taskPreferences.add(task);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,11 +8,17 @@ 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.TaskerEventType;
|
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 {
|
public class TaskerEventsActivity extends AbstractSettingsActivity {
|
||||||
|
|
||||||
private TaskerConstants.TaskerDevice device;
|
private TaskerDevice device;
|
||||||
|
|
||||||
public TaskerEventsActivity() {
|
public TaskerEventsActivity() {
|
||||||
}
|
}
|
||||||
@ -21,8 +27,8 @@ public class TaskerEventsActivity extends AbstractSettingsActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.xml.tasker_events_preferences);
|
addPreferencesFromResource(R.xml.tasker_events_preferences);
|
||||||
device = (TaskerConstants.TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.DEVICE_INTENT);
|
device = (TaskerDevice) getIntent().getSerializableExtra(TaskerConstants.INTENT_DEVICE);
|
||||||
PreferenceCategory category = (PreferenceCategory) findPreference(TaskerConstants.PREF_EVENT_GROUP);
|
PreferenceCategory category = (PreferenceCategory) findPreference(TaskerConstants.ACTIVITY_EVENT_GROUP);
|
||||||
for (final TaskerEventType eventType : device.getSpec().getSupportedTypes()) {
|
for (final TaskerEventType eventType : device.getSpec().getSupportedTypes()) {
|
||||||
Preference preference = new Preference(this);
|
Preference preference = new Preference(this);
|
||||||
preference.setTitle(eventType.getLocalization());
|
preference.setTitle(eventType.getLocalization());
|
||||||
@ -30,8 +36,8 @@ public class TaskerEventsActivity extends AbstractSettingsActivity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
Intent intent = new Intent(TaskerEventsActivity.this, TaskerEventActivity.class);
|
Intent intent = new Intent(TaskerEventsActivity.this, TaskerEventActivity.class);
|
||||||
intent.putExtra(TaskerConstants.EVENT_INTENT, eventType);
|
intent.putExtra(TaskerConstants.INTENT_EVENT, eventType);
|
||||||
intent.putExtra(TaskerConstants.DEVICE_INTENT, device);
|
intent.putExtra(TaskerConstants.INTENT_DEVICE, device);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.tasker.service;
|
package nodomain.freeyourgadget.gadgetbridge.tasker.spec;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplier;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplier;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.SettingSupplierImpl;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.SettingSupplierImpl;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.task.TaskerTaskProvider;
|
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 {
|
public abstract class AbstractTaskerSpec implements TaskerSpec {
|
||||||
|
|
||||||
private Map<TaskerEventType, TaskerSettings> settings = new HashMap<>();
|
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.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
@ -6,8 +6,14 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEventType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.tasker.plugin.TaskerConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.settings.TaskerSettings;
|
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 {
|
public interface TaskerSpec {
|
||||||
|
|
||||||
TaskerEventType getEventType(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
|
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.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
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.service.TaskerService;
|
||||||
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.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 {
|
public class TaskerTask implements Runnable {
|
||||||
|
|
||||||
private Future task;
|
private Future task;
|
||||||
@ -39,11 +47,15 @@ public class TaskerTask implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (TaskerService.ready()) {
|
try {
|
||||||
|
if (TaskerService.isReady()) {
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
GBApplication.getContext().sendBroadcast(new TaskerIntent(provider.getTask(new TaskerEvent(type, count))));
|
GBApplication.getContext().sendBroadcast(new TaskerIntent(provider.getTask(new TaskerEvent(type, count))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NoTaskDefinedException e) {
|
||||||
|
TaskerUtil.noTaskDefinedInformation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
|
@ -2,8 +2,17 @@ package nodomain.freeyourgadget.gadgetbridge.tasker.task;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
import nodomain.freeyourgadget.gadgetbridge.tasker.event.TaskerEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tasker task provider provides task names {@link TaskerEvent} based.
|
||||||
|
*/
|
||||||
public interface TaskerTaskProvider {
|
public interface TaskerTaskProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task name for specific {@link TaskerEvent}
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* @return Task name
|
||||||
|
*/
|
||||||
String getTask(TaskerEvent event);
|
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>
|
<string name="language_and_region_prefs">Sprach- und Gebietseinstellungen</string>
|
||||||
|
|
||||||
<!-- Tasker -->
|
<!-- Tasker -->
|
||||||
|
|
||||||
<string name="tasker">Tasker</string>
|
<string name="tasker">Tasker</string>
|
||||||
<string name="tasker_enabled">Aktiv</string>
|
<string name="tasker_enabled">Aktiviert</string>
|
||||||
<string name="tasker_enabled_sum">Aktiviert Tasker aber deaktiviert die Steuerung der Medien</string>
|
<string name="tasker_enabled_sum">Aktiviert die Tasker-Unterstützung</string>
|
||||||
<string name="tasker_task_single">Task für einzelnes drücken</string>
|
<string name="tasker_add">Hinzufügen</string>
|
||||||
<string name="tasker_task_double">Task für doppeltes drücken</string>
|
<string name="tasker_remove">Entfernen</string>
|
||||||
<string name="tasker_task_triple">Task für dreifaches drücken</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>
|
</resources>
|
||||||
|
@ -677,9 +677,11 @@
|
|||||||
<string name="tasker_enabled_sum">Enables Tasker support</string>
|
<string name="tasker_enabled_sum">Enables Tasker support</string>
|
||||||
<string name="tasker_add">Add</string>
|
<string name="tasker_add">Add</string>
|
||||||
<string name="tasker_remove">Remove</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_button">Button Events</string>
|
||||||
<string name="tasker_event_connection">Connection Events</string>
|
<string name="tasker_event_connection">Connection Events</string>
|
||||||
<string name="tasker_event_data">Data 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">Enable threshold</string>
|
||||||
<string name="tasker_threshold_enable_sum">Enables delay between task</string>
|
<string name="tasker_threshold_enable_sum">Enables delay between task</string>
|
||||||
<string name="tasker_threshold">Threshold in milliseconds</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>
|
(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>
|
<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>
|
</resources>
|
@ -746,7 +746,7 @@
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<!--<PreferenceCategory android:key="pref_key_tasker_group">-->
|
<!--<PreferenceCategory android:key="pref_key_tasker_group">-->
|
||||||
<Preference
|
<Preference
|
||||||
android:key="pref_key_tasker"
|
android:key="act_tasker"
|
||||||
android:title="@string/tasker" />
|
android:title="@string/tasker" />
|
||||||
<!--</PreferenceCategory>-->
|
<!--</PreferenceCategory>-->
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:key="act_tasker_task_group">
|
android:key="act_tasker_task_group">
|
||||||
<PreferenceCategory android:key="tasker_event">
|
<SwitchPreference
|
||||||
<Preference
|
android:key="act_tasker_event_enabled"
|
||||||
android:key="tasker_info"
|
android:title="@string/tasker_event_enabled" />
|
||||||
android:persistent="false"
|
|
||||||
android:selectable="false"
|
|
||||||
android:summary="@string/tasker_info" />
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="act_tasker_threshold_enabled"
|
android:key="act_tasker_threshold_enabled"
|
||||||
android:title="@string/tasker_threshold_enable" />
|
android:title="@string/tasker_threshold_enable" />
|
||||||
@ -18,9 +15,7 @@
|
|||||||
<nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.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"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference>
|
||||||
android:widgetLayout="@layout/tasker_add_button"></nodomain.freeyourgadget.gadgetbridge.tasker.settings.activities.ButtonPreference>
|
|
||||||
</PreferenceCategory>
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:key="act_tasker_task"
|
android:key="act_tasker_task"
|
||||||
android:summary="@string/tasker_task_name" />
|
android:summary="@string/tasker_task_name" />
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<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>
|
</PreferenceScreen>
|
@ -1,13 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<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
|
<Preference
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:selectable="false"
|
android:selectable="false"
|
||||||
android:summary="@string/tasker_info" />
|
android:summary="@string/tasker_info" />
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="tasker_enabled"
|
android:key="act_tasker_enabled"
|
||||||
android:summary="@string/tasker_enabled_sum"
|
android:summary="@string/tasker_enabled_sum"
|
||||||
android:title="@string/tasker_enabled" />
|
android:title="@string/tasker_enabled" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
Loading…
Reference in New Issue
Block a user