1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-02 03:16:07 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
2021-12-25 22:06:19 +01:00

952 lines
50 KiB
Java

/* Copyright (C) 2015-2021 Andreas Böhler, Andreas Shimokawa, Avamander,
Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Daniel Hauck, Dikay900,
Frank Slezak, ivanovlev, João Paulo Barraca, José Rebelo, Julien Pivotto,
Kasha, keeshii, mamucho, Martin, Matthieu Baerts, Nephiel, Sebastian Kranz,
Sergey Trofimov, Steffen Liebergeld, Taavi Eomäe, Uwe Hermann
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothPairingRequestReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.CMWeatherReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.CalendarReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.LineageOsWeatherReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.MusicPlaybackReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.OmniJawsObserver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PebbleReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PhoneCallReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.SMSReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.TimeChangeReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.TinyWeatherForecastGermanyReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.*;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.Reminder;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.receivers.AutoConnectIntervalReceiver;
import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBAutoFetchReceiver;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.EmojiConverter;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ADD_CALENDAREVENT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_CONFIGURE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_REORDER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CALLSTATE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DELETEAPP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DELETE_CALENDAREVENT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DELETE_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DISCONNECT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ENABLE_REALTIME_STEPS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_RECORDED_DATA;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_HEARTRATE_TEST;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_READ_CONFIGURATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_APPINFO;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_DEVICEINFO;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_SCREENSHOT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_RESET;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SEND_CONFIGURATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SEND_WEATHER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETCANNEDMESSAGES;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETMUSICINFO;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETMUSICSTATE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETTIME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_ALARMS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_CONSTANT_VIBRATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_FM_FREQUENCY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_LED_COLOR;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_REMINDERS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_TEST_NEW_FUNCTION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_ALARMS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_CONFIG;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_CONFIG_ID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_UUID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_BOOLEAN_ENABLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_DESCRIPTION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_DURATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_ID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_LOCATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TIMESTAMP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TITLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_DISPLAYNAME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CONFIG;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CONNECT_FIRST_TIME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_FIND_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_FM_FREQUENCY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_INTERVAL_SECONDS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_LED_COLOR;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ALBUM;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_DURATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_POSITION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_RATE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_REPEAT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_SHUFFLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_STATE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACKCOUNT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACKNR;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ACTIONS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_DNDSUPPRESSED;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_FLAGS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ICONID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PEBBLE_COLOR;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PHONENUMBER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCEAPPID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCENAME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RECORDED_DATA_TYPES;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_REMINDERS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RESET_FLAGS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_VIBRATION_INTENSITY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WEATHER;
public class DeviceCommunicationService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
@SuppressLint("StaticFieldLeak") // only used for test cases
private static DeviceSupportFactory DEVICE_SUPPORT_FACTORY = null;
private boolean mStarted = false;
private DeviceSupportFactory mFactory;
private GBDevice mGBDevice = null;
private DeviceSupport mDeviceSupport;
private DeviceCoordinator mCoordinator = null;
private PhoneCallReceiver mPhoneCallReceiver = null;
private SMSReceiver mSMSReceiver = null;
private PebbleReceiver mPebbleReceiver = null;
private MusicPlaybackReceiver mMusicPlaybackReceiver = null;
private TimeChangeReceiver mTimeChangeReceiver = null;
private BluetoothConnectReceiver mBlueToothConnectReceiver = null;
private BluetoothPairingRequestReceiver mBlueToothPairingRequestReceiver = null;
private AlarmClockReceiver mAlarmClockReceiver = null;
private GBAutoFetchReceiver mGBAutoFetchReceiver = null;
private AutoConnectIntervalReceiver mAutoConnectInvervalReceiver= null;
private AlarmReceiver mAlarmReceiver = null;
private CalendarReceiver mCalendarReceiver = null;
private CMWeatherReceiver mCMWeatherReceiver = null;
private LineageOsWeatherReceiver mLineageOsWeatherReceiver = null;
private TinyWeatherForecastGermanyReceiver mTinyWeatherForecastGermanyReceiver = null;
private OmniJawsObserver mOmniJawsObserver = null;
private final String[] mMusicActions = {
"com.android.music.metachanged",
"com.android.music.playstatechanged",
"com.android.music.queuechanged",
"com.android.music.playbackcomplete",
"net.sourceforge.subsonic.androidapp.EVENT_META_CHANGED",
"com.maxmpz.audioplayer.TPOS_SYNC",
"com.maxmpz.audioplayer.STATUS_CHANGED",
"com.maxmpz.audioplayer.PLAYING_MODE_CHANGED",
"com.spotify.music.metadatachanged",
"com.spotify.music.playbackstatechanged"
};
private ArrayList<DeviceContainer> deviceContainerArrayList = new ArrayList<>();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (GBDevice.ACTION_DEVICE_CHANGED.equals(action)) {
GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
if (mGBDevice != null && mGBDevice.equals(device)) {
mGBDevice = device;
mCoordinator = DeviceHelper.getInstance().getCoordinator(device);
boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized());
setReceiversEnableState(enableReceivers, mGBDevice.isInitialized(), mCoordinator);
} else {
LOG.error("Got ACTION_DEVICE_CHANGED from unexpected device: " + device);
}
}
}
};
private Boolean mServiceStarted = false;
public DeviceCommunicationService() {
}
@Override
public void onCreate() {
LOG.debug("DeviceCommunicationService is being created");
super.onCreate();
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED));
if (hasPrefs()) {
getPrefs().getPreferences().registerOnSharedPreferenceChangeListener(this);
}
}
private DeviceSupportFactory getDeviceSupportFactory() {
if (DEVICE_SUPPORT_FACTORY != null) {
return DEVICE_SUPPORT_FACTORY;
}
return new DeviceSupportFactory(this);
}
/**
* For testing!
*
* @param factory to use for testing
*/
public static void setDeviceSupportFactory(DeviceSupportFactory factory) {
DEVICE_SUPPORT_FACTORY = factory;
}
@Override
public synchronized int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
LOG.info("no intent");
return START_NOT_STICKY;
}
String action = intent.getAction();
boolean firstTime = intent.getBooleanExtra(EXTRA_CONNECT_FIRST_TIME, false);
if (action == null) {
LOG.info("no action");
return START_NOT_STICKY;
}
LOG.debug("Service start command: " + action);
if (action.equals(ACTION_START)) {
start();
return START_STICKY;
}
GBDevice intentGBDevice = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
DeviceContainer intentGBDeviceContainer = getContainerForDevice(intentGBDevice);
if (intentGBDeviceContainer == null) {
if (intentGBDevice != null) {
intentGBDevice.sendDeviceUpdateIntent(this);
}
return START_NOT_STICKY;
}
if (!action.equals(ACTION_START) && !action.equals(ACTION_CONNECT)) {
if (!mServiceStarted) {
// using the service before issuing ACTION_START
LOG.info("Must start service with " + ACTION_START + " or " + ACTION_CONNECT + " before using it: " + action);
return START_NOT_STICKY;
}
if (mDeviceSupport == null || (!isInitialized() && !action.equals(ACTION_DISCONNECT) && (!mDeviceSupport.useAutoConnect() || isConnected()))) {
// trying to send notification without valid Bluetooth connection
if (intentGBDeviceContainer.getGBDevice() != null) {
// at least send back the current device state
intentGBDeviceContainer.getGBDevice().sendDeviceUpdateIntent(this);
}
return START_STICKY;
}
}
// when we get past this, we should have valid mDeviceSupport and mGBDevice instances
Prefs prefs = getPrefs();
switch (action) {
/* case ACTION_START: {
start();
break;
}*/
case ACTION_CONNECT: {
start(); // ensure started
String btDeviceAddress;
btDeviceAddress = intentGBDevice.getAddress();
boolean autoReconnect = GBPrefs.AUTO_RECONNECT_DEFAULT;
if (prefs != null && prefs.getPreferences() != null) {
prefs.getPreferences().edit().putString("last_device_address", btDeviceAddress).apply();
autoReconnect = getGBPrefs().getAutoReconnect();
}
if (!isConnecting(intentGBDevice) && !isConnected(intentGBDevice)) {
setDeviceSupport(null, intentGBDeviceContainer);
try {
DeviceSupportFactory factory = getDeviceSupportFactory();
intentGBDeviceContainer.setDeviceSupportFactory(factory);
DeviceSupport deviceSupport = factory.createDeviceSupport(intentGBDevice);
if (deviceSupport != null) {
setDeviceSupport(deviceSupport, intentGBDeviceContainer);
if (firstTime) {
deviceSupport.connectFirstTime();
} else {
deviceSupport.setAutoReconnect(autoReconnect);
deviceSupport.connect();
}
} else {
GB.toast(this, getString(R.string.cannot_connect, "Can't create device support"), Toast.LENGTH_SHORT, GB.ERROR);
}
} catch (Exception e) {
GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR, e);
setDeviceSupport(null, intentGBDeviceContainer);
}
} else {
// send an update at least
intentGBDevice.sendDeviceUpdateIntent(this);
}
break;
}
default:
if (mDeviceSupport == null || mGBDevice == null) {
LOG.warn("device support:" + mDeviceSupport + ", device: " + mGBDevice + ", aborting");
} else {
handleAction(intent, action, prefs);
}
break;
}
return START_STICKY;
}
/**
* @param text original text
* @return 'text' or a new String without non supported chars like emoticons, etc.
*/
private String sanitizeNotifText(String text) {
if (text == null || text.length() == 0)
return text;
text = mDeviceSupport.customStringFilter(text);
if (!mCoordinator.supportsUnicodeEmojis()) {
return EmojiConverter.convertUnicodeEmojiToAscii(text, getApplicationContext());
}
return text;
}
private void handleAction(Intent intent, String action, Prefs prefs) {
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(mGBDevice.getAddress()));
boolean transliterate = devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false);
if (transliterate) {
for (String extra : GBDeviceService.transliterationExtras) {
if (intent.hasExtra(extra)) {
intent.putExtra(extra, LanguageUtils.transliterate(intent.getStringExtra(extra)));
}
}
}
switch (action) {
case ACTION_REQUEST_DEVICEINFO:
mGBDevice.sendDeviceUpdateIntent(this);
break;
case ACTION_NOTIFICATION: {
int desiredId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
NotificationSpec notificationSpec = new NotificationSpec(desiredId);
notificationSpec.phoneNumber = intent.getStringExtra(EXTRA_NOTIFICATION_PHONENUMBER);
notificationSpec.sender = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SENDER));
notificationSpec.subject = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT));
notificationSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_TITLE));
notificationSpec.body = sanitizeNotifText(intent.getStringExtra(EXTRA_NOTIFICATION_BODY));
notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME);
notificationSpec.type = (NotificationType) intent.getSerializableExtra(EXTRA_NOTIFICATION_TYPE);
notificationSpec.attachedActions = (ArrayList<NotificationSpec.Action>) intent.getSerializableExtra(EXTRA_NOTIFICATION_ACTIONS);
notificationSpec.pebbleColor = (byte) intent.getSerializableExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR);
notificationSpec.flags = intent.getIntExtra(EXTRA_NOTIFICATION_FLAGS, 0);
notificationSpec.sourceAppId = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCEAPPID);
notificationSpec.iconId = intent.getIntExtra(EXTRA_NOTIFICATION_ICONID, 0);
notificationSpec.dndSuppressed = intent.getIntExtra(EXTRA_NOTIFICATION_DNDSUPPRESSED, 0);
if (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null) {
GBApplication.getIDSenderLookup().add(notificationSpec.getId(), notificationSpec.phoneNumber);
}
//TODO: check if at least one of the attached actions is a reply action instead?
if ((notificationSpec.attachedActions != null && notificationSpec.attachedActions.size() > 0)
|| (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null)) {
// NOTE: maybe not where it belongs
// I would rather like to save that as an array in SharedPreferences
// this would work but I dont know how to do the same in the Settings Activity's xml
ArrayList<String> replies = new ArrayList<>();
for (int i = 1; i <= 16; i++) {
String reply = devicePrefs.getString("canned_reply_" + i, null);
if (reply != null && !reply.equals("")) {
replies.add(reply);
}
}
notificationSpec.cannedReplies = replies.toArray(new String[0]);
}
mDeviceSupport.onNotification(notificationSpec);
break;
}
case ACTION_DELETE_NOTIFICATION: {
mDeviceSupport.onDeleteNotification(intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1));
break;
}
case ACTION_ADD_CALENDAREVENT: {
CalendarEventSpec calendarEventSpec = new CalendarEventSpec();
calendarEventSpec.id = intent.getLongExtra(EXTRA_CALENDAREVENT_ID, -1);
calendarEventSpec.type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
calendarEventSpec.timestamp = intent.getIntExtra(EXTRA_CALENDAREVENT_TIMESTAMP, -1);
calendarEventSpec.durationInSeconds = intent.getIntExtra(EXTRA_CALENDAREVENT_DURATION, -1);
calendarEventSpec.title = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_TITLE));
calendarEventSpec.description = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_DESCRIPTION));
calendarEventSpec.location = sanitizeNotifText(intent.getStringExtra(EXTRA_CALENDAREVENT_LOCATION));
mDeviceSupport.onAddCalendarEvent(calendarEventSpec);
break;
}
case ACTION_DELETE_CALENDAREVENT: {
long id = intent.getLongExtra(EXTRA_CALENDAREVENT_ID, -1);
byte type = intent.getByteExtra(EXTRA_CALENDAREVENT_TYPE, (byte) -1);
mDeviceSupport.onDeleteCalendarEvent(type, id);
break;
}
case ACTION_RESET: {
int flags = intent.getIntExtra(EXTRA_RESET_FLAGS, 0);
mDeviceSupport.onReset(flags);
break;
}
case ACTION_HEARTRATE_TEST: {
mDeviceSupport.onHeartRateTest();
break;
}
case ACTION_FETCH_RECORDED_DATA: {
int dataTypes = intent.getIntExtra(EXTRA_RECORDED_DATA_TYPES, 0);
mDeviceSupport.onFetchRecordedData(dataTypes);
break;
}
case ACTION_DISCONNECT: {
mDeviceSupport.dispose();
if (mGBDevice != null) {
mGBDevice.setState(GBDevice.State.NOT_CONNECTED);
mGBDevice.sendDeviceUpdateIntent(this);
}
setReceiversEnableState(false, false, null);
mGBDevice = null;
mDeviceSupport = null;
mCoordinator = null;
break;
}
case ACTION_FIND_DEVICE: {
boolean start = intent.getBooleanExtra(EXTRA_FIND_START, false);
mDeviceSupport.onFindDevice(start);
break;
}
case ACTION_SET_CONSTANT_VIBRATION: {
int intensity = intent.getIntExtra(EXTRA_VIBRATION_INTENSITY, 0);
mDeviceSupport.onSetConstantVibration(intensity);
break;
}
case ACTION_CALLSTATE:
CallSpec callSpec = new CallSpec();
callSpec.command = intent.getIntExtra(EXTRA_CALL_COMMAND, CallSpec.CALL_UNDEFINED);
callSpec.number = intent.getStringExtra(EXTRA_CALL_PHONENUMBER);
callSpec.name = sanitizeNotifText(intent.getStringExtra(EXTRA_CALL_DISPLAYNAME));
mDeviceSupport.onSetCallState(callSpec);
break;
case ACTION_SETCANNEDMESSAGES:
int type = intent.getIntExtra(EXTRA_CANNEDMESSAGES_TYPE, -1);
String[] cannedMessages = intent.getStringArrayExtra(EXTRA_CANNEDMESSAGES);
CannedMessagesSpec cannedMessagesSpec = new CannedMessagesSpec();
cannedMessagesSpec.type = type;
cannedMessagesSpec.cannedMessages = cannedMessages;
mDeviceSupport.onSetCannedMessages(cannedMessagesSpec);
break;
case ACTION_SETTIME:
mDeviceSupport.onSetTime();
break;
case ACTION_SETMUSICINFO:
MusicSpec musicSpec = new MusicSpec();
musicSpec.artist = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ARTIST));
musicSpec.album = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_ALBUM));
musicSpec.track = sanitizeNotifText(intent.getStringExtra(EXTRA_MUSIC_TRACK));
musicSpec.duration = intent.getIntExtra(EXTRA_MUSIC_DURATION, 0);
musicSpec.trackCount = intent.getIntExtra(EXTRA_MUSIC_TRACKCOUNT, 0);
musicSpec.trackNr = intent.getIntExtra(EXTRA_MUSIC_TRACKNR, 0);
mDeviceSupport.onSetMusicInfo(musicSpec);
break;
case ACTION_SETMUSICSTATE:
MusicStateSpec stateSpec = new MusicStateSpec();
stateSpec.shuffle = intent.getByteExtra(EXTRA_MUSIC_SHUFFLE, (byte) 0);
stateSpec.repeat = intent.getByteExtra(EXTRA_MUSIC_REPEAT, (byte) 0);
stateSpec.position = intent.getIntExtra(EXTRA_MUSIC_POSITION, 0);
stateSpec.playRate = intent.getIntExtra(EXTRA_MUSIC_RATE, 0);
stateSpec.state = intent.getByteExtra(EXTRA_MUSIC_STATE, (byte) 0);
mDeviceSupport.onSetMusicState(stateSpec);
break;
case ACTION_REQUEST_APPINFO:
mDeviceSupport.onAppInfoReq();
break;
case ACTION_REQUEST_SCREENSHOT:
mDeviceSupport.onScreenshotReq();
break;
case ACTION_STARTAPP: {
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
boolean start = intent.getBooleanExtra(EXTRA_APP_START, true);
mDeviceSupport.onAppStart(uuid, start);
break;
}
case ACTION_DELETEAPP: {
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
mDeviceSupport.onAppDelete(uuid);
break;
}
case ACTION_APP_CONFIGURE: {
UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID);
String config = intent.getStringExtra(EXTRA_APP_CONFIG);
Integer id = null;
if (intent.hasExtra(EXTRA_APP_CONFIG_ID)) {
id = intent.getIntExtra(EXTRA_APP_CONFIG_ID, 0);
}
mDeviceSupport.onAppConfiguration(uuid, config, id);
break;
}
case ACTION_APP_REORDER: {
UUID[] uuids = (UUID[]) intent.getSerializableExtra(EXTRA_APP_UUID);
mDeviceSupport.onAppReorder(uuids);
break;
}
case ACTION_INSTALL:
Uri uri = intent.getParcelableExtra(EXTRA_URI);
if (uri != null) {
LOG.info("will try to install app/fw");
mDeviceSupport.onInstallApp(uri);
}
break;
case ACTION_SET_ALARMS:
ArrayList<? extends Alarm> alarms = (ArrayList<? extends Alarm>) intent.getSerializableExtra(EXTRA_ALARMS);
mDeviceSupport.onSetAlarms(alarms);
break;
case ACTION_SET_REMINDERS:
ArrayList<? extends Reminder> reminders = (ArrayList<? extends Reminder>) intent.getSerializableExtra(EXTRA_REMINDERS);
mDeviceSupport.onSetReminders(reminders);
break;
case ACTION_ENABLE_REALTIME_STEPS: {
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
mDeviceSupport.onEnableRealtimeSteps(enable);
break;
}
case ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT: {
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
mDeviceSupport.onEnableHeartRateSleepSupport(enable);
break;
}
case ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL: {
int seconds = intent.getIntExtra(EXTRA_INTERVAL_SECONDS, 0);
mDeviceSupport.onSetHeartRateMeasurementInterval(seconds);
break;
}
case ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT: {
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
mDeviceSupport.onEnableRealtimeHeartRateMeasurement(enable);
break;
}
case ACTION_SEND_CONFIGURATION: {
String config = intent.getStringExtra(EXTRA_CONFIG);
mDeviceSupport.onSendConfiguration(config);
break;
}
case ACTION_READ_CONFIGURATION: {
String config = intent.getStringExtra(EXTRA_CONFIG);
mDeviceSupport.onReadConfiguration(config);
break;
}
case ACTION_TEST_NEW_FUNCTION: {
mDeviceSupport.onTestNewFunction();
break;
}
case ACTION_SEND_WEATHER: {
WeatherSpec weatherSpec = intent.getParcelableExtra(EXTRA_WEATHER);
if (weatherSpec != null) {
mDeviceSupport.onSendWeather(weatherSpec);
}
break;
}
case ACTION_SET_LED_COLOR:
int color = intent.getIntExtra(EXTRA_LED_COLOR, 0);
if (color != 0) {
mDeviceSupport.onSetLedColor(color);
}
break;
case ACTION_SET_FM_FREQUENCY:
float frequency = intent.getFloatExtra(EXTRA_FM_FREQUENCY, -1);
if (frequency != -1) {
mDeviceSupport.onSetFmFrequency(frequency);
}
break;
}
}
/**
* Disposes the current DeviceSupport instance (if any) and sets a new device support instance
* (if not null).
*
* @param deviceSupport to dispose
*/
private void setDeviceSupport(@Nullable DeviceSupport deviceSupport, DeviceContainer deviceContainer) {
if (deviceContainer == null) {
GBDevice mGBDevice = deviceSupport != null ? deviceSupport.getDevice() : null;
if (mGBDevice != null) {
deviceContainerArrayList.add(new DeviceContainer(mGBDevice, deviceSupport));
}
} else {
DeviceSupport mDeviceSupport = deviceContainer.getDeviceSupport();
if (deviceSupport != mDeviceSupport && mDeviceSupport != null) {
mDeviceSupport.dispose();
}
deviceContainer.setDeviceSupport(deviceSupport);
deviceContainer.setGBDevice(deviceSupport != null ? deviceSupport.getDevice() : null);
mCoordinator = null;
}
mDeviceSupport = deviceSupport;
mGBDevice = mDeviceSupport != null ? mDeviceSupport.getDevice() : null;
mCoordinator = mGBDevice != null ? DeviceHelper.getInstance().getCoordinator(mGBDevice) : null;
}
private DeviceContainer getContainerForDevice(GBDevice device) {
if (device == null) {
return null;
}
for (DeviceContainer container : deviceContainerArrayList) {
if (container.getGBDevice().equals(device)) {
return container;
}
}
DeviceContainer container = new DeviceContainer(device);
deviceContainerArrayList.add(container);
return container;
}
private void start() {
if (!mServiceStarted) {
GB.createNotificationChannels(this);
startForeground(GB.NOTIFICATION_ID, GB.createNotification(getString(R.string.gadgetbridge_running), this));
mServiceStarted = true;
}
}
public boolean isStarted() {
return mServiceStarted;
}
private boolean isConnected(GBDevice gbDevice) {
return gbDevice != null && gbDevice.isConnected();
}
private boolean isConnecting(GBDevice gbDevice) {
return gbDevice != null && gbDevice.isConnecting();
}
private boolean isInitialized(GBDevice gbDevice) {
return gbDevice != null && gbDevice.isInitialized();
}
private void setReceiversEnableState(boolean enable, boolean initialized, DeviceCoordinator coordinator, DeviceContainer deviceContainer) {
LOG.info("Setting broadcast receivers to: " + enable);
if (enable && initialized && coordinator != null && coordinator.supportsCalendarEvents()) {
if (deviceContainer.getCalendarReceiver() == null && getPrefs().getBoolean("enable_calendar_sync", true)) {
if (!(GBApplication.isRunningMarshmallowOrLater() && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)) {
IntentFilter calendarIntentFilter = new IntentFilter();
calendarIntentFilter.addAction("android.intent.action.PROVIDER_CHANGED");
calendarIntentFilter.addDataScheme("content");
calendarIntentFilter.addDataAuthority("com.android.calendar", null);
deviceContainer.setCalendarReceiver(new CalendarReceiver(deviceContainer.getGBDevice()));
registerReceiver(deviceContainer.getCalendarReceiver(), calendarIntentFilter);
}
}
if (deviceContainer.getAlarmReceiver() == null) {
deviceContainer.setAlarmReceiver(new AlarmReceiver());
registerReceiver(deviceContainer.getAlarmReceiver(), new IntentFilter("DAILY_ALARM"));
}
} else {
if (deviceContainer.getCalendarReceiver() != null) {
unregisterReceiver(deviceContainer.getCalendarReceiver());
deviceContainer.setCalendarReceiver(null);
}
if (deviceContainer.getAlarmReceiver() != null) {
unregisterReceiver(deviceContainer.getAlarmReceiver());
deviceContainer.setAlarmReceiver(null);
}
}
if (enable) {
if (deviceContainer.getPhoneCallReceiver() == null) {
deviceContainer.setPhoneCallReceiver(new PhoneCallReceiver());
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
filter.addAction("nodomain.freeyourgadget.gadgetbridge.MUTE_CALL");
registerReceiver(deviceContainer.getPhoneCallReceiver(), filter);
}
if (deviceContainer.getSMSReceiver() == null) {
deviceContainer.setSMSReceiver(new SMSReceiver());
registerReceiver(deviceContainer.getSMSReceiver(), new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
}
if (deviceContainer.getPebbleReceiver() == null) {
deviceContainer.setPebbleReceiver(new PebbleReceiver());
registerReceiver(deviceContainer.getPebbleReceiver(), new IntentFilter("com.getpebble.action.SEND_NOTIFICATION"));
}
if (deviceContainer.getMusicPlaybackReceiver() == null && coordinator != null && coordinator.supportsMusicInfo()) {
deviceContainer.setMusicPlaybackReceiver(new MusicPlaybackReceiver());
IntentFilter filter = new IntentFilter();
for (String action : mMusicActions) {
filter.addAction(action);
}
registerReceiver(deviceContainer.getMusicPlaybackReceiver(), filter);
}
if (deviceContainer.getTimeChangeReceiver() == null) {
deviceContainer.setTimeChangeReceiver(new TimeChangeReceiver());
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.TIME_SET");
filter.addAction("android.intent.action.TIMEZONE_CHANGED");
registerReceiver(deviceContainer.getTimeChangeReceiver(), filter);
}
if (deviceContainer.getBlueToothConnectReceiver() == null) {
deviceContainer.setBlueToothConnectReceiver(new BluetoothConnectReceiver(this));
registerReceiver(deviceContainer.getBlueToothConnectReceiver(), new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
}
if (deviceContainer.getBlueToothPairingRequestReceiver() == null) {
deviceContainer.setBlueToothPairingRequestReceiver(new BluetoothPairingRequestReceiver(this));
registerReceiver(deviceContainer.getBlueToothPairingRequestReceiver(), new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
}
if (deviceContainer.getAlarmClockReceiver() == null) {
deviceContainer.setAlarmClockReceiver(new AlarmClockReceiver());
IntentFilter filter = new IntentFilter();
filter.addAction(AlarmClockReceiver.ALARM_ALERT_ACTION);
filter.addAction(AlarmClockReceiver.ALARM_DONE_ACTION);
filter.addAction(AlarmClockReceiver.GOOGLE_CLOCK_ALARM_ALERT_ACTION);
filter.addAction(AlarmClockReceiver.GOOGLE_CLOCK_ALARM_DONE_ACTION);
registerReceiver(deviceContainer.getAlarmClockReceiver(), filter);
}
// Weather receivers
if ( coordinator != null && coordinator.supportsWeather()) {
if (GBApplication.isRunningOreoOrLater()) {
if (mLineageOsWeatherReceiver == null) {
mLineageOsWeatherReceiver = new LineageOsWeatherReceiver();
registerReceiver(mLineageOsWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER"));
}
}
else {
if (mCMWeatherReceiver == null) {
mCMWeatherReceiver = new CMWeatherReceiver();
registerReceiver(mCMWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER"));
}
}
if (mTinyWeatherForecastGermanyReceiver == null) {
mTinyWeatherForecastGermanyReceiver = new TinyWeatherForecastGermanyReceiver();
registerReceiver(mTinyWeatherForecastGermanyReceiver, new IntentFilter("de.kaffeemitkoffein.broadcast.WEATHERDATA"));
}
if (mOmniJawsObserver == null) {
try {
mOmniJawsObserver = new OmniJawsObserver(new Handler());
getContentResolver().registerContentObserver(OmniJawsObserver.WEATHER_URI, true, mOmniJawsObserver);
} catch (PackageManager.NameNotFoundException e) {
//Nothing wrong, it just means we're not running on omnirom.
}
}
}
if (GBApplication.getPrefs().getBoolean("auto_fetch_enabled", false) &&
coordinator != null && coordinator.supportsActivityDataFetching() && mGBAutoFetchReceiver == null) {
mGBAutoFetchReceiver = new GBAutoFetchReceiver();
registerReceiver(mGBAutoFetchReceiver, new IntentFilter("android.intent.action.USER_PRESENT"));
}
if (mAutoConnectInvervalReceiver == null) {
mAutoConnectInvervalReceiver= new AutoConnectIntervalReceiver(this);
registerReceiver(mAutoConnectInvervalReceiver, new IntentFilter("GB_RECONNECT"));
}
} else {
if (deviceContainer.getPhoneCallReceiver() != null) {
unregisterReceiver(deviceContainer.getPhoneCallReceiver());
deviceContainer.setPhoneCallReceiver(null);
}
if (deviceContainer.getSMSReceiver() != null) {
unregisterReceiver(deviceContainer.getSMSReceiver());
deviceContainer.setSMSReceiver(null);
}
if (deviceContainer.getPebbleReceiver() != null) {
unregisterReceiver(deviceContainer.getPebbleReceiver());
deviceContainer.setPebbleReceiver(null);
}
if (deviceContainer.getMusicPlaybackReceiver() != null) {
unregisterReceiver(deviceContainer.getMusicPlaybackReceiver());
deviceContainer.setMusicPlaybackReceiver(null);
}
if (deviceContainer.getTimeChangeReceiver() != null) {
unregisterReceiver(deviceContainer.getTimeChangeReceiver());
deviceContainer.setTimeChangeReceiver(null);
}
if (deviceContainer.getBlueToothConnectReceiver() != null) {
unregisterReceiver(deviceContainer.getBlueToothConnectReceiver());
deviceContainer.setBlueToothConnectReceiver(null);
}
if (deviceContainer.getBlueToothPairingRequestReceiver() != null) {
unregisterReceiver(deviceContainer.getBlueToothPairingRequestReceiver());
deviceContainer.setBlueToothPairingRequestReceiver(null);
}
if (deviceContainer.getAlarmClockReceiver() != null) {
unregisterReceiver(deviceContainer.getAlarmClockReceiver());
deviceContainer.setAlarmClockReceiver(null);
}
if (deviceContainer.getCMWeatherReceiver() != null) {
unregisterReceiver(deviceContainer.getCMWeatherReceiver());
deviceContainer.setCMWeatherReceiver(null);
}
if (mLineageOsWeatherReceiver != null) {
unregisterReceiver(mLineageOsWeatherReceiver);
mLineageOsWeatherReceiver = null;
}
if (deviceContainer.getOmniJawsObserver() != null) {
getContentResolver().unregisterContentObserver(deviceContainer.getOmniJawsObserver());
deviceContainer.setOmniJawsObserver(null);
mOmniJawsObserver = null;
}
if (mTinyWeatherForecastGermanyReceiver != null) {
unregisterReceiver(mTinyWeatherForecastGermanyReceiver);
mTinyWeatherForecastGermanyReceiver = null;
}
if (mGBAutoFetchReceiver != null) {
unregisterReceiver(mGBAutoFetchReceiver);
mGBAutoFetchReceiver = null;
}
if (mAutoConnectInvervalReceiver != null) {
unregisterReceiver(mAutoConnectInvervalReceiver);
mAutoConnectInvervalReceiver.destroy();
mAutoConnectInvervalReceiver = null;
}
}
}
@Override
public void onDestroy() {
if (hasPrefs()) {
getPrefs().getPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
LOG.debug("DeviceCommunicationService is being destroyed");
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
for (DeviceContainer container : deviceContainerArrayList) {
setReceiversEnableState(false, false, null, container); // disable BroadcastReceivers
setDeviceSupport(null, container);
}
GB.removeNotification(GB.NOTIFICATION_ID, this); // need to do this because the updated notification won't be cancelled when service stops
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (GBPrefs.AUTO_RECONNECT.equals(key)) {
boolean autoReconnect = getGBPrefs().getAutoReconnect();
DeviceSupport mDeviceSupport = null; // TODO: Fix
if (mDeviceSupport != null) {
mDeviceSupport.setAutoReconnect(autoReconnect);
}
}
if (GBPrefs.CHART_MAX_HEART_RATE.equals(key) || GBPrefs.CHART_MIN_HEART_RATE.equals(key)) {
HeartRateUtils.getInstance().updateCachedHeartRatePreferences();
}
}
protected boolean hasPrefs() {
return getPrefs().getPreferences() != null;
}
public Prefs getPrefs() {
return GBApplication.getPrefs();
}
public GBPrefs getGBPrefs() {
return GBApplication.getGBPrefs();
}
public ArrayList<DeviceContainer> getGBDevices() {
return deviceContainerArrayList;
}
}