mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-13 10:26:48 +01:00
multi-device-support (#2526)
this PR aims to add device for multiple connected devices at once. A lot of stuff already works, some things need to be done: - [x] change DeviceCommunicationService to hold multiple devices and supports - [x] implement connect / disconnect logic - [x] widgets, not really suited for multiple devices, so far - [x] change the notification to show multiple devices - [ ] change GBDeviceService#onFindDevice and similar API functions to target individual devices, not all connected. - [x] move auto-reconnect setting to device settings - [x] fix music event crash - [x] work out behaviour when pressing "connect" from notification - [ ] handle service crashes - [ ] suit coordinator methods for multiple devices of same kind - [x] change ACL_CONNECTED receiver to connect to devices that are not currently registered in DeviceCommunicationService - [ ] adjust after-boot auto-connection logic - [ ] fix hanging device support. Device says disconnected, GB says connected - [x] firmware updater doesn't work My attempt to make onFindDevice work was to change the arguments to ```EventHandler#onFindDevice(GBDevice device, boolean start)```. The Problem is that this forces the device-specific implementations to also accept GBDevice as an argument. Co-authored-by: Daniel Dakhno <dakhnod@gmail.com> Co-authored-by: Andreas Shimokawa <shimokawa@fsfe.org> Co-authored-by: dakhnod <dakhnod@gmail.com> Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2526 Co-authored-by: dakhnod <dakhnod@noreply.codeberg.org> Co-committed-by: dakhnod <dakhnod@noreply.codeberg.org>
This commit is contained in:
parent
e683a5bc56
commit
4a8523f790
@ -68,6 +68,7 @@ import java.io.Serializable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -272,8 +273,11 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
|
|
||||||
if (context instanceof GBApplication) {
|
if (context instanceof GBApplication) {
|
||||||
GBApplication gbApp = (GBApplication) context;
|
GBApplication gbApp = (GBApplication) context;
|
||||||
final GBDevice device = gbApp.getDeviceManager().getSelectedDevice();
|
final List<GBDevice> devices = gbApp.getDeviceManager().getSelectedDevices();
|
||||||
if (device != null) {
|
if(devices.size() == 0){
|
||||||
|
GB.toast("Device not selected/connected", Toast.LENGTH_LONG, GB.INFO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
new DatePickerDialog(DebugActivity.this, new DatePickerDialog.OnDateSetListener() {
|
new DatePickerDialog(DebugActivity.this, new DatePickerDialog.OnDateSetListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
|
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
|
||||||
@ -283,15 +287,14 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
long timestamp = date.getTimeInMillis() - 1000;
|
long timestamp = date.getTimeInMillis() - 1000;
|
||||||
GB.toast("Setting lastSyncTimeMillis: " + timestamp, Toast.LENGTH_LONG, GB.INFO);
|
GB.toast("Setting lastSyncTimeMillis: " + timestamp, Toast.LENGTH_LONG, GB.INFO);
|
||||||
|
|
||||||
|
for(GBDevice device : devices){
|
||||||
SharedPreferences.Editor editor = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).edit();
|
SharedPreferences.Editor editor = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).edit();
|
||||||
editor.remove("lastSyncTimeMillis"); //FIXME: key reconstruction is BAD
|
editor.remove("lastSyncTimeMillis"); //FIXME: key reconstruction is BAD
|
||||||
editor.putLong("lastSyncTimeMillis", timestamp);
|
editor.putLong("lastSyncTimeMillis", timestamp);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
}, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
|
|
||||||
} else {
|
|
||||||
GB.toast("Device not selected/connected", Toast.LENGTH_LONG, GB.INFO);
|
|
||||||
}
|
}
|
||||||
|
}, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -411,8 +414,8 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
GBApplication gbApp = (GBApplication) context;
|
GBApplication gbApp = (GBApplication) context;
|
||||||
final GBDevice device = gbApp.getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = gbApp.getDeviceManager().getSelectedDevices();
|
||||||
if (device != null) {
|
for(GBDevice device : devices){
|
||||||
GBApplication.deleteDeviceSpecificSharedPrefs(device.getAddress());
|
GBApplication.deleteDeviceSpecificSharedPrefs(device.getAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,19 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
|
|||||||
} else {
|
} else {
|
||||||
setInfoText(getString(R.string.installer_activity_wait_while_determining_status));
|
setInfoText(getString(R.string.installer_activity_wait_while_determining_status));
|
||||||
|
|
||||||
|
List<GBDevice> selectedDevices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
|
if(selectedDevices.size() == 0){
|
||||||
|
GB.toast("please connect the device you want to send to", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(selectedDevices.size() != 1){
|
||||||
|
GB.toast("please connect ONLY the device you want to send to", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
device = selectedDevices.get(0);
|
||||||
|
|
||||||
// needed to get the device
|
// needed to get the device
|
||||||
if (device == null || !device.isConnected()) {
|
if (device == null || !device.isConnected()) {
|
||||||
connect();
|
connect();
|
||||||
@ -245,13 +258,16 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
|
|||||||
List<DeviceCoordinator> allCoordinators = DeviceHelper.getInstance().getAllCoordinators();
|
List<DeviceCoordinator> allCoordinators = DeviceHelper.getInstance().getAllCoordinators();
|
||||||
List<DeviceCoordinator> sortedCoordinators = new ArrayList<>(allCoordinators.size());
|
List<DeviceCoordinator> sortedCoordinators = new ArrayList<>(allCoordinators.size());
|
||||||
|
|
||||||
GBDevice connectedDevice = deviceManager.getSelectedDevice();
|
List<GBDevice> devices = deviceManager.getSelectedDevices();
|
||||||
if (connectedDevice != null && connectedDevice.isConnected()) {
|
for(GBDevice connectedDevice : devices){
|
||||||
|
if (connectedDevice.isConnected()) {
|
||||||
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(connectedDevice);
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(connectedDevice);
|
||||||
if (coordinator != null) {
|
if (coordinator != null) {
|
||||||
connectedCoordinators.add(coordinator);
|
connectedCoordinators.add(coordinator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sortedCoordinators.addAll(connectedCoordinators);
|
sortedCoordinators.addAll(connectedCoordinators);
|
||||||
for (DeviceCoordinator coordinator : allCoordinators) {
|
for (DeviceCoordinator coordinator : allCoordinators) {
|
||||||
|
@ -811,6 +811,8 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
|||||||
int[] supportedSettings = coordinator.getSupportedDeviceSpecificSettings(device);
|
int[] supportedSettings = coordinator.getSupportedDeviceSpecificSettings(device);
|
||||||
String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device);
|
String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device);
|
||||||
|
|
||||||
|
supportedSettings = ArrayUtils.insert(0, supportedSettings, coordinator.getSupportedDeviceSpecificConnectionSettings());
|
||||||
|
|
||||||
if (supportedLanguages != null) {
|
if (supportedLanguages != null) {
|
||||||
supportedSettings = ArrayUtils.insert(0, supportedSettings, R.xml.devicesettings_language_generic);
|
supportedSettings = ArrayUtils.insert(0, supportedSettings, R.xml.devicesettings_language_generic);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
|
|||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
if (device.getState() != GBDevice.State.NOT_CONNECTED) {
|
if (device.getState() != GBDevice.State.NOT_CONNECTED) {
|
||||||
showTransientSnackbar(R.string.controlcenter_snackbar_disconnecting);
|
showTransientSnackbar(R.string.controlcenter_snackbar_disconnecting);
|
||||||
GBApplication.deviceService().disconnect();
|
GBApplication.deviceService().disconnect(device);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
|
|||||||
);
|
);
|
||||||
|
|
||||||
//device specific settings
|
//device specific settings
|
||||||
holder.deviceSpecificSettingsView.setVisibility(coordinator.getSupportedDeviceSpecificSettings(device) != null ? View.VISIBLE : View.GONE);
|
holder.deviceSpecificSettingsView.setVisibility(coordinator.getSupportedDeviceSpecificConnectionSettings() != null ? View.VISIBLE : View.GONE);
|
||||||
holder.deviceSpecificSettingsView.setOnClickListener(new View.OnClickListener()
|
holder.deviceSpecificSettingsView.setOnClickListener(new View.OnClickListener()
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices;
|
||||||
|
|
||||||
|
public abstract class AbstractBLClassicDeviceCoordinator extends AbstractDeviceCoordinator {
|
||||||
|
@Override
|
||||||
|
public ConnectionType getConnectionType() {
|
||||||
|
return ConnectionType.BL_CLASSIC;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices;
|
||||||
|
|
||||||
|
public abstract class AbstractBLEDeviceCoordinator extends AbstractDeviceCoordinator{
|
||||||
|
@Override
|
||||||
|
public ConnectionType getConnectionType() {
|
||||||
|
return ConnectionType.BLE;
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ import android.bluetooth.le.ScanFilter;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ import java.util.Collections;
|
|||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
@ -61,6 +63,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
|||||||
return getSupportedType(candidate).isSupported();
|
return getSupportedType(candidate).isSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionType getConnectionType() {
|
||||||
|
return ConnectionType.BOTH;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(GBDevice device) {
|
public boolean supports(GBDevice device) {
|
||||||
return getDeviceType().equals(device.getType());
|
return getDeviceType().equals(device.getType());
|
||||||
@ -86,7 +93,7 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
|||||||
public void deleteDevice(final GBDevice gbDevice) throws GBException {
|
public void deleteDevice(final GBDevice gbDevice) throws GBException {
|
||||||
LOG.info("will try to delete device: " + gbDevice.getName());
|
LOG.info("will try to delete device: " + gbDevice.getName());
|
||||||
if (gbDevice.isConnected() || gbDevice.isConnecting()) {
|
if (gbDevice.isConnected() || gbDevice.isConnecting()) {
|
||||||
GBApplication.deviceService().disconnect();
|
GBApplication.deviceService().disconnect(gbDevice);
|
||||||
}
|
}
|
||||||
Prefs prefs = getPrefs();
|
Prefs prefs = getPrefs();
|
||||||
|
|
||||||
@ -258,9 +265,24 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getSupportedDeviceSpecificConnectionSettings() {
|
||||||
|
int[] settings = new int[0];
|
||||||
|
ConnectionType connectionType = getConnectionType();
|
||||||
|
|
||||||
|
if(connectionType.usesBluetoothLE()){
|
||||||
|
settings = ArrayUtils.insert(0, settings, R.xml.devicesettings_reconnect_ble);
|
||||||
|
}
|
||||||
|
if(connectionType.usesBluetoothClassic()){
|
||||||
|
settings = ArrayUtils.insert(0, settings, R.xml.devicesettings_reconnect_bl_classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||||
return null;
|
return new int[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,6 +77,27 @@ public interface DeviceCoordinator {
|
|||||||
*/
|
*/
|
||||||
int BONDING_STYLE_LAZY = 4;
|
int BONDING_STYLE_LAZY = 4;
|
||||||
|
|
||||||
|
enum ConnectionType{
|
||||||
|
BLE(false, true),
|
||||||
|
BL_CLASSIC(true, false),
|
||||||
|
BOTH(true, true)
|
||||||
|
;
|
||||||
|
boolean usesBluetoothClassic, usesBluetoothLE;
|
||||||
|
|
||||||
|
ConnectionType(boolean usesBluetoothClassic, boolean usesBluetoothLE) {
|
||||||
|
this.usesBluetoothClassic = usesBluetoothClassic;
|
||||||
|
this.usesBluetoothLE = usesBluetoothLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usesBluetoothLE(){
|
||||||
|
return usesBluetoothLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usesBluetoothClassic(){
|
||||||
|
return usesBluetoothClassic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this coordinator handles the given candidate.
|
* Checks whether this coordinator handles the given candidate.
|
||||||
* Returns the supported device type for the given candidate or
|
* Returns the supported device type for the given candidate or
|
||||||
@ -88,6 +109,13 @@ public interface DeviceCoordinator {
|
|||||||
@NonNull
|
@NonNull
|
||||||
DeviceType getSupportedType(GBDeviceCandidate candidate);
|
DeviceType getSupportedType(GBDeviceCandidate candidate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of connection, Classic of BLE
|
||||||
|
*
|
||||||
|
* @return ConnectionType
|
||||||
|
*/
|
||||||
|
ConnectionType getConnectionType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this coordinator handles the given candidate.
|
* Checks whether this coordinator handles the given candidate.
|
||||||
*
|
*
|
||||||
@ -363,6 +391,13 @@ public interface DeviceCoordinator {
|
|||||||
*/
|
*/
|
||||||
boolean supportsUnicodeEmojis();
|
boolean supportsUnicodeEmojis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns device specific settings related to connection
|
||||||
|
*
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
int[] getSupportedDeviceSpecificConnectionSettings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates which device specific settings the device supports (not per device type or family, but unique per device).
|
* Indicates which device specific settings the device supports (not per device type or family, but unique per device).
|
||||||
*/
|
*/
|
||||||
|
@ -67,7 +67,7 @@ public class DeviceManager {
|
|||||||
* This allows direct access to the list from ListAdapters.
|
* This allows direct access to the list from ListAdapters.
|
||||||
*/
|
*/
|
||||||
private final List<GBDevice> deviceList = new ArrayList<>();
|
private final List<GBDevice> deviceList = new ArrayList<>();
|
||||||
private GBDevice selectedDevice = null;
|
private List<GBDevice> selectedDevices = new ArrayList<>();
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
@ -137,22 +137,13 @@ public class DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateSelectedDevice(GBDevice dev) {
|
private void updateSelectedDevice(GBDevice dev) {
|
||||||
if (selectedDevice == null) {
|
selectedDevices.clear();
|
||||||
selectedDevice = dev;
|
for(GBDevice device : deviceList){
|
||||||
} else {
|
if(device.isInitialized()){
|
||||||
if (selectedDevice.equals(dev)) {
|
selectedDevices.add(device);
|
||||||
selectedDevice = dev; // equality vs identity!
|
|
||||||
} else {
|
|
||||||
if (selectedDevice.isConnected() && dev.isConnected()) {
|
|
||||||
LOG.warn("multiple connected devices -- this is currently not really supported");
|
|
||||||
selectedDevice = dev; // use the last one that changed
|
|
||||||
} else if (!selectedDevice.isConnected()) {
|
|
||||||
selectedDevice = dev; // use the last one that changed
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
GB.updateNotification(selectedDevices, context);
|
||||||
GB.updateNotification(selectedDevice, context);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshPairedDevices() {
|
private void refreshPairedDevices() {
|
||||||
@ -184,9 +175,8 @@ public class DeviceManager {
|
|||||||
return Collections.unmodifiableList(deviceList);
|
return Collections.unmodifiableList(deviceList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public List<GBDevice> getSelectedDevices() {
|
||||||
public GBDevice getSelectedDevice() {
|
return selectedDevices;
|
||||||
return selectedDevice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyDevicesChanged() {
|
private void notifyDevicesChanged() {
|
||||||
|
@ -25,6 +25,7 @@ import androidx.annotation.NonNull;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
@ -168,18 +169,27 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsAppListFetching() {
|
public boolean supportsAppListFetching() {
|
||||||
GBDevice mGBDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (mGBDevice != null && mGBDevice.getFirmwareVersion() != null) {
|
for(GBDevice device : devices){
|
||||||
return PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) < 3;
|
if(device.getType() == DeviceType.PEBBLE){
|
||||||
|
if (device.getFirmwareVersion() != null) {
|
||||||
|
return PebbleUtils.getFwMajor(device.getFirmwareVersion()) < 3;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsAppReordering() {
|
public boolean supportsAppReordering() {
|
||||||
GBDevice mGBDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (mGBDevice != null && mGBDevice.getFirmwareVersion() != null) {
|
for(GBDevice device : devices){
|
||||||
return PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) >= 3;
|
if(device.getType() == DeviceType.PEBBLE){
|
||||||
|
if (device.getFirmwareVersion() != null) {
|
||||||
|
return PebbleUtils.getFwMajor(device.getFirmwareVersion()) >= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
@ -35,7 +35,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class QC35Coordinator extends AbstractDeviceCoordinator {
|
public class QC35Coordinator extends AbstractBLClassicDeviceCoordinator {
|
||||||
@Override
|
@Override
|
||||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||||
|
|
||||||
|
@ -54,13 +54,18 @@ public class AppsManagementActivity extends AbstractGBActivity {
|
|||||||
|
|
||||||
private void refreshInstalledApps() {
|
private void refreshInstalledApps() {
|
||||||
try {
|
try {
|
||||||
GBDevice selected = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (selected.getType() != DeviceType.FOSSILQHYBRID || !selected.isConnected() || !selected.getModel().startsWith("DN") || selected.getState() != GBDevice.State.INITIALIZED) {
|
boolean deviceFound = false;
|
||||||
throw new RuntimeException("Device not connected");
|
for(GBDevice device : devices){
|
||||||
}
|
if (
|
||||||
String installedAppsJson = selected.getDeviceInfo("INSTALLED_APPS").getDetails();
|
device.getType() == DeviceType.FOSSILQHYBRID &&
|
||||||
|
device.isConnected() &&
|
||||||
|
device.getModel().startsWith("DN") &&
|
||||||
|
device.getState() == GBDevice.State.INITIALIZED
|
||||||
|
) {
|
||||||
|
String installedAppsJson = device.getDeviceInfo("INSTALLED_APPS").getDetails();
|
||||||
if (installedAppsJson == null || installedAppsJson.isEmpty()) {
|
if (installedAppsJson == null || installedAppsJson.isEmpty()) {
|
||||||
throw new RuntimeException("cant get installed apps");
|
throw new RuntimeException("can't get installed apps");
|
||||||
}
|
}
|
||||||
JSONArray apps = new JSONArray(installedAppsJson);
|
JSONArray apps = new JSONArray(installedAppsJson);
|
||||||
appNames = new String[apps.length()];
|
appNames = new String[apps.length()];
|
||||||
@ -68,11 +73,15 @@ public class AppsManagementActivity extends AbstractGBActivity {
|
|||||||
appNames[i] = apps.getString(i);
|
appNames[i] = apps.getString(i);
|
||||||
}
|
}
|
||||||
appsListView.setAdapter(new AppsListAdapter(this, appNames));
|
appsListView.setAdapter(new AppsListAdapter(this, appNames));
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
toast(e.getMessage());
|
toast(e.getMessage());
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
throw new RuntimeException("Device not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppsListAdapter extends ArrayAdapter<String> {
|
class AppsListAdapter extends ArrayAdapter<String> {
|
||||||
|
@ -29,6 +29,8 @@ import android.widget.Toast;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
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.AbstractGBActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
|
||||||
@ -85,9 +87,16 @@ public class CalibrationActivity extends AbstractGBActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_qhybrid_calibration);
|
setContentView(R.layout.activity_qhybrid_calibration);
|
||||||
|
|
||||||
GBDevice device = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
|
boolean atLeastOneConnected = false;
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(device.getType() == DeviceType.FOSSILQHYBRID){
|
||||||
|
atLeastOneConnected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(device == null || device.getType() != DeviceType.FOSSILQHYBRID){
|
if(!atLeastOneConnected){
|
||||||
Toast.makeText(this, R.string.watch_not_connected, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.watch_not_connected, Toast.LENGTH_LONG).show();
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
|
@ -303,13 +303,15 @@ public class ConfigActivity extends AbstractGBActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
device = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (device == null || device.getType() != DeviceType.FOSSILQHYBRID || device.getFirmwareVersion().charAt(2) != '0') {
|
for(GBDevice device : devices){
|
||||||
setSettingsError(getString(R.string.watch_not_connected));
|
if (device.getType() == DeviceType.FOSSILQHYBRID && device.getFirmwareVersion().charAt(2) == '0') {
|
||||||
} else {
|
|
||||||
updateSettings();
|
updateSettings();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setSettingsError(getString(R.string.watch_not_connected));
|
||||||
|
}
|
||||||
|
|
||||||
private void updateTimeOffset() {
|
private void updateTimeOffset() {
|
||||||
int timeOffset = prefs.getInt("QHYBRID_TIME_OFFSET", 0);
|
int timeOffset = prefs.getInt("QHYBRID_TIME_OFFSET", 0);
|
||||||
|
@ -46,6 +46,8 @@ 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.AbstractGBActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement;
|
||||||
@ -168,7 +170,10 @@ public class HRConfigActivity extends AbstractGBActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable some functions on watches with too new firmware (from official app 4.6.0 and higher)
|
// Disable some functions on watches with too new firmware (from official app 4.6.0 and higher)
|
||||||
String fwVersion_str = GBApplication.app().getDeviceManager().getSelectedDevice().getFirmwareVersion();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(device.getType() == DeviceType.FOSSILQHYBRID){
|
||||||
|
String fwVersion_str = device.getFirmwareVersion();
|
||||||
fwVersion_str = fwVersion_str.replaceFirst("^DN", "").replaceFirst("r\\.v.*", "");
|
fwVersion_str = fwVersion_str.replaceFirst("^DN", "").replaceFirst("r\\.v.*", "");
|
||||||
Version fwVersion = new Version(fwVersion_str);
|
Version fwVersion = new Version(fwVersion_str);
|
||||||
if (fwVersion.compareTo(new Version("1.0.2.20")) >= 0) {
|
if (fwVersion.compareTo(new Version("1.0.2.20")) >= 0) {
|
||||||
@ -182,6 +187,9 @@ public class HRConfigActivity extends AbstractGBActivity {
|
|||||||
GB.toast(getString(R.string.fossil_hr_warning_firmware_too_new), Toast.LENGTH_LONG, GB.INFO);
|
GB.toast(getString(R.string.fossil_hr_warning_firmware_too_new), Toast.LENGTH_LONG, GB.INFO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
|
@ -35,6 +35,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
@ -54,7 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Version;
|
import nodomain.freeyourgadget.gadgetbridge.util.Version;
|
||||||
|
|
||||||
public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
public class QHybridCoordinator extends AbstractBLEDeviceCoordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(QHybridCoordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(QHybridCoordinator.class);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -89,8 +91,13 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsActivityDataFetching() {
|
public boolean supportsActivityDataFetching() {
|
||||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
return connectedDevice != null && connectedDevice.getType() == DeviceType.FOSSILQHYBRID && connectedDevice.getState() == GBDevice.State.INITIALIZED;
|
for(GBDevice device : devices){
|
||||||
|
if(isFossilHybrid(device) && device.getState() == GBDevice.State.INITIALIZED){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -129,12 +136,15 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean supportsAlarmConfiguration() {
|
private boolean supportsAlarmConfiguration() {
|
||||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){
|
LOG.debug("devices count: " + devices.size());
|
||||||
return false;
|
for(GBDevice device : devices){
|
||||||
}
|
if(isFossilHybrid(device) && device.getState() == GBDevice.State.INITIALIZED){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAlarmSlotCount() {
|
public int getAlarmSlotCount() {
|
||||||
@ -268,15 +278,20 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHybridHR() {
|
private boolean isHybridHR() {
|
||||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (connectedDevice != null) {
|
for(GBDevice device : devices){
|
||||||
return connectedDevice.getName().startsWith("Hybrid HR");
|
if(isFossilHybrid(device) && device.getName().startsWith("Hybrid HR")){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Version getFirmwareVersion() {
|
private Version getFirmwareVersion() {
|
||||||
String firmware = GBApplication.app().getDeviceManager().getSelectedDevice().getFirmwareVersion();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(isFossilHybrid(device)){
|
||||||
|
String firmware = device.getFirmwareVersion();
|
||||||
if (firmware != null) {
|
if (firmware != null) {
|
||||||
Matcher matcher = Pattern.compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").matcher(firmware); // DN1.0.2.19r.v5
|
Matcher matcher = Pattern.compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").matcher(firmware); // DN1.0.2.19r.v5
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
@ -284,6 +299,13 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
|||||||
return new Version(firmware);
|
return new Version(firmware);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isFossilHybrid(GBDevice device){
|
||||||
|
return device.getType() == DeviceType.FOSSILQHYBRID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import java.util.Collections;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
@ -26,7 +27,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.um25.Support.UM25Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.um25.Support.UM25Support;
|
||||||
|
|
||||||
public class UM25Coordinator extends AbstractDeviceCoordinator {
|
public class UM25Coordinator extends AbstractBLEDeviceCoordinator {
|
||||||
@Override
|
@Override
|
||||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
@ -36,7 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class VescCoordinator extends AbstractDeviceCoordinator {
|
public class VescCoordinator extends AbstractBLEDeviceCoordinator {
|
||||||
public final static String UUID_SERVICE_SERIAL_HM10 = "0000ffe0-0000-1000-8000-00805f9b34fb";
|
public final static String UUID_SERVICE_SERIAL_HM10 = "0000ffe0-0000-1000-8000-00805f9b34fb";
|
||||||
public final static String UUID_CHARACTERISTIC_SERIAL_TX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb";
|
public final static String UUID_CHARACTERISTIC_SERIAL_TX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb";
|
||||||
public final static String UUID_CHARACTERISTIC_SERIAL_RX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb";
|
public final static String UUID_CHARACTERISTIC_SERIAL_RX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb";
|
||||||
|
@ -20,13 +20,17 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||||
|
|
||||||
public class BluetoothConnectReceiver extends BroadcastReceiver {
|
public class BluetoothConnectReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@ -46,14 +50,30 @@ public class BluetoothConnectReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||||
LOG.info("connection attempt detected from or to " + device.getAddress() + "(" + device.getName() + ")");
|
LOG.info("connection attempt detected from " + device.getAddress() + "(" + device.getName() + ")");
|
||||||
|
|
||||||
GBDevice gbDevice = service.getGBDevice();
|
GBDevice gbDevice = getKnownDeviceByAddressOrNull(device.getAddress());
|
||||||
if (gbDevice != null) {
|
if(gbDevice == null){
|
||||||
if (device.getAddress().equals(gbDevice.getAddress()) && gbDevice.getState() == GBDevice.State.WAITING_FOR_RECONNECT) {
|
LOG.info("connected device {} unknown", device.getAddress());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SharedPreferences deviceSpecificPreferences = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress());
|
||||||
|
boolean reactToConnection = deviceSpecificPreferences.getBoolean(GBPrefs.DEVICE_CONNECT_BACK, false);
|
||||||
|
reactToConnection |= gbDevice.getState() == GBDevice.State.WAITING_FOR_RECONNECT;
|
||||||
|
if(!reactToConnection){
|
||||||
|
return;
|
||||||
|
}
|
||||||
LOG.info("Will re-connect to " + gbDevice.getAddress() + "(" + gbDevice.getName() + ")");
|
LOG.info("Will re-connect to " + gbDevice.getAddress() + "(" + gbDevice.getName() + ")");
|
||||||
GBApplication.deviceService().connect();
|
GBApplication.deviceService().connect(gbDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GBDevice getKnownDeviceByAddressOrNull(String deviceAddress){
|
||||||
|
List<GBDevice> knownDevices = GBApplication.app().getDeviceManager().getDevices();
|
||||||
|
for(GBDevice device : knownDevices){
|
||||||
|
if(device.getAddress().equals(deviceAddress)){
|
||||||
|
return device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,15 @@ public class BluetoothPairingRequestReceiver extends BroadcastReceiver {
|
|||||||
if (!action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
|
if (!action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GBDevice gbDevice = service.getGBDevice();
|
|
||||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||||
if (gbDevice == null || device == null) {
|
if (device == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GBDevice gbDevice = null;
|
||||||
|
try {
|
||||||
|
gbDevice = service.getDeviceByAddress(device.getAddress());
|
||||||
|
|
||||||
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
||||||
try {
|
try {
|
||||||
if (coordinator.getBondingStyle() == DeviceCoordinator.BONDING_STYLE_NONE) {
|
if (coordinator.getBondingStyle() == DeviceCoordinator.BONDING_STYLE_NONE) {
|
||||||
@ -63,5 +65,8 @@ public class BluetoothPairingRequestReceiver extends BroadcastReceiver {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("Could not abort pairing request process");
|
LOG.warn("Could not abort pairing request process");
|
||||||
}
|
}
|
||||||
|
} catch (DeviceCommunicationService.DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -767,9 +767,9 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
notificationsActive.removeAll(notificationsToRemove);
|
notificationsActive.removeAll(notificationsToRemove);
|
||||||
|
|
||||||
// Send notification remove request to device
|
// Send notification remove request to device
|
||||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (connectedDevice != null) {
|
for(GBDevice device : devices){
|
||||||
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(connectedDevice.getAddress()));
|
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
|
||||||
if (prefs.getBoolean("autoremove_notifications", true)) {
|
if (prefs.getBoolean("autoremove_notifications", true)) {
|
||||||
for (int id : notificationsToRemove) {
|
for (int id : notificationsToRemove) {
|
||||||
LOG.info("Notification " + id + " removed, will ask device to delete it");
|
LOG.info("Notification " + id + " removed, will ask device to delete it");
|
||||||
|
@ -118,6 +118,13 @@ public class GBDeviceService implements DeviceService {
|
|||||||
invokeService(intent);
|
invokeService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect(@Nullable GBDevice device) {
|
||||||
|
Intent intent = createIntent().setAction(ACTION_DISCONNECT)
|
||||||
|
.putExtra(GBDevice.EXTRA_DEVICE, device);
|
||||||
|
invokeService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
Intent intent = createIntent().setAction(ACTION_DISCONNECT);
|
Intent intent = createIntent().setAction(ACTION_DISCONNECT);
|
||||||
|
@ -154,6 +154,8 @@ public interface DeviceService extends EventHandler {
|
|||||||
|
|
||||||
void connect(@Nullable GBDevice device, boolean firstTime);
|
void connect(@Nullable GBDevice device, boolean firstTime);
|
||||||
|
|
||||||
|
void disconnect(@Nullable GBDevice device);
|
||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
void quit();
|
void quit();
|
||||||
|
@ -44,9 +44,11 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
|
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
@ -189,6 +191,108 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WEA
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WORLD_CLOCKS;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WORLD_CLOCKS;
|
||||||
|
|
||||||
public class DeviceCommunicationService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class DeviceCommunicationService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
public static class DeviceStruct{
|
||||||
|
private GBDevice device;
|
||||||
|
private DeviceCoordinator coordinator;
|
||||||
|
private DeviceSupport deviceSupport;
|
||||||
|
|
||||||
|
public GBDevice getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevice(GBDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceCoordinator getCoordinator() {
|
||||||
|
return coordinator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCoordinator(DeviceCoordinator coordinator) {
|
||||||
|
this.coordinator = coordinator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceSupport getDeviceSupport() {
|
||||||
|
return deviceSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceSupport(DeviceSupport deviceSupport) {
|
||||||
|
this.deviceSupport = deviceSupport;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FeatureSet{
|
||||||
|
private boolean supportsWeather = false;
|
||||||
|
private boolean supportsActivityDataFetching = false;
|
||||||
|
private boolean supportsCalendarEvents = false;
|
||||||
|
private boolean supportsMusicInfo = false;
|
||||||
|
|
||||||
|
public boolean supportsWeather() {
|
||||||
|
return supportsWeather;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupportsWeather(boolean supportsWeather) {
|
||||||
|
this.supportsWeather = supportsWeather;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsActivityDataFetching() {
|
||||||
|
return supportsActivityDataFetching;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupportsActivityDataFetching(boolean supportsActivityDataFetching) {
|
||||||
|
this.supportsActivityDataFetching = supportsActivityDataFetching;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCalendarEvents() {
|
||||||
|
return supportsCalendarEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupportsCalendarEvents(boolean supportsCalendarEvents) {
|
||||||
|
this.supportsCalendarEvents = supportsCalendarEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMusicInfo() {
|
||||||
|
return supportsMusicInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupportsMusicInfo(boolean supportsMusicInfo) {
|
||||||
|
this.supportsMusicInfo = supportsMusicInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logicalOr(DeviceCoordinator operand){
|
||||||
|
if(operand.supportsCalendarEvents()){
|
||||||
|
setSupportsCalendarEvents(true);
|
||||||
|
}
|
||||||
|
if(operand.supportsWeather()){
|
||||||
|
setSupportsWeather(true);
|
||||||
|
}
|
||||||
|
if(operand.supportsActivityDataFetching()){
|
||||||
|
setSupportsActivityDataFetching(true);
|
||||||
|
}
|
||||||
|
if(operand.supportsMusicInfo()){
|
||||||
|
setSupportsMusicInfo(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DeviceNotFoundException extends GBException{
|
||||||
|
private final String address;
|
||||||
|
|
||||||
|
public DeviceNotFoundException(GBDevice device) {
|
||||||
|
this.address = device.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceNotFoundException(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return String.format("device %s not found cached", address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
|
||||||
@SuppressLint("StaticFieldLeak") // only used for test cases
|
@SuppressLint("StaticFieldLeak") // only used for test cases
|
||||||
private static DeviceSupportFactory DEVICE_SUPPORT_FACTORY = null;
|
private static DeviceSupportFactory DEVICE_SUPPORT_FACTORY = null;
|
||||||
@ -196,9 +300,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
private boolean mStarted = false;
|
private boolean mStarted = false;
|
||||||
|
|
||||||
private DeviceSupportFactory mFactory;
|
private DeviceSupportFactory mFactory;
|
||||||
private GBDevice mGBDevice = null;
|
private final ArrayList<DeviceStruct> deviceStructs = new ArrayList<>(1);
|
||||||
private DeviceSupport mDeviceSupport;
|
|
||||||
private DeviceCoordinator mCoordinator = null;
|
|
||||||
|
|
||||||
private PhoneCallReceiver mPhoneCallReceiver = null;
|
private PhoneCallReceiver mPhoneCallReceiver = null;
|
||||||
private SMSReceiver mSMSReceiver = null;
|
private SMSReceiver mSMSReceiver = null;
|
||||||
@ -236,6 +338,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
*
|
*
|
||||||
* @param factory
|
* @param factory
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("JavaDoc")
|
||||||
public static void setDeviceSupportFactory(DeviceSupportFactory factory) {
|
public static void setDeviceSupportFactory(DeviceSupportFactory factory) {
|
||||||
DEVICE_SUPPORT_FACTORY = factory;
|
DEVICE_SUPPORT_FACTORY = factory;
|
||||||
}
|
}
|
||||||
@ -250,18 +353,43 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if(GBDevice.ACTION_DEVICE_CHANGED.equals(action)){
|
if(GBDevice.ACTION_DEVICE_CHANGED.equals(action)){
|
||||||
GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||||
if (mGBDevice != null && mGBDevice.equals(device)) {
|
|
||||||
mGBDevice = device;
|
// create a new instance of the changed devices coordinator, in case it's capabilities changed
|
||||||
mCoordinator = DeviceHelper.getInstance().getCoordinator(device);
|
DeviceStruct cachedStruct = getDeviceStructOrNull(device);
|
||||||
boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized());
|
if(cachedStruct != null) {
|
||||||
setReceiversEnableState(enableReceivers, mGBDevice.isInitialized(), mCoordinator);
|
cachedStruct.setDevice(device);
|
||||||
} else {
|
DeviceCoordinator newCoordinator = DeviceHelper.getInstance().getCoordinator(device);
|
||||||
LOG.error("Got ACTION_DEVICE_CHANGED from unexpected device: " + device);
|
cachedStruct.setCoordinator(newCoordinator);
|
||||||
}
|
}
|
||||||
|
updateReceiversState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void updateReceiversState(){
|
||||||
|
boolean enableReceivers = false;
|
||||||
|
boolean anyDeviceInitialized = false;
|
||||||
|
|
||||||
|
FeatureSet features = new FeatureSet();
|
||||||
|
|
||||||
|
for(DeviceStruct struct: deviceStructs){
|
||||||
|
DeviceSupport deviceSupport = struct.getDeviceSupport();
|
||||||
|
if((deviceSupport != null && deviceSupport.useAutoConnect()) || isDeviceInitialized(struct.getDevice())){
|
||||||
|
enableReceivers = true;
|
||||||
|
}
|
||||||
|
if(isDeviceInitialized(struct.getDevice())){
|
||||||
|
anyDeviceInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceCoordinator coordinator = struct.getCoordinator();
|
||||||
|
if(coordinator != null){
|
||||||
|
features.logicalOr(coordinator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setReceiversEnableState(enableReceivers, anyDeviceInitialized, features);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
LOG.debug("DeviceCommunicationService is being created");
|
LOG.debug("DeviceCommunicationService is being created");
|
||||||
@ -269,6 +397,9 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED));
|
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED));
|
||||||
mFactory = getDeviceSupportFactory();
|
mFactory = getDeviceSupportFactory();
|
||||||
|
|
||||||
|
mBlueToothConnectReceiver = new BluetoothConnectReceiver(this);
|
||||||
|
registerReceiver(mBlueToothConnectReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
|
||||||
|
|
||||||
if (hasPrefs()) {
|
if (hasPrefs()) {
|
||||||
getPrefs().getPreferences().registerOnSharedPreferenceChangeListener(this);
|
getPrefs().getPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
@ -306,14 +437,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDeviceSupport == null || (!isInitialized() && !action.equals(ACTION_DISCONNECT) && (!mDeviceSupport.useAutoConnect() || isConnected()))) {
|
// TODO
|
||||||
|
/*if (mDeviceSupport == null || (!isInitialized() && !action.equals(ACTION_DISCONNECT) && (!mDeviceSupport.useAutoConnect() || isConnected()))) {
|
||||||
// trying to send notification without valid Bluetooth connection
|
// trying to send notification without valid Bluetooth connection
|
||||||
if (mGBDevice != null) {
|
if (mGBDevice != null) {
|
||||||
// at least send back the current device state
|
// at least send back the current device state
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
mGBDevice.sendDeviceUpdateIntent(this);
|
||||||
}
|
}
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// when we get past this, we should have valid mDeviceSupport and mGBDevice instances
|
// when we get past this, we should have valid mDeviceSupport and mGBDevice instances
|
||||||
@ -338,18 +470,38 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
btDeviceAddress = gbDevice.getAddress();
|
btDeviceAddress = gbDevice.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(gbDevice == null){
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
boolean autoReconnect = GBPrefs.AUTO_RECONNECT_DEFAULT;
|
boolean autoReconnect = GBPrefs.AUTO_RECONNECT_DEFAULT;
|
||||||
if (prefs != null && prefs.getPreferences() != null) {
|
if (prefs != null && prefs.getPreferences() != null) {
|
||||||
prefs.getPreferences().edit().putString("last_device_address", btDeviceAddress).apply();
|
prefs.getPreferences().edit().putString("last_device_address", btDeviceAddress).apply();
|
||||||
autoReconnect = getGBPrefs().getAutoReconnect();
|
autoReconnect = getGBPrefs().getAutoReconnect(gbDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceStruct registeredStruct = getDeviceStructOrNull(gbDevice);
|
||||||
|
if(registeredStruct != null){
|
||||||
|
boolean deviceAlreadyConnected = isDeviceConnecting(registeredStruct.getDevice()) || isDeviceConnected(registeredStruct.getDevice());
|
||||||
|
if(deviceAlreadyConnected){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
removeDeviceSupport(gbDevice);
|
||||||
|
} catch (DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
registeredStruct = new DeviceStruct();
|
||||||
|
registeredStruct.setDevice(gbDevice);
|
||||||
|
registeredStruct.setCoordinator(DeviceHelper.getInstance().getCoordinator(gbDevice));
|
||||||
|
deviceStructs.add(registeredStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gbDevice != null && !isConnecting() && !isConnected()) {
|
|
||||||
setDeviceSupport(null);
|
|
||||||
try {
|
try {
|
||||||
DeviceSupport deviceSupport = mFactory.createDeviceSupport(gbDevice);
|
DeviceSupport deviceSupport = mFactory.createDeviceSupport(gbDevice);
|
||||||
if (deviceSupport != null) {
|
if (deviceSupport != null) {
|
||||||
setDeviceSupport(deviceSupport);
|
setDeviceSupport(gbDevice, deviceSupport);
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
deviceSupport.connectFirstTime();
|
deviceSupport.connectFirstTime();
|
||||||
} else {
|
} else {
|
||||||
@ -361,18 +513,30 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR, e);
|
GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||||
setDeviceSupport(null);
|
|
||||||
}
|
}
|
||||||
} else if (mGBDevice != null) {
|
|
||||||
// send an update at least
|
for(DeviceStruct struct2 : deviceStructs){
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
struct2.getDevice().sendDeviceUpdateIntent(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (mDeviceSupport == null || mGBDevice == null) {
|
GBDevice targetedDevice = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||||
LOG.warn("device support:" + mDeviceSupport + ", device: " + mGBDevice + ", aborting");
|
ArrayList<GBDevice> targetedDevices = new ArrayList<>();
|
||||||
|
if(targetedDevice != null){
|
||||||
|
targetedDevices.add(targetedDevice);
|
||||||
}else{
|
}else{
|
||||||
handleAction(intent, action, prefs);
|
for(GBDevice device : getGBDevices()){
|
||||||
|
if(isDeviceInitialized(device)){
|
||||||
|
targetedDevices.add(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (GBDevice device1 : targetedDevices) {
|
||||||
|
try {
|
||||||
|
handleAction(intent, action, device1);
|
||||||
|
} catch (DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -383,21 +547,35 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
* @param text original text
|
* @param text original text
|
||||||
* @return 'text' or a new String without non supported chars like emoticons, etc.
|
* @return 'text' or a new String without non supported chars like emoticons, etc.
|
||||||
*/
|
*/
|
||||||
private String sanitizeNotifText(String text) {
|
private String sanitizeNotifText(String text, GBDevice device) throws DeviceNotFoundException {
|
||||||
if (text == null || text.length() == 0)
|
if (text == null || text.length() == 0)
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
text = mDeviceSupport.customStringFilter(text);
|
text = getDeviceSupport(device).customStringFilter(text);
|
||||||
|
|
||||||
if (!mCoordinator.supportsUnicodeEmojis()) {
|
if (!getDeviceCoordinator(device).supportsUnicodeEmojis()) {
|
||||||
return EmojiConverter.convertUnicodeEmojiToAscii(text, getApplicationContext());
|
return EmojiConverter.convertUnicodeEmojiToAscii(text, getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAction(Intent intent, String action, Prefs prefs) {
|
private DeviceCoordinator getDeviceCoordinator(GBDevice device) throws DeviceNotFoundException {
|
||||||
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(mGBDevice.getAddress()));
|
if(device == null){
|
||||||
|
throw new DeviceNotFoundException("null");
|
||||||
|
}
|
||||||
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device)){
|
||||||
|
return struct.getCoordinator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new DeviceNotFoundException(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleAction(Intent intent, String action, GBDevice device) throws DeviceNotFoundException {
|
||||||
|
DeviceSupport deviceSupport = getDeviceSupport(device);
|
||||||
|
|
||||||
|
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
|
||||||
boolean transliterate = devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false);
|
boolean transliterate = devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false);
|
||||||
|
|
||||||
if (transliterate) {
|
if (transliterate) {
|
||||||
@ -410,16 +588,16 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_REQUEST_DEVICEINFO:
|
case ACTION_REQUEST_DEVICEINFO:
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
device.sendDeviceUpdateIntent(this);
|
||||||
break;
|
break;
|
||||||
case ACTION_NOTIFICATION: {
|
case ACTION_NOTIFICATION: {
|
||||||
int desiredId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
|
int desiredId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
|
||||||
NotificationSpec notificationSpec = new NotificationSpec(desiredId);
|
NotificationSpec notificationSpec = new NotificationSpec(desiredId);
|
||||||
notificationSpec.phoneNumber = intent.getStringExtra(EXTRA_NOTIFICATION_PHONENUMBER);
|
notificationSpec.phoneNumber = intent.getStringExtra(EXTRA_NOTIFICATION_PHONENUMBER);
|
||||||
notificationSpec.sender = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SENDER));
|
notificationSpec.sender = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SENDER), device);
|
||||||
notificationSpec.subject = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT));
|
notificationSpec.subject = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT), device);
|
||||||
notificationSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_TITLE));
|
notificationSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_TITLE), device);
|
||||||
notificationSpec.body = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_BODY));
|
notificationSpec.body = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_BODY), device);
|
||||||
notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME);
|
notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME);
|
||||||
notificationSpec.type = (NotificationType) intent.getSerializableExtra(EXTRA_NOTIFICATION_TYPE);
|
notificationSpec.type = (NotificationType) intent.getSerializableExtra(EXTRA_NOTIFICATION_TYPE);
|
||||||
notificationSpec.attachedActions = (ArrayList<NotificationSpec.Action>) intent.getSerializableExtra(EXTRA_NOTIFICATION_ACTIONS);
|
notificationSpec.attachedActions = (ArrayList<NotificationSpec.Action>) intent.getSerializableExtra(EXTRA_NOTIFICATION_ACTIONS);
|
||||||
@ -449,11 +627,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
notificationSpec.cannedReplies = replies.toArray(new String[0]);
|
notificationSpec.cannedReplies = replies.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mDeviceSupport.onNotification(notificationSpec);
|
deviceSupport.onNotification(notificationSpec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DELETE_NOTIFICATION: {
|
case ACTION_DELETE_NOTIFICATION: {
|
||||||
mDeviceSupport.onDeleteNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1));
|
deviceSupport.onDeleteNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_ADD_CALENDAREVENT: {
|
case ACTION_ADD_CALENDAREVENT: {
|
||||||
@ -462,61 +640,62 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
calendarEventSpec.type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
|
calendarEventSpec.type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
|
||||||
calendarEventSpec.timestamp = intent.getIntExtra(EXTRA_CALENDAREVENT_TIMESTAMP, -1);
|
calendarEventSpec.timestamp = intent.getIntExtra(EXTRA_CALENDAREVENT_TIMESTAMP, -1);
|
||||||
calendarEventSpec.durationInSeconds = intent.getIntExtra(EXTRA_CALENDAREVENT_DURATION, -1);
|
calendarEventSpec.durationInSeconds = intent.getIntExtra(EXTRA_CALENDAREVENT_DURATION, -1);
|
||||||
calendarEventSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_TITLE));
|
calendarEventSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_TITLE), device);
|
||||||
calendarEventSpec.description = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_DESCRIPTION));
|
calendarEventSpec.description = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_DESCRIPTION), device);
|
||||||
calendarEventSpec.location = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_LOCATION));
|
calendarEventSpec.location = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_LOCATION), device);
|
||||||
mDeviceSupport.onAddCalendarEvent(calendarEventSpec);
|
deviceSupport.onAddCalendarEvent(calendarEventSpec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DELETE_CALENDAREVENT: {
|
case ACTION_DELETE_CALENDAREVENT: {
|
||||||
long id = intent.getLongExtra(EXTRA_CALENDAREVENT_ID, -1);
|
long id = intent.getLongExtra(EXTRA_CALENDAREVENT_ID, -1);
|
||||||
byte type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
|
byte type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
|
||||||
mDeviceSupport.onDeleteCalendarEvent(type, id);
|
deviceSupport.onDeleteCalendarEvent(type, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_RESET: {
|
case ACTION_RESET: {
|
||||||
int flags = intent.getIntExtra(EXTRA_RESET_FLAGS, 0);
|
int flags = intent.getIntExtra(EXTRA_RESET_FLAGS, 0);
|
||||||
mDeviceSupport.onReset(flags);
|
deviceSupport.onReset(flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_HEARTRATE_TEST: {
|
case ACTION_HEARTRATE_TEST: {
|
||||||
mDeviceSupport.onHeartRateTest();
|
deviceSupport.onHeartRateTest();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_FETCH_RECORDED_DATA: {
|
case ACTION_FETCH_RECORDED_DATA: {
|
||||||
|
if(!getDeviceCoordinator(device).supportsActivityDataFetching()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
int dataTypes = intent.getIntExtra(EXTRA_RECORDED_DATA_TYPES, 0);
|
int dataTypes = intent.getIntExtra(EXTRA_RECORDED_DATA_TYPES, 0);
|
||||||
mDeviceSupport.onFetchRecordedData(dataTypes);
|
deviceSupport.onFetchRecordedData(dataTypes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DISCONNECT: {
|
case ACTION_DISCONNECT:
|
||||||
mDeviceSupport.dispose();
|
try {
|
||||||
if (mGBDevice != null) {
|
removeDeviceSupport(device);
|
||||||
mGBDevice.setState(GBDevice.State.NOT_CONNECTED);
|
} catch (DeviceNotFoundException e) {
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
setReceiversEnableState(false, false, null);
|
device.setState(GBDevice.State.NOT_CONNECTED);
|
||||||
mGBDevice = null;
|
device.sendDeviceUpdateIntent(this);
|
||||||
mDeviceSupport = null;
|
updateReceiversState();
|
||||||
mCoordinator = null;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ACTION_FIND_DEVICE: {
|
case ACTION_FIND_DEVICE: {
|
||||||
boolean start = intent.getBooleanExtra(EXTRA_FIND_START, false);
|
boolean start = intent.getBooleanExtra(EXTRA_FIND_START, false);
|
||||||
mDeviceSupport.onFindDevice(start);
|
deviceSupport.onFindDevice(start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SET_CONSTANT_VIBRATION: {
|
case ACTION_SET_CONSTANT_VIBRATION: {
|
||||||
int intensity = intent.getIntExtra(EXTRA_VIBRATION_INTENSITY, 0);
|
int intensity = intent.getIntExtra(EXTRA_VIBRATION_INTENSITY, 0);
|
||||||
mDeviceSupport.onSetConstantVibration(intensity);
|
deviceSupport.onSetConstantVibration(intensity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_CALLSTATE:
|
case ACTION_CALLSTATE:
|
||||||
CallSpec callSpec = new CallSpec();
|
CallSpec callSpec = new CallSpec();
|
||||||
callSpec.command = intent.getIntExtra(EXTRA_CALL_COMMAND, CallSpec.CALL_UNDEFINED);
|
callSpec.command = intent.getIntExtra(EXTRA_CALL_COMMAND, CallSpec.CALL_UNDEFINED);
|
||||||
callSpec.number = intent.getStringExtra(EXTRA_CALL_PHONENUMBER);
|
callSpec.number = intent.getStringExtra(EXTRA_CALL_PHONENUMBER);
|
||||||
callSpec.name = sanitizeNotifText(intent.getStringExtra(EXTRA_CALL_DISPLAYNAME));
|
callSpec.name = sanitizeNotifText(intent.getStringExtra(EXTRA_CALL_DISPLAYNAME), device);
|
||||||
callSpec.dndSuppressed = intent.getIntExtra(EXTRA_CALL_DNDSUPPRESSED, 0);
|
callSpec.dndSuppressed = intent.getIntExtra(EXTRA_CALL_DNDSUPPRESSED, 0);
|
||||||
mDeviceSupport.onSetCallState(callSpec);
|
deviceSupport.onSetCallState(callSpec);
|
||||||
break;
|
break;
|
||||||
case ACTION_SETCANNEDMESSAGES:
|
case ACTION_SETCANNEDMESSAGES:
|
||||||
int type = intent.getIntExtra(EXTRA_CANNEDMESSAGES_TYPE, -1);
|
int type = intent.getIntExtra(EXTRA_CANNEDMESSAGES_TYPE, -1);
|
||||||
@ -525,24 +704,24 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
CannedMessagesSpec cannedMessagesSpec = new CannedMessagesSpec();
|
CannedMessagesSpec cannedMessagesSpec = new CannedMessagesSpec();
|
||||||
cannedMessagesSpec.type = type;
|
cannedMessagesSpec.type = type;
|
||||||
cannedMessagesSpec.cannedMessages = cannedMessages;
|
cannedMessagesSpec.cannedMessages = cannedMessages;
|
||||||
mDeviceSupport.onSetCannedMessages(cannedMessagesSpec);
|
deviceSupport.onSetCannedMessages(cannedMessagesSpec);
|
||||||
break;
|
break;
|
||||||
case ACTION_SETTIME:
|
case ACTION_SETTIME:
|
||||||
mDeviceSupport.onSetTime();
|
deviceSupport.onSetTime();
|
||||||
break;
|
break;
|
||||||
case ACTION_SETMUSICINFO:
|
case ACTION_SETMUSICINFO:
|
||||||
MusicSpec musicSpec = new MusicSpec();
|
MusicSpec musicSpec = new MusicSpec();
|
||||||
musicSpec.artist = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ARTIST));
|
musicSpec.artist = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ARTIST), device);
|
||||||
musicSpec.album = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ALBUM));
|
musicSpec.album = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ALBUM), device);
|
||||||
musicSpec.track = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_TRACK));
|
musicSpec.track = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_TRACK), device);
|
||||||
musicSpec.duration = intent.getIntExtra(EXTRA_MUSIC_DURATION, 0);
|
musicSpec.duration = intent.getIntExtra(EXTRA_MUSIC_DURATION, 0);
|
||||||
musicSpec.trackCount = intent.getIntExtra(EXTRA_MUSIC_TRACKCOUNT, 0);
|
musicSpec.trackCount = intent.getIntExtra(EXTRA_MUSIC_TRACKCOUNT, 0);
|
||||||
musicSpec.trackNr = intent.getIntExtra(EXTRA_MUSIC_TRACKNR, 0);
|
musicSpec.trackNr = intent.getIntExtra(EXTRA_MUSIC_TRACKNR, 0);
|
||||||
mDeviceSupport.onSetMusicInfo(musicSpec);
|
deviceSupport.onSetMusicInfo(musicSpec);
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_PHONE_VOLUME:
|
case ACTION_SET_PHONE_VOLUME:
|
||||||
float phoneVolume = intent.getFloatExtra(EXTRA_PHONE_VOLUME, 0);
|
float phoneVolume = intent.getFloatExtra(EXTRA_PHONE_VOLUME, 0);
|
||||||
mDeviceSupport.onSetPhoneVolume(phoneVolume);
|
deviceSupport.onSetPhoneVolume(phoneVolume);
|
||||||
break;
|
break;
|
||||||
case ACTION_SETMUSICSTATE:
|
case ACTION_SETMUSICSTATE:
|
||||||
MusicStateSpec stateSpec = new MusicStateSpec();
|
MusicStateSpec stateSpec = new MusicStateSpec();
|
||||||
@ -551,23 +730,23 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
stateSpec.position = intent.getIntExtra(EXTRA_MUSIC_POSITION, 0);
|
stateSpec.position = intent.getIntExtra(EXTRA_MUSIC_POSITION, 0);
|
||||||
stateSpec.playRate = intent.getIntExtra(EXTRA_MUSIC_RATE, 0);
|
stateSpec.playRate = intent.getIntExtra(EXTRA_MUSIC_RATE, 0);
|
||||||
stateSpec.state = intent.getByteExtra(EXTRA_MUSIC_STATE, (byte) 0);
|
stateSpec.state = intent.getByteExtra(EXTRA_MUSIC_STATE, (byte) 0);
|
||||||
mDeviceSupport.onSetMusicState(stateSpec);
|
deviceSupport.onSetMusicState(stateSpec);
|
||||||
break;
|
break;
|
||||||
case ACTION_REQUEST_APPINFO:
|
case ACTION_REQUEST_APPINFO:
|
||||||
mDeviceSupport.onAppInfoReq();
|
deviceSupport.onAppInfoReq();
|
||||||
break;
|
break;
|
||||||
case ACTION_REQUEST_SCREENSHOT:
|
case ACTION_REQUEST_SCREENSHOT:
|
||||||
mDeviceSupport.onScreenshotReq();
|
deviceSupport.onScreenshotReq();
|
||||||
break;
|
break;
|
||||||
case ACTION_STARTAPP: {
|
case ACTION_STARTAPP: {
|
||||||
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
|
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
|
||||||
boolean start = intent.getBooleanExtra(EXTRA_APP_START, true);
|
boolean start = intent.getBooleanExtra(EXTRA_APP_START, true);
|
||||||
mDeviceSupport.onAppStart(uuid, start);
|
deviceSupport.onAppStart(uuid, start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DELETEAPP: {
|
case ACTION_DELETEAPP: {
|
||||||
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
|
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
|
||||||
mDeviceSupport.onAppDelete(uuid);
|
deviceSupport.onAppDelete(uuid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_APP_CONFIGURE: {
|
case ACTION_APP_CONFIGURE: {
|
||||||
@ -577,87 +756,87 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
if (intent.hasExtra(EXTRA_APP_CONFIG_ID)) {
|
if (intent.hasExtra(EXTRA_APP_CONFIG_ID)) {
|
||||||
id = intent.getIntExtra(EXTRA_APP_CONFIG_ID, 0);
|
id = intent.getIntExtra(EXTRA_APP_CONFIG_ID, 0);
|
||||||
}
|
}
|
||||||
mDeviceSupport.onAppConfiguration(uuid, config, id);
|
deviceSupport.onAppConfiguration(uuid, config, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_APP_REORDER: {
|
case ACTION_APP_REORDER: {
|
||||||
UUID[] uuids = (UUID[]) intent.getSerializableExtra(EXTRA_APP_UUID);
|
UUID[] uuids = (UUID[]) intent.getSerializableExtra(EXTRA_APP_UUID);
|
||||||
mDeviceSupport.onAppReorder(uuids);
|
deviceSupport.onAppReorder(uuids);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_INSTALL:
|
case ACTION_INSTALL:
|
||||||
Uri uri = intent.getParcelableExtra(EXTRA_URI);
|
Uri uri = intent.getParcelableExtra(EXTRA_URI);
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
LOG.info("will try to install app/fw");
|
LOG.info("will try to install app/fw");
|
||||||
mDeviceSupport.onInstallApp(uri);
|
deviceSupport.onInstallApp(uri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_ALARMS:
|
case ACTION_SET_ALARMS:
|
||||||
ArrayList<? extends Alarm> alarms = (ArrayList<? extends Alarm>) intent.getSerializableExtra(EXTRA_ALARMS);
|
ArrayList<? extends Alarm> alarms = (ArrayList<? extends Alarm>) intent.getSerializableExtra(EXTRA_ALARMS);
|
||||||
mDeviceSupport.onSetAlarms(alarms);
|
deviceSupport.onSetAlarms(alarms);
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_REMINDERS:
|
case ACTION_SET_REMINDERS:
|
||||||
ArrayList<? extends Reminder> reminders = (ArrayList<? extends Reminder>) intent.getSerializableExtra(EXTRA_REMINDERS);
|
ArrayList<? extends Reminder> reminders = (ArrayList<? extends Reminder>) intent.getSerializableExtra(EXTRA_REMINDERS);
|
||||||
mDeviceSupport.onSetReminders(reminders);
|
deviceSupport.onSetReminders(reminders);
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_WORLD_CLOCKS:
|
case ACTION_SET_WORLD_CLOCKS:
|
||||||
ArrayList<? extends WorldClock> clocks = (ArrayList<? extends WorldClock>) intent.getSerializableExtra(EXTRA_WORLD_CLOCKS);
|
ArrayList<? extends WorldClock> clocks = (ArrayList<? extends WorldClock>) intent.getSerializableExtra(EXTRA_WORLD_CLOCKS);
|
||||||
mDeviceSupport.onSetWorldClocks(clocks);
|
deviceSupport.onSetWorldClocks(clocks);
|
||||||
break;
|
break;
|
||||||
case ACTION_ENABLE_REALTIME_STEPS: {
|
case ACTION_ENABLE_REALTIME_STEPS: {
|
||||||
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
||||||
mDeviceSupport.onEnableRealtimeSteps(enable);
|
deviceSupport.onEnableRealtimeSteps(enable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT: {
|
case ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT: {
|
||||||
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
||||||
mDeviceSupport.onEnableHeartRateSleepSupport(enable);
|
deviceSupport.onEnableHeartRateSleepSupport(enable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL: {
|
case ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL: {
|
||||||
int seconds = intent.getIntExtra(EXTRA_INTERVAL_SECONDS, 0);
|
int seconds = intent.getIntExtra(EXTRA_INTERVAL_SECONDS, 0);
|
||||||
mDeviceSupport.onSetHeartRateMeasurementInterval(seconds);
|
deviceSupport.onSetHeartRateMeasurementInterval(seconds);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT: {
|
case ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT: {
|
||||||
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
|
||||||
mDeviceSupport.onEnableRealtimeHeartRateMeasurement(enable);
|
deviceSupport.onEnableRealtimeHeartRateMeasurement(enable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SEND_CONFIGURATION: {
|
case ACTION_SEND_CONFIGURATION: {
|
||||||
String config = intent.getStringExtra(EXTRA_CONFIG);
|
String config = intent.getStringExtra(EXTRA_CONFIG);
|
||||||
mDeviceSupport.onSendConfiguration(config);
|
deviceSupport.onSendConfiguration(config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_READ_CONFIGURATION: {
|
case ACTION_READ_CONFIGURATION: {
|
||||||
String config = intent.getStringExtra(EXTRA_CONFIG);
|
String config = intent.getStringExtra(EXTRA_CONFIG);
|
||||||
mDeviceSupport.onReadConfiguration(config);
|
deviceSupport.onReadConfiguration(config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_TEST_NEW_FUNCTION: {
|
case ACTION_TEST_NEW_FUNCTION: {
|
||||||
mDeviceSupport.onTestNewFunction();
|
deviceSupport.onTestNewFunction();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SEND_WEATHER: {
|
case ACTION_SEND_WEATHER: {
|
||||||
WeatherSpec weatherSpec = intent.getParcelableExtra(EXTRA_WEATHER);
|
WeatherSpec weatherSpec = intent.getParcelableExtra(EXTRA_WEATHER);
|
||||||
if (weatherSpec != null) {
|
if (weatherSpec != null) {
|
||||||
mDeviceSupport.onSendWeather(weatherSpec);
|
deviceSupport.onSendWeather(weatherSpec);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SET_LED_COLOR:
|
case ACTION_SET_LED_COLOR:
|
||||||
int color = intent.getIntExtra(EXTRA_LED_COLOR, 0);
|
int color = intent.getIntExtra(EXTRA_LED_COLOR, 0);
|
||||||
if (color != 0) {
|
if (color != 0) {
|
||||||
mDeviceSupport.onSetLedColor(color);
|
deviceSupport.onSetLedColor(color);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_POWER_OFF:
|
case ACTION_POWER_OFF:
|
||||||
mDeviceSupport.onPowerOff();
|
deviceSupport.onPowerOff();
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_FM_FREQUENCY:
|
case ACTION_SET_FM_FREQUENCY:
|
||||||
float frequency = intent.getFloatExtra(EXTRA_FM_FREQUENCY, -1);
|
float frequency = intent.getFloatExtra(EXTRA_FM_FREQUENCY, -1);
|
||||||
if (frequency != -1) {
|
if (frequency != -1) {
|
||||||
mDeviceSupport.onSetFmFrequency(frequency);
|
deviceSupport.onSetFmFrequency(frequency);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_GPS_LOCATION:
|
case ACTION_SET_GPS_LOCATION:
|
||||||
@ -671,18 +850,79 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
* Disposes the current DeviceSupport instance (if any) and sets a new device support instance
|
* Disposes the current DeviceSupport instance (if any) and sets a new device support instance
|
||||||
* (if not null).
|
* (if not null).
|
||||||
*
|
*
|
||||||
* @param deviceSupport
|
* @param deviceSupport deviceSupport to reokace/add
|
||||||
*/
|
*/
|
||||||
private void setDeviceSupport(@Nullable DeviceSupport deviceSupport) {
|
private void setDeviceSupport(GBDevice device, DeviceSupport deviceSupport) throws DeviceNotFoundException {
|
||||||
if (deviceSupport != mDeviceSupport && mDeviceSupport != null) {
|
DeviceStruct deviceStruct = getDeviceStruct(device);
|
||||||
mDeviceSupport.dispose();
|
DeviceSupport cachedDeviceSupport = deviceStruct.getDeviceSupport();
|
||||||
mDeviceSupport = null;
|
if (deviceSupport != cachedDeviceSupport && cachedDeviceSupport != null) {
|
||||||
mGBDevice = null;
|
cachedDeviceSupport.dispose();
|
||||||
mCoordinator = null;
|
|
||||||
}
|
}
|
||||||
mDeviceSupport = deviceSupport;
|
deviceStruct.setDeviceSupport(deviceSupport);
|
||||||
mGBDevice = mDeviceSupport != null ? mDeviceSupport.getDevice() : null;
|
}
|
||||||
mCoordinator = mGBDevice != null ? DeviceHelper.getInstance().getCoordinator(mGBDevice) : null;
|
|
||||||
|
private void removeDeviceSupport(GBDevice device) throws DeviceNotFoundException {
|
||||||
|
DeviceStruct struct = getDeviceStruct(device);
|
||||||
|
if(struct.getDeviceSupport() != null){
|
||||||
|
struct.getDeviceSupport().dispose();
|
||||||
|
}
|
||||||
|
struct.setDeviceSupport(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceStruct getDeviceStructOrNull(GBDevice device){
|
||||||
|
DeviceStruct deviceStruct = null;
|
||||||
|
try {
|
||||||
|
deviceStruct = getDeviceStruct(device);
|
||||||
|
} catch (DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return deviceStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceStruct getDeviceStruct(GBDevice device) throws DeviceNotFoundException {
|
||||||
|
if(device == null){
|
||||||
|
throw new DeviceNotFoundException("null");
|
||||||
|
}
|
||||||
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device)){
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new DeviceNotFoundException(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GBDevice getDeviceByAddress(String deviceAddress) throws DeviceNotFoundException {
|
||||||
|
if(deviceAddress == null){
|
||||||
|
throw new DeviceNotFoundException(deviceAddress);
|
||||||
|
}
|
||||||
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().getAddress().equals(deviceAddress)){
|
||||||
|
return struct.getDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new DeviceNotFoundException(deviceAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GBDevice getDeviceByAddressOrNull(String deviceAddress){
|
||||||
|
GBDevice device = null;
|
||||||
|
try {
|
||||||
|
device = getDeviceByAddress(deviceAddress);
|
||||||
|
} catch (DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceSupport getDeviceSupport(GBDevice device) throws DeviceNotFoundException {
|
||||||
|
if(device == null){
|
||||||
|
throw new DeviceNotFoundException("null");
|
||||||
|
}
|
||||||
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device)){
|
||||||
|
return struct.getDeviceSupport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new DeviceNotFoundException(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
@ -697,30 +937,49 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
return mStarted;
|
return mStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConnected() {
|
private boolean isDeviceConnected(GBDevice device) {
|
||||||
return mGBDevice != null && mGBDevice.isConnected();
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device) ){
|
||||||
|
return struct.getDevice().isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConnecting() {
|
private boolean isDeviceConnecting(GBDevice device) {
|
||||||
return mGBDevice != null && mGBDevice.isConnecting();
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device) ){
|
||||||
|
return struct.getDevice().isConnecting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInitialized() {
|
private boolean isDeviceInitialized(GBDevice device) {
|
||||||
return mGBDevice != null && mGBDevice.isInitialized();
|
for(DeviceStruct struct : deviceStructs){
|
||||||
|
if(struct.getDevice().equals(device) ){
|
||||||
|
return struct.getDevice().isInitialized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setReceiversEnableState(boolean enable, boolean initialized, DeviceCoordinator coordinator) {
|
private void setReceiversEnableState(boolean enable, boolean initialized, FeatureSet features) {
|
||||||
LOG.info("Setting broadcast receivers to: " + enable);
|
LOG.info("Setting broadcast receivers to: " + enable);
|
||||||
|
|
||||||
if (enable && initialized && coordinator != null && coordinator.supportsCalendarEvents()) {
|
if(enable && features == null){
|
||||||
|
throw new RuntimeException("features cannot be null when enabling receivers");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable && initialized && features.supportsCalendarEvents()) {
|
||||||
if (mCalendarReceiver == null && getPrefs().getBoolean("enable_calendar_sync", true)) {
|
if (mCalendarReceiver == null && getPrefs().getBoolean("enable_calendar_sync", true)) {
|
||||||
if (!(GBApplication.isRunningMarshmallowOrLater() && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)) {
|
if (!(GBApplication.isRunningMarshmallowOrLater() && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)) {
|
||||||
IntentFilter calendarIntentFilter = new IntentFilter();
|
IntentFilter calendarIntentFilter = new IntentFilter();
|
||||||
calendarIntentFilter.addAction("android.intent.action.PROVIDER_CHANGED");
|
calendarIntentFilter.addAction("android.intent.action.PROVIDER_CHANGED");
|
||||||
calendarIntentFilter.addDataScheme("content");
|
calendarIntentFilter.addDataScheme("content");
|
||||||
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
|
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
|
||||||
mCalendarReceiver = new CalendarReceiver(mGBDevice);
|
mCalendarReceiver = new CalendarReceiver(null);
|
||||||
registerReceiver(mCalendarReceiver, calendarIntentFilter);
|
registerReceiver(mCalendarReceiver, calendarIntentFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -756,7 +1015,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
mPebbleReceiver = new PebbleReceiver();
|
mPebbleReceiver = new PebbleReceiver();
|
||||||
registerReceiver(mPebbleReceiver, new IntentFilter("com.getpebble.action.SEND_NOTIFICATION"));
|
registerReceiver(mPebbleReceiver, new IntentFilter("com.getpebble.action.SEND_NOTIFICATION"));
|
||||||
}
|
}
|
||||||
if (mMusicPlaybackReceiver == null && coordinator != null && coordinator.supportsMusicInfo()) {
|
if (mMusicPlaybackReceiver == null && features.supportsMusicInfo()) {
|
||||||
mMusicPlaybackReceiver = new MusicPlaybackReceiver();
|
mMusicPlaybackReceiver = new MusicPlaybackReceiver();
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
for (String action : mMusicActions) {
|
for (String action : mMusicActions) {
|
||||||
@ -771,10 +1030,6 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
filter.addAction("android.intent.action.TIMEZONE_CHANGED");
|
filter.addAction("android.intent.action.TIMEZONE_CHANGED");
|
||||||
registerReceiver(mTimeChangeReceiver, filter);
|
registerReceiver(mTimeChangeReceiver, filter);
|
||||||
}
|
}
|
||||||
if (mBlueToothConnectReceiver == null) {
|
|
||||||
mBlueToothConnectReceiver = new BluetoothConnectReceiver(this);
|
|
||||||
registerReceiver(mBlueToothConnectReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
|
|
||||||
}
|
|
||||||
if (mBlueToothPairingRequestReceiver == null) {
|
if (mBlueToothPairingRequestReceiver == null) {
|
||||||
mBlueToothPairingRequestReceiver = new BluetoothPairingRequestReceiver(this);
|
mBlueToothPairingRequestReceiver = new BluetoothPairingRequestReceiver(this);
|
||||||
registerReceiver(mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
|
registerReceiver(mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
|
||||||
@ -790,7 +1045,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Weather receivers
|
// Weather receivers
|
||||||
if ( coordinator != null && coordinator.supportsWeather()) {
|
if (features.supportsWeather()) {
|
||||||
if (GBApplication.isRunningOreoOrLater()) {
|
if (GBApplication.isRunningOreoOrLater()) {
|
||||||
if (mLineageOsWeatherReceiver == null) {
|
if (mLineageOsWeatherReceiver == null) {
|
||||||
mLineageOsWeatherReceiver = new LineageOsWeatherReceiver();
|
mLineageOsWeatherReceiver = new LineageOsWeatherReceiver();
|
||||||
@ -818,7 +1073,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GBApplication.getPrefs().getBoolean("auto_fetch_enabled", false) &&
|
if (GBApplication.getPrefs().getBoolean("auto_fetch_enabled", false) &&
|
||||||
coordinator != null && coordinator.supportsActivityDataFetching() && mGBAutoFetchReceiver == null) {
|
features.supportsActivityDataFetching() && mGBAutoFetchReceiver == null) {
|
||||||
mGBAutoFetchReceiver = new GBAutoFetchReceiver();
|
mGBAutoFetchReceiver = new GBAutoFetchReceiver();
|
||||||
registerReceiver(mGBAutoFetchReceiver, new IntentFilter("android.intent.action.USER_PRESENT"));
|
registerReceiver(mGBAutoFetchReceiver, new IntentFilter("android.intent.action.USER_PRESENT"));
|
||||||
}
|
}
|
||||||
@ -847,10 +1102,6 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
unregisterReceiver(mTimeChangeReceiver);
|
unregisterReceiver(mTimeChangeReceiver);
|
||||||
mTimeChangeReceiver = null;
|
mTimeChangeReceiver = null;
|
||||||
}
|
}
|
||||||
if (mBlueToothConnectReceiver != null) {
|
|
||||||
unregisterReceiver(mBlueToothConnectReceiver);
|
|
||||||
mBlueToothConnectReceiver = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBlueToothPairingRequestReceiver != null) {
|
if (mBlueToothPairingRequestReceiver != null) {
|
||||||
unregisterReceiver(mBlueToothPairingRequestReceiver);
|
unregisterReceiver(mBlueToothPairingRequestReceiver);
|
||||||
@ -900,7 +1151,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
|
||||||
setReceiversEnableState(false, false, null); // disable BroadcastReceivers
|
setReceiversEnableState(false, false, null); // disable BroadcastReceivers
|
||||||
|
|
||||||
setDeviceSupport(null);
|
unregisterReceiver(mBlueToothConnectReceiver);
|
||||||
|
|
||||||
|
for(GBDevice device : getGBDevices()){
|
||||||
|
try {
|
||||||
|
removeDeviceSupport(device);
|
||||||
|
} catch (DeviceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
GB.removeNotification(GB.NOTIFICATION_ID, this); // need to do this because the updated notification won't be cancelled when service stops
|
GB.removeNotification(GB.NOTIFICATION_ID, this); // need to do this because the updated notification won't be cancelled when service stops
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,10 +1170,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
if (GBPrefs.AUTO_RECONNECT.equals(key)) {
|
if (GBPrefs.DEVICE_AUTO_RECONNECT.equals(key)) {
|
||||||
boolean autoReconnect = getGBPrefs().getAutoReconnect();
|
for(DeviceStruct deviceStruct : deviceStructs){
|
||||||
if (mDeviceSupport != null) {
|
boolean autoReconnect = getGBPrefs().getAutoReconnect(deviceStruct.getDevice());
|
||||||
mDeviceSupport.setAutoReconnect(autoReconnect);
|
deviceStruct.getDeviceSupport().setAutoReconnect(autoReconnect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (GBPrefs.CHART_MAX_HEART_RATE.equals(key) || GBPrefs.CHART_MIN_HEART_RATE.equals(key)) {
|
if (GBPrefs.CHART_MAX_HEART_RATE.equals(key) || GBPrefs.CHART_MIN_HEART_RATE.equals(key)) {
|
||||||
@ -934,7 +1193,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
return GBApplication.getGBPrefs();
|
return GBApplication.getGBPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDevice getGBDevice() {
|
public GBDevice[] getGBDevices() {
|
||||||
return mGBDevice;
|
GBDevice[] devices = new GBDevice[deviceStructs.size()];
|
||||||
|
for(int i = 0; i < devices.length; i++){
|
||||||
|
devices[i] = deviceStructs.get(i).getDevice();
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,248 +161,170 @@ public class DeviceSupportFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeviceSupport createBTDeviceSupport(GBDevice gbDevice) throws GBException {
|
private ServiceDeviceSupport createServiceDeviceSupport(GBDevice device){
|
||||||
if (mBtAdapter != null && mBtAdapter.isEnabled()) {
|
switch (device.getType()) {
|
||||||
DeviceSupport deviceSupport = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (gbDevice.getType()) {
|
|
||||||
case PEBBLE:
|
case PEBBLE:
|
||||||
deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new PebbleSupport());
|
||||||
break;
|
|
||||||
case MIBAND:
|
case MIBAND:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBandSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiBandSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case MIBAND2:
|
case MIBAND2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HuamiSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new HuamiSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case MIBAND3:
|
case MIBAND3:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBand3Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiBand3Support());
|
||||||
break;
|
|
||||||
case MIBAND4:
|
case MIBAND4:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBand4Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiBand4Support());
|
||||||
break;
|
|
||||||
case MIBAND5:
|
case MIBAND5:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBand5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiBand5Support());
|
||||||
break;
|
|
||||||
case MIBAND6:
|
case MIBAND6:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBand6Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiBand6Support());
|
||||||
break;
|
|
||||||
case AMAZFITBIP:
|
case AMAZFITBIP:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipSupport());
|
||||||
break;
|
|
||||||
case AMAZFITBIP_LITE:
|
case AMAZFITBIP_LITE:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipLiteSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipLiteSupport());
|
||||||
break;
|
|
||||||
case AMAZFITBIPS:
|
case AMAZFITBIPS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipSSupport());
|
||||||
break;
|
|
||||||
case AMAZFITBIPS_LITE:
|
case AMAZFITBIPS_LITE:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSLiteSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipSLiteSupport());
|
||||||
break;
|
|
||||||
case AMAZFITBIPU:
|
case AMAZFITBIPU:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipUSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipUSupport());
|
||||||
break;
|
|
||||||
case AMAZFITBIPUPRO:
|
case AMAZFITBIPUPRO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipUProSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBipUProSupport());
|
||||||
break;
|
|
||||||
case AMAZFITPOP:
|
case AMAZFITPOP:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitPopSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitPopSupport());
|
||||||
break;
|
|
||||||
case AMAZFITPOPPRO:
|
case AMAZFITPOPPRO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitPopProSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitPopProSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTR:
|
case AMAZFITGTR:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTRSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTRSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTR_LITE:
|
case AMAZFITGTR_LITE:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTRLiteSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTRLiteSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTR2:
|
case AMAZFITGTR2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTR2Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTR2Support());
|
||||||
break;
|
|
||||||
case ZEPP_E:
|
case ZEPP_E:
|
||||||
deviceSupport = new ServiceDeviceSupport(new ZeppESupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new ZeppESupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTR2E:
|
case AMAZFITGTR2E:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTR2eSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTR2eSupport());
|
||||||
break;
|
|
||||||
case AMAZFITTREX:
|
case AMAZFITTREX:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitTRexSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitTRexSupport());
|
||||||
break;
|
|
||||||
case AMAZFITTREXPRO:
|
case AMAZFITTREXPRO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitTRexProSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitTRexProSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTS:
|
case AMAZFITGTS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTSSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTSSupport());
|
||||||
break;
|
|
||||||
case AMAZFITVERGEL:
|
case AMAZFITVERGEL:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitVergeLSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitVergeLSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTS2:
|
case AMAZFITGTS2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTS2Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTS2Support());
|
||||||
break;
|
|
||||||
case AMAZFITGTS2_MINI:
|
case AMAZFITGTS2_MINI:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTS2MiniSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTS2MiniSupport());
|
||||||
break;
|
|
||||||
case AMAZFITGTS2E:
|
case AMAZFITGTS2E:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTS2eSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitGTS2eSupport());
|
||||||
break;
|
|
||||||
case AMAZFITCOR:
|
case AMAZFITCOR:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitCorSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitCorSupport());
|
||||||
break;
|
|
||||||
case AMAZFITCOR2:
|
case AMAZFITCOR2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitCor2Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitCor2Support());
|
||||||
break;
|
|
||||||
case AMAZFITBAND5:
|
case AMAZFITBAND5:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBand5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitBand5Support());
|
||||||
break;
|
|
||||||
case AMAZFITX:
|
case AMAZFITX:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitXSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitXSupport());
|
||||||
break;
|
|
||||||
case AMAZFITNEO:
|
case AMAZFITNEO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitNeoSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new AmazfitNeoSupport());
|
||||||
break;
|
|
||||||
case VIBRATISSIMO:
|
case VIBRATISSIMO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new VibratissimoSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new VibratissimoSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case LIVEVIEW:
|
case LIVEVIEW:
|
||||||
deviceSupport = new ServiceDeviceSupport(new LiveviewSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new LiveviewSupport());
|
||||||
break;
|
|
||||||
case HPLUS:
|
case HPLUS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.HPLUS), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
|
||||||
break;
|
|
||||||
case MAKIBESF68:
|
case MAKIBESF68:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.MAKIBESF68), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
|
||||||
break;
|
|
||||||
case EXRIZUK8:
|
case EXRIZUK8:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.EXRIZUK8), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
|
||||||
break;
|
|
||||||
case Q8:
|
case Q8:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.Q8), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new HPlusSupport(device.getType()));
|
||||||
break;
|
|
||||||
case NO1F1:
|
case NO1F1:
|
||||||
deviceSupport = new ServiceDeviceSupport(new No1F1Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new No1F1Support());
|
||||||
break;
|
|
||||||
case TECLASTH30:
|
case TECLASTH30:
|
||||||
deviceSupport = new ServiceDeviceSupport(new TeclastH30Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new TeclastH30Support());
|
||||||
break;
|
|
||||||
case XWATCH:
|
case XWATCH:
|
||||||
deviceSupport = new ServiceDeviceSupport(new XWatchSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new XWatchSupport());
|
||||||
break;
|
|
||||||
case FOSSILQHYBRID:
|
case FOSSILQHYBRID:
|
||||||
deviceSupport = new ServiceDeviceSupport(new QHybridSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new QHybridSupport());
|
||||||
break;
|
|
||||||
case ZETIME:
|
case ZETIME:
|
||||||
deviceSupport = new ServiceDeviceSupport(new ZeTimeDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new ZeTimeDeviceSupport());
|
||||||
break;
|
|
||||||
case ID115:
|
case ID115:
|
||||||
deviceSupport = new ServiceDeviceSupport(new ID115Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new ID115Support());
|
||||||
break;
|
|
||||||
case WATCH9:
|
case WATCH9:
|
||||||
deviceSupport = new ServiceDeviceSupport(new Watch9DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new Watch9DeviceSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case WATCHXPLUS:
|
case WATCHXPLUS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new WatchXPlusDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new WatchXPlusDeviceSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case ROIDMI:
|
case ROIDMI:
|
||||||
deviceSupport = new ServiceDeviceSupport(new RoidmiSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new RoidmiSupport());
|
||||||
break;
|
|
||||||
case ROIDMI3:
|
case ROIDMI3:
|
||||||
deviceSupport = new ServiceDeviceSupport(new RoidmiSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new RoidmiSupport());
|
||||||
break;
|
|
||||||
case Y5:
|
case Y5:
|
||||||
deviceSupport = new ServiceDeviceSupport(new Y5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new Y5Support());
|
||||||
break;
|
|
||||||
case CASIOGB6900:
|
case CASIOGB6900:
|
||||||
deviceSupport = new ServiceDeviceSupport(new CasioGB6900DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new CasioGB6900DeviceSupport());
|
||||||
break;
|
|
||||||
case CASIOGBX100:
|
case CASIOGBX100:
|
||||||
deviceSupport = new ServiceDeviceSupport(new CasioGBX100DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new CasioGBX100DeviceSupport());
|
||||||
break;
|
|
||||||
case MISCALE2:
|
case MISCALE2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiScale2DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MiScale2DeviceSupport());
|
||||||
break;
|
|
||||||
case BFH16:
|
case BFH16:
|
||||||
deviceSupport = new ServiceDeviceSupport(new BFH16DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new BFH16DeviceSupport());
|
||||||
break;
|
|
||||||
case MIJIA_LYWSD02:
|
case MIJIA_LYWSD02:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MijiaLywsd02Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MijiaLywsd02Support());
|
||||||
break;
|
|
||||||
case MAKIBESHR3:
|
case MAKIBESHR3:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MakibesHR3DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new MakibesHR3DeviceSupport());
|
||||||
break;
|
|
||||||
case ITAG:
|
case ITAG:
|
||||||
deviceSupport = new ServiceDeviceSupport(new ITagSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new ITagSupport());
|
||||||
break;
|
|
||||||
case NUTMINI:
|
case NUTMINI:
|
||||||
deviceSupport = new ServiceDeviceSupport(new NutSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new NutSupport());
|
||||||
break;
|
|
||||||
case BANGLEJS:
|
case BANGLEJS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new BangleJSDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new BangleJSDeviceSupport());
|
||||||
break;
|
|
||||||
case TLW64:
|
case TLW64:
|
||||||
deviceSupport = new ServiceDeviceSupport(new TLW64Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new TLW64Support());
|
||||||
break;
|
|
||||||
case PINETIME_JF:
|
case PINETIME_JF:
|
||||||
deviceSupport = new ServiceDeviceSupport(new PineTimeJFSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new PineTimeJFSupport());
|
||||||
break;
|
|
||||||
case SG2:
|
case SG2:
|
||||||
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.SG2), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new HPlusSupport(DeviceType.SG2));
|
||||||
break;
|
|
||||||
case LEFUN:
|
case LEFUN:
|
||||||
deviceSupport = new ServiceDeviceSupport(new LefunDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new LefunDeviceSupport());
|
||||||
break;
|
|
||||||
case SONY_SWR12:
|
case SONY_SWR12:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SonySWR12DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SonySWR12DeviceSupport());
|
||||||
break;
|
|
||||||
case WASPOS:
|
case WASPOS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new WaspOSDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new WaspOSDeviceSupport());
|
||||||
break;
|
|
||||||
case SMAQ2OSS:
|
case SMAQ2OSS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SMAQ2OSSSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SMAQ2OSSSupport());
|
||||||
break;
|
|
||||||
case UM25:
|
case UM25:
|
||||||
deviceSupport = new ServiceDeviceSupport(new UM25Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new UM25Support());
|
||||||
break;
|
|
||||||
case DOMYOS_T540:
|
case DOMYOS_T540:
|
||||||
deviceSupport = new ServiceDeviceSupport(new DomyosT540Support(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new DomyosT540Support(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case FITPRO:
|
case FITPRO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new FitProDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new FitProDeviceSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case NOTHING_EAR1:
|
case NOTHING_EAR1:
|
||||||
deviceSupport = new ServiceDeviceSupport(new Ear1Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new Ear1Support());
|
||||||
break;
|
|
||||||
case GALAXY_BUDS:
|
case GALAXY_BUDS:
|
||||||
deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new GalaxyBudsDeviceSupport());
|
||||||
break;
|
|
||||||
case GALAXY_BUDS_LIVE:
|
case GALAXY_BUDS_LIVE:
|
||||||
deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new GalaxyBudsDeviceSupport());
|
||||||
break;
|
|
||||||
case GALAXY_BUDS_PRO:
|
case GALAXY_BUDS_PRO:
|
||||||
deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case SONY_WH_1000XM3:
|
case SONY_WH_1000XM3:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SonyHeadphonesSupport());
|
||||||
break;
|
|
||||||
case SONY_WH_1000XM4:
|
case SONY_WH_1000XM4:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SonyHeadphonesSupport());
|
||||||
break;
|
|
||||||
case SONY_WF_SP800N:
|
case SONY_WF_SP800N:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SonyHeadphonesSupport(), ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
break;
|
|
||||||
case SONY_WF_1000XM3:
|
case SONY_WF_1000XM3:
|
||||||
deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new SonyHeadphonesSupport());
|
||||||
break;
|
|
||||||
case VESC_NRF:
|
case VESC_NRF:
|
||||||
case VESC_HM10:
|
case VESC_HM10:
|
||||||
deviceSupport = new ServiceDeviceSupport(new VescDeviceSupport(gbDevice.getType()), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new VescDeviceSupport(device.getType()));
|
||||||
break;
|
|
||||||
case BOSE_QC35:
|
case BOSE_QC35:
|
||||||
deviceSupport = new ServiceDeviceSupport(new QC35BaseSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
return new ServiceDeviceSupport(new QC35BaseSupport());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceSupport createBTDeviceSupport(GBDevice gbDevice) throws GBException {
|
||||||
|
if (mBtAdapter != null && mBtAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
DeviceSupport deviceSupport = createServiceDeviceSupport(gbDevice);
|
||||||
if (deviceSupport != null) {
|
if (deviceSupport != null) {
|
||||||
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
|
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
|
||||||
return deviceSupport;
|
return deviceSupport;
|
||||||
@ -416,7 +338,7 @@ public class DeviceSupportFactory {
|
|||||||
|
|
||||||
private DeviceSupport createTCPDeviceSupport(GBDevice gbDevice) throws GBException {
|
private DeviceSupport createTCPDeviceSupport(GBDevice gbDevice) throws GBException {
|
||||||
try {
|
try {
|
||||||
DeviceSupport deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
DeviceSupport deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
|
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
|
||||||
return deviceSupport;
|
return deviceSupport;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -27,6 +27,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -61,9 +62,14 @@ public class ServiceDeviceSupport implements DeviceSupport {
|
|||||||
private String lastNotificationKind;
|
private String lastNotificationKind;
|
||||||
private final EnumSet<Flags> flags;
|
private final EnumSet<Flags> flags;
|
||||||
|
|
||||||
public ServiceDeviceSupport(DeviceSupport delegate, EnumSet<Flags> flags) {
|
public ServiceDeviceSupport(DeviceSupport delegate, Flags... flags) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.flags = flags;
|
this.flags = EnumSet.noneOf(Flags.class);
|
||||||
|
this.flags.addAll(Arrays.asList(flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceDeviceSupport(DeviceSupport delegate){
|
||||||
|
this(delegate, Flags.BUSY_CHECKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
@ -69,8 +70,8 @@ public class AmazfitBipLiteFirmwareInfo extends HuamiFirmwareInfo {
|
|||||||
if (searchString32BitAligned(bytes, "Amazfit Bip Lite")) {
|
if (searchString32BitAligned(bytes, "Amazfit Bip Lite")) {
|
||||||
return HuamiFirmwareType.FIRMWARE;
|
return HuamiFirmwareType.FIRMWARE;
|
||||||
}
|
}
|
||||||
GBDevice device = GBApplication.app().getDeviceManager().getSelectedDevice();
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
if (device != null) {
|
for(GBDevice device : devices){
|
||||||
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
|
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
|
||||||
if (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_RELAX_FIRMWARE_CHECKS, false)) {
|
if (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_RELAX_FIRMWARE_CHECKS, false)) {
|
||||||
if (searchString32BitAligned(bytes, "Amazfit Bip")) {
|
if (searchString32BitAligned(bytes, "Amazfit Bip")) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbips;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbips;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
@ -66,10 +67,8 @@ public class AmazfitBipSFirmwareInfo extends HuamiFirmwareInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HuamiFirmwareType determineFirmwareType(byte[] bytes) {
|
protected HuamiFirmwareType determineFirmwareType(byte[] bytes) {
|
||||||
|
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
|
||||||
GBDevice device = GBApplication.app().getDeviceManager().getSelectedDevice();
|
for (GBDevice device : devices) {
|
||||||
|
|
||||||
if (device != null) {
|
|
||||||
if (device.getFirmwareVersion().startsWith("2.")) {
|
if (device.getFirmwareVersion().startsWith("2.")) {
|
||||||
//For devices on firmware 2.x it is a tonleasp device and needs a header which looks like Mi Band 4
|
//For devices on firmware 2.x it is a tonleasp device and needs a header which looks like Mi Band 4
|
||||||
if (ArrayUtils.equals(bytes, MiBand4FirmwareInfo.FW_HEADER, MiBand4FirmwareInfo.FW_HEADER_OFFSET)) {
|
if (ArrayUtils.equals(bytes, MiBand4FirmwareInfo.FW_HEADER, MiBand4FirmwareInfo.FW_HEADER_OFFSET)) {
|
||||||
|
@ -242,7 +242,7 @@ class PebbleIoThread extends GBDeviceIoThread {
|
|||||||
public void run() {
|
public void run() {
|
||||||
mIsConnected = connect();
|
mIsConnected = connect();
|
||||||
if (!mIsConnected) {
|
if (!mIsConnected) {
|
||||||
if (GBApplication.getGBPrefs().getAutoReconnect() && !mQuit) {
|
if (GBApplication.getGBPrefs().getAutoReconnect(getDevice()) && !mQuit) {
|
||||||
gbDevice.setState(GBDevice.State.WAITING_FOR_RECONNECT);
|
gbDevice.setState(GBDevice.State.WAITING_FOR_RECONNECT);
|
||||||
gbDevice.sendDeviceUpdateIntent(getContext());
|
gbDevice.sendDeviceUpdateIntent(getContext());
|
||||||
}
|
}
|
||||||
@ -406,7 +406,7 @@ class PebbleIoThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
enablePebbleKitSupport(false);
|
enablePebbleKitSupport(false);
|
||||||
|
|
||||||
if (mQuit || !GBApplication.getGBPrefs().getAutoReconnect()) {
|
if (mQuit || !GBApplication.getGBPrefs().getAutoReconnect(getDevice())) {
|
||||||
gbDevice.setState(GBDevice.State.NOT_CONNECTED);
|
gbDevice.setState(GBDevice.State.NOT_CONNECTED);
|
||||||
} else {
|
} else {
|
||||||
gbDevice.setState(GBDevice.State.WAITING_FOR_RECONNECT);
|
gbDevice.setState(GBDevice.State.WAITING_FOR_RECONNECT);
|
||||||
|
@ -69,7 +69,7 @@ public class QC35BaseSupport extends AbstractSerialDeviceSupport {
|
|||||||
public boolean connect() {
|
public boolean connect() {
|
||||||
getDeviceProtocol();
|
getDeviceProtocol();
|
||||||
getDeviceIOThread().start();
|
getDeviceIOThread().start();
|
||||||
getDevice().setBatteryThresholdPercent((short)15);
|
getDevice().setBatteryThresholdPercent((short)25);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ public class QC35Protocol extends GBDeviceProtocol {
|
|||||||
if(third == 0x03){
|
if(third == 0x03){
|
||||||
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
|
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
|
||||||
batteryInfo.level = data[0];
|
batteryInfo.level = data[0];
|
||||||
|
batteryInfo.state = BatteryState.BATTERY_NORMAL;
|
||||||
events.add(batteryInfo);
|
events.add(batteryInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,24 +58,31 @@ public class AutoConnectIntervalReceiver extends BroadcastReceiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GBDevice gbDevice = service.getGBDevice();
|
GBDevice[] devices = service.getGBDevices();
|
||||||
if (gbDevice == null) {
|
if (action.equals(DeviceManager.ACTION_DEVICES_CHANGED)){
|
||||||
return;
|
boolean scheduleAutoConnect = false;
|
||||||
|
boolean allDevicesInitialized = true;
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(!device.isInitialized()){
|
||||||
|
allDevicesInitialized = false;
|
||||||
|
}else if(device.getState() == GBDevice.State.WAITING_FOR_RECONNECT){
|
||||||
|
scheduleAutoConnect = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.equals(DeviceManager.ACTION_DEVICES_CHANGED)) {
|
if(allDevicesInitialized){
|
||||||
if (gbDevice.isInitialized()) {
|
LOG.info("will reset connection delay, all devices are initialized!");
|
||||||
LOG.info("will reset connection delay, device is initialized!");
|
return;
|
||||||
mDelay = 4;
|
|
||||||
}
|
}
|
||||||
else if (gbDevice.getState() == GBDevice.State.WAITING_FOR_RECONNECT) {
|
if(scheduleAutoConnect){
|
||||||
scheduleReconnect();
|
scheduleReconnect();
|
||||||
}
|
}
|
||||||
|
}else if (action.equals("GB_RECONNECT")){
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(device.getState() == GBDevice.State.WAITING_FOR_RECONNECT) {
|
||||||
|
LOG.info("Will re-connect to " + device.getAddress() + "(" + device.getName() + ")");
|
||||||
|
GBApplication.deviceService().connect(device);
|
||||||
}
|
}
|
||||||
else if (action.equals("GB_RECONNECT")) {
|
|
||||||
if (gbDevice.getState() == GBDevice.State.WAITING_FOR_RECONNECT) {
|
|
||||||
LOG.info("Will re-connect to " + gbDevice.getAddress() + "(" + gbDevice.getName() + ")");
|
|
||||||
GBApplication.deviceService().connect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ public class BondingUtil {
|
|||||||
public static void connectThenComplete(BondingInterface bondingInterface, GBDevice device) {
|
public static void connectThenComplete(BondingInterface bondingInterface, GBDevice device) {
|
||||||
toast(bondingInterface.getContext(), bondingInterface.getContext().getString(R.string.discovery_trying_to_connect_to, device.getName()), Toast.LENGTH_SHORT, GB.INFO);
|
toast(bondingInterface.getContext(), bondingInterface.getContext().getString(R.string.discovery_trying_to_connect_to, device.getName()), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
// Disconnect when LE Pebble so that the user can manually initiate a connection
|
// Disconnect when LE Pebble so that the user can manually initiate a connection
|
||||||
GBApplication.deviceService().disconnect();
|
GBApplication.deviceService().disconnect(device);
|
||||||
GBApplication.deviceService().connect(device, true);
|
GBApplication.deviceService().connect(device, true);
|
||||||
bondingInterface.onBondingComplete(true);
|
bondingInterface.onBondingComplete(true);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.SpannableString;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -44,6 +46,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
||||||
@ -145,7 +148,20 @@ public class GB {
|
|||||||
return pendingIntent;
|
return pendingIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createNotification(GBDevice device, Context context) {
|
public static Notification createNotification(List<GBDevice> devices, Context context) {
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||||
|
if(devices.size() == 0){
|
||||||
|
builder.setContentTitle(context.getString(R.string.info_no_devices_connected))
|
||||||
|
.setSmallIcon(R.drawable.ic_notification_disconnected)
|
||||||
|
.setContentIntent(getContentIntent(context))
|
||||||
|
.setShowWhen(false)
|
||||||
|
.setOngoing(true);
|
||||||
|
|
||||||
|
if (!GBApplication.isRunningTwelveOrLater()) {
|
||||||
|
builder.setColor(context.getResources().getColor(R.color.accent));
|
||||||
|
}
|
||||||
|
}else if(devices.size() == 1) {
|
||||||
|
GBDevice device = devices.get(0);
|
||||||
String deviceName = device.getAliasOrName();
|
String deviceName = device.getAliasOrName();
|
||||||
String text = device.getStateString();
|
String text = device.getStateString();
|
||||||
if (device.getBatteryLevel() != GBDevice.BATTERY_UNKNOWN) {
|
if (device.getBatteryLevel() != GBDevice.BATTERY_UNKNOWN) {
|
||||||
@ -153,7 +169,6 @@ public class GB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean connected = device.isInitialized();
|
boolean connected = device.isInitialized();
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
|
||||||
builder.setContentTitle(deviceName)
|
builder.setContentTitle(deviceName)
|
||||||
.setTicker(deviceName + " - " + text)
|
.setTicker(deviceName + " - " + text)
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
@ -183,6 +198,52 @@ public class GB {
|
|||||||
PendingIntent reconnectPendingIntent = PendingIntent.getService(context, 2, deviceCommunicationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent reconnectPendingIntent = PendingIntent.getService(context, 2, deviceCommunicationServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
builder.addAction(R.drawable.ic_notification, context.getString(R.string.controlcenter_connect), reconnectPendingIntent);
|
builder.addAction(R.drawable.ic_notification, context.getString(R.string.controlcenter_connect), reconnectPendingIntent);
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
StringBuilder contentText = new StringBuilder();
|
||||||
|
boolean isConnected = true;
|
||||||
|
boolean anyDeviceSupportesActivityDataFetching = false;
|
||||||
|
for(GBDevice device : devices){
|
||||||
|
if(!device.isInitialized()){
|
||||||
|
isConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
anyDeviceSupportesActivityDataFetching |= DeviceHelper.getInstance().getCoordinator(device).supportsActivityDataFetching();
|
||||||
|
|
||||||
|
String deviceName = device.getAliasOrName();
|
||||||
|
String text = device.getStateString();
|
||||||
|
if (device.getBatteryLevel() != GBDevice.BATTERY_UNKNOWN) {
|
||||||
|
text += ": " + context.getString(R.string.battery) + " " + device.getBatteryLevel() + "%";
|
||||||
|
}
|
||||||
|
contentText.append(deviceName).append(" (").append(text).append(")<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
SpannableString formated = new SpannableString(
|
||||||
|
Html.fromHtml(contentText.substring(0, contentText.length() - 4)) // cut away last <br>
|
||||||
|
);
|
||||||
|
|
||||||
|
String title = context.getString(R.string.info_connected_count, devices.size());
|
||||||
|
|
||||||
|
builder.setContentTitle(title)
|
||||||
|
.setContentText(formated)
|
||||||
|
.setSmallIcon(isConnected ? R.drawable.ic_notification : R.drawable.ic_notification_disconnected)
|
||||||
|
.setContentIntent(getContentIntent(context))
|
||||||
|
.setStyle(new NotificationCompat.BigTextStyle().bigText(formated).setBigContentTitle(title))
|
||||||
|
.setShowWhen(false)
|
||||||
|
.setOngoing(true);
|
||||||
|
|
||||||
|
if (!GBApplication.isRunningTwelveOrLater()) {
|
||||||
|
builder.setColor(context.getResources().getColor(R.color.accent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GBApplication.isRunningLollipopOrLater() && anyDeviceSupportesActivityDataFetching) { //for some reason this fails on KK
|
||||||
|
Intent deviceCommunicationServiceIntent = new Intent(context, DeviceCommunicationService.class);
|
||||||
|
deviceCommunicationServiceIntent.setAction(DeviceService.ACTION_FETCH_RECORDED_DATA);
|
||||||
|
deviceCommunicationServiceIntent.putExtra(EXTRA_RECORDED_DATA_TYPES, ActivityKind.TYPE_ACTIVITY);
|
||||||
|
PendingIntent fetchPendingIntent = PendingIntent.getService(context, 1, deviceCommunicationServiceIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
builder.addAction(R.drawable.ic_refresh, context.getString(R.string.controlcenter_fetch_activity_data), fetchPendingIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GBApplication.isRunningLollipopOrLater()) {
|
if (GBApplication.isRunningLollipopOrLater()) {
|
||||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||||
}
|
}
|
||||||
@ -220,8 +281,8 @@ public class GB {
|
|||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateNotification(GBDevice device, Context context) {
|
public static void updateNotification(List<GBDevice> devices, Context context) {
|
||||||
Notification notification = createNotification(device, context);
|
Notification notification = createNotification(devices, context);
|
||||||
notify(NOTIFICATION_ID, notification, context);
|
notify(NOTIFICATION_ID, notification, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.util;
|
|||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.Criteria;
|
import android.location.Criteria;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
@ -33,6 +34,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
|
||||||
public class GBPrefs {
|
public class GBPrefs {
|
||||||
// Since this class must not log to slf4j, we use plain android.util.Log
|
// Since this class must not log to slf4j, we use plain android.util.Log
|
||||||
@ -41,7 +43,8 @@ public class GBPrefs {
|
|||||||
public static final String PACKAGE_BLACKLIST = "package_blacklist";
|
public static final String PACKAGE_BLACKLIST = "package_blacklist";
|
||||||
public static final String PACKAGE_PEBBLEMSG_BLACKLIST = "package_pebblemsg_blacklist";
|
public static final String PACKAGE_PEBBLEMSG_BLACKLIST = "package_pebblemsg_blacklist";
|
||||||
public static final String CALENDAR_BLACKLIST = "calendar_blacklist";
|
public static final String CALENDAR_BLACKLIST = "calendar_blacklist";
|
||||||
public static final String AUTO_RECONNECT = "general_autocreconnect";
|
public static final String DEVICE_AUTO_RECONNECT = "prefs_key_device_auto_reconnect";
|
||||||
|
public static final String DEVICE_CONNECT_BACK = "prefs_key_device_reconnect_on_acl";
|
||||||
private static final String AUTO_START = "general_autostartonboot";
|
private static final String AUTO_START = "general_autostartonboot";
|
||||||
public static final String AUTO_EXPORT_ENABLED = "auto_export_enabled";
|
public static final String AUTO_EXPORT_ENABLED = "auto_export_enabled";
|
||||||
public static final String AUTO_EXPORT_LOCATION = "auto_export_location";
|
public static final String AUTO_EXPORT_LOCATION = "auto_export_location";
|
||||||
@ -67,8 +70,9 @@ public class GBPrefs {
|
|||||||
mPrefs = prefs;
|
mPrefs = prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAutoReconnect() {
|
public boolean getAutoReconnect(GBDevice device) {
|
||||||
return mPrefs.getBoolean(AUTO_RECONNECT, AUTO_RECONNECT_DEFAULT);
|
SharedPreferences deviceSpecificPreferences = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress());
|
||||||
|
return deviceSpecificPreferences.getBoolean(DEVICE_AUTO_RECONNECT, AUTO_RECONNECT_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAutoStart() {
|
public boolean getAutoStart() {
|
||||||
|
@ -1628,4 +1628,7 @@
|
|||||||
<string name="about_activity_title_banglejs_nopebble">Über Bangle.js Gadgetbridge</string>
|
<string name="about_activity_title_banglejs_nopebble">Über Bangle.js Gadgetbridge</string>
|
||||||
<string name="pref_device_action_fitness_app_control_toggle">Fitness-App-Tracking umschalten</string>
|
<string name="pref_device_action_fitness_app_control_toggle">Fitness-App-Tracking umschalten</string>
|
||||||
<string name="pref_title_banglejs_text_bitmap">Text als Bitmaps</string>
|
<string name="pref_title_banglejs_text_bitmap">Text als Bitmaps</string>
|
||||||
|
|
||||||
|
<string name="info_connected_count">%d Geräte verbunden</string>
|
||||||
|
<string name="info_no_devices_connected">Keine Geräte verbunden</string>
|
||||||
</resources>
|
</resources>
|
@ -1666,4 +1666,7 @@
|
|||||||
<string name="pref_summary_opentracks_packagename">Used for starting/stopping GPS track recording in external fitness app.</string>
|
<string name="pref_summary_opentracks_packagename">Used for starting/stopping GPS track recording in external fitness app.</string>
|
||||||
<string name="watchface_dialog_pre_setting_position">pre-setting position to %s</string>
|
<string name="watchface_dialog_pre_setting_position">pre-setting position to %s</string>
|
||||||
<string name="watchface_setting_light_up_on_notification">Light up on new notification</string>
|
<string name="watchface_setting_light_up_on_notification">Light up on new notification</string>
|
||||||
|
|
||||||
|
<string name="info_no_devices_connected">no devices connected</string>
|
||||||
|
<string name="info_connected_count">%d devices connected</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
11
app/src/main/res/xml/devicesettings_reconnect_bl_classic.xml
Normal file
11
app/src/main/res/xml/devicesettings_reconnect_bl_classic.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="Connection over Bluetooth classic" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="prefs_key_device_reconnect_on_acl"
|
||||||
|
android:title="connect on connection from device"
|
||||||
|
android:summary="establish a connection when connection is initiated by device, like headphones"
|
||||||
|
android:layout="@layout/preference_checkbox" />
|
||||||
|
</PreferenceScreen>
|
11
app/src/main/res/xml/devicesettings_reconnect_ble.xml
Normal file
11
app/src/main/res/xml/devicesettings_reconnect_ble.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="Connection over BLE" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="prefs_key_device_auto_reconnect"
|
||||||
|
android:title="auto-reconnect to device"
|
||||||
|
android:summary="proactively try to connect to device periodically"
|
||||||
|
android:layout="@layout/preference_checkbox" />
|
||||||
|
</PreferenceScreen>
|
@ -17,7 +17,9 @@
|
|||||||
android:layout="@layout/preference_checkbox"
|
android:layout="@layout/preference_checkbox"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="general_autocreconnect"
|
android:key="general_autocreconnect"
|
||||||
android:title="@string/pref_title_general_autoreconnect" />
|
android:title="@string/pref_title_general_autoreconnect"
|
||||||
|
android:enabled="false"
|
||||||
|
android:summary="setting has been moved to device specific settings"/>
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:layout="@layout/preference_checkbox"
|
android:layout="@layout/preference_checkbox"
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user