diff --git a/CHANGELOG.md b/CHANGELOG.md
index 784d2e82a..4656ac9f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
### Changelog
+#### Version 0.21.0 (next)
+* Initial NO.1 F1 support
+* Amazfit Bip: Display GPS firmware version
+* Amazfit Bip: Fix E-Mail notifications
+* Amazfit Bip: Fix call notification with unknown caller
+* Pebble: Fix crash when takeing screenshots on Android 8.0 (Oreo)
+* Pebble: Support some google app icons
+* Pebble: try to support spotify
+* Fix language being reset to system default
+
#### Version 0.20.2
* Amazfit Bip: Various fixes regarding weather, add condition string support for FW 0.0.8.74
* Amazfit Bip: enable caller display in later firmwares
diff --git a/README.md b/README.md
index 8e713ba50..a4fbd80ac 100644
--- a/README.md
+++ b/README.md
@@ -6,10 +6,13 @@ Pebble, Mi Band, Amazfit Bit and HPlus device (and more) without the vendor's cl
and without the need to create an account and transmit any of your data to the
vendor's servers.
+
[Homepage](https://gadgetbridge.org)
[Blog](https://blog.gadgetbridge.org)
+[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/Gadgetbridge/donate)
+
[![Build](https://travis-ci.org/Freeyourgadget/Gadgetbridge.svg?branch=master)](https://travis-ci.org/Freeyourgadget/Gadgetbridge)
## Download
diff --git a/app/build.gradle b/app/build.gradle
index 06027cc0f..a9dff3d8a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -26,8 +26,8 @@ android {
targetSdkVersion 25
// note: always bump BOTH versionCode and versionName!
- versionName "0.20.2"
- versionCode 100
+ versionName "0.21.0"
+ versionCode 101
vectorDrawables.useSupportLibrary = true
}
buildTypes {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
index 10cd32ddb..5e2105583 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
@@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.service.NotificationCollectorMonitorService;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
+import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
@@ -544,11 +545,11 @@ public class GBApplication extends Application {
} else {
language = new Locale(lang);
}
- Configuration config = new Configuration();
- config.setLocale(language);
+ updateLanguage(language);
+ }
- // FIXME: I have no idea what I am doing
- context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
+ public static void updateLanguage(Locale locale) {
+ AndroidUtils.setLanguage(context, locale);
Intent intent = new Intent();
intent.setAction(ACTION_LANGUAGE_CHANGE);
@@ -570,6 +571,12 @@ public class GBApplication extends Application {
return typedValue.data;
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ updateLanguage(getLanguage());
+ }
+
public static int getBackgroundColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java
new file mode 100644
index 000000000..475031e23
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBActivity.java
@@ -0,0 +1,96 @@
+/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
+
+ 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 . */
+package nodomain.freeyourgadget.gadgetbridge.activities;
+
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.app.AppCompatActivity;
+
+import java.util.Locale;
+
+import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
+
+
+public abstract class AbstractGBActivity extends AppCompatActivity implements GBActivity {
+
+ public static final int NONE = 0;
+ public static final int NO_ACTIONBAR = 1;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case GBApplication.ACTION_LANGUAGE_CHANGE:
+ setLanguage(GBApplication.getLanguage(), true);
+ break;
+ case GBApplication.ACTION_QUIT:
+ finish();
+ break;
+ }
+ }
+ };
+
+ public void setLanguage(Locale language, boolean recreate) {
+ AndroidUtils.setLanguage(this, language, recreate);
+ }
+
+ public static void init(GBActivity activity) {
+ init(activity, NONE);
+ }
+
+ public static void init(GBActivity activity, int flags) {
+ if (GBApplication.isDarkThemeEnabled()) {
+ if ((flags & NO_ACTIONBAR) != 0) {
+ activity.setTheme(R.style.GadgetbridgeThemeDark_NoActionBar);
+ } else {
+ activity.setTheme(R.style.GadgetbridgeThemeDark);
+ }
+ } else {
+ if ((flags & NO_ACTIONBAR) != 0) {
+ activity.setTheme(R.style.GadgetbridgeTheme_NoActionBar);
+ } else {
+ activity.setTheme(R.style.GadgetbridgeTheme);
+ }
+ }
+ activity.setLanguage(GBApplication.getLanguage(), false);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ IntentFilter filterLocal = new IntentFilter();
+ filterLocal.addAction(GBApplication.ACTION_QUIT);
+ filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
+ LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
+
+ init(this);
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
+ super.onDestroy();
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java
index 087954de7..2390aedff 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragmentActivity.java
@@ -33,7 +33,7 @@ import android.support.v4.app.FragmentPagerAdapter;
*
* @see AbstractGBFragment
*/
-public abstract class AbstractGBFragmentActivity extends GBActivity {
+public abstract class AbstractGBFragmentActivity extends AbstractGBActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java
index 14d37112a..a1ca99131 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java
@@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
/**
@@ -46,7 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
* to set that listener in #onCreate, *not* in #onPostCreate, otherwise the value will
* not be displayed.
*/
-public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivity {
+public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivity implements GBActivity {
private static final Logger LOG = LoggerFactory.getLogger(AbstractSettingsActivity.class);
@@ -56,7 +55,7 @@ public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivi
String action = intent.getAction();
switch (action) {
case GBApplication.ACTION_LANGUAGE_CHANGE:
- setLanguage(GBApplication.getLanguage());
+ setLanguage(GBApplication.getLanguage(), true);
break;
case GBApplication.ACTION_QUIT:
finish();
@@ -129,11 +128,7 @@ public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivi
@Override
protected void onCreate(Bundle savedInstanceState) {
- if (GBApplication.isDarkThemeEnabled()) {
- setTheme(R.style.GadgetbridgeThemeDark);
- } else {
- setTheme(R.style.GadgetbridgeTheme);
- }
+ AbstractGBActivity.init(this);
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBApplication.ACTION_QUIT);
@@ -215,7 +210,7 @@ public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivi
return super.onOptionsItemSelected(item);
}
- private void setLanguage(Locale language) {
- AndroidUtils.setLanguage(this, language);
+ public void setLanguage(Locale language, boolean recreate) {
+ AndroidUtils.setLanguage(this, language, recreate);
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java
index 543673de3..d0cfa085d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java
@@ -31,7 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
-public class AlarmDetails extends GBActivity {
+public class AlarmDetails extends AbstractGBActivity {
private GBAlarm alarm;
private TimePicker timePicker;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java
index f26dd3b04..a2c39bbcf 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AndroidPairingActivity.java
@@ -20,7 +20,7 @@ import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
-public class AndroidPairingActivity extends GBActivity {
+public class AndroidPairingActivity extends AbstractGBActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java
index 5c3c10146..20ea96cc9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppBlacklistActivity.java
@@ -31,7 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.AppBlacklistAdapter;
-public class AppBlacklistActivity extends GBActivity {
+public class AppBlacklistActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(AppBlacklistActivity.class);
private AppBlacklistAdapter appBlacklistAdapter;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java
index 15307a32c..54e4ae15e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java
@@ -47,7 +47,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
-public class CalBlacklistActivity extends GBActivity {
+public class CalBlacklistActivity extends AbstractGBActivity {
private final String[] EVENT_PROJECTION = new String[]{
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
index 584ac07da..3528c82be 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
@@ -38,7 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ALARMS;
-public class ConfigureAlarms extends GBActivity {
+public class ConfigureAlarms extends AbstractGBActivity {
private static final int REQ_CONFIGURE_ALARM = 1;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java
index 7e889efa1..377663d83 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java
@@ -62,9 +62,9 @@ import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
-//TODO: extend GBActivity, but it requires actionbar that is not available
+//TODO: extend AbstractGBActivity, but it requires actionbar that is not available
public class ControlCenterv2 extends AppCompatActivity
- implements NavigationView.OnNavigationItemSelectedListener {
+ implements NavigationView.OnNavigationItemSelectedListener, GBActivity {
//needed for KK compatibility
static {
@@ -84,7 +84,7 @@ public class ControlCenterv2 extends AppCompatActivity
String action = intent.getAction();
switch (action) {
case GBApplication.ACTION_LANGUAGE_CHANGE:
- setLanguage(GBApplication.getLanguage());
+ setLanguage(GBApplication.getLanguage(), true);
break;
case GBApplication.ACTION_QUIT:
finish();
@@ -98,11 +98,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
- if (GBApplication.isDarkThemeEnabled()) {
- setTheme(R.style.GadgetbridgeThemeDark_NoActionBar);
- } else {
- setTheme(R.style.GadgetbridgeTheme_NoActionBar);
- }
+ AbstractGBActivity.init(this, AbstractGBActivity.NO_ACTIONBAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controlcenterv2);
@@ -315,7 +311,7 @@ public class ControlCenterv2 extends AppCompatActivity
ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[wantedPermissions.size()]), 0);
}
- private void setLanguage(Locale language) {
- AndroidUtils.setLanguage(this, language);
+ public void setLanguage(Locale language, boolean recreate) {
+ AndroidUtils.setLanguage(this, language, recreate);
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java
index 2085f7615..782f43a24 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DbManagementActivity.java
@@ -45,7 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.ImportExportSharedPreferences;
-public class DbManagementActivity extends GBActivity {
+public class DbManagementActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(DbManagementActivity.class);
private static SharedPreferences sharedPrefs;
private ImportExportSharedPreferences shared_file = new ImportExportSharedPreferences();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java
index a88df172e..03e3cecdf 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java
@@ -53,7 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
-public class DebugActivity extends GBActivity {
+public class DebugActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class);
private static final String EXTRA_REPLY = "reply";
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
index 6c80cf76a..b7af301cf 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
@@ -69,7 +69,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
import static android.bluetooth.le.ScanSettings.MATCH_MODE_STICKY;
import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_LATENCY;
-public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemClickListener {
+public class DiscoveryActivity extends AbstractGBActivity implements AdapterView.OnItemClickListener {
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
private static final long SCAN_DURATION = 60000; // 60s
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java
index cc70d4f7c..ca4790eb0 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java
@@ -40,7 +40,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton;
-public class ExternalPebbleJSActivity extends GBActivity {
+public class ExternalPebbleJSActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(ExternalPebbleJSActivity.class);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java
index f1f5ac229..28b57e464 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java
@@ -51,7 +51,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
-public class FwAppInstallerActivity extends GBActivity implements InstallActivity {
+public class FwAppInstallerActivity extends AbstractGBActivity implements InstallActivity {
private static final Logger LOG = LoggerFactory.getLogger(FwAppInstallerActivity.class);
private static final String ITEM_DETAILS = "details";
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java
index 09246d6dc..7600c8f66 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/GBActivity.java
@@ -1,80 +1,9 @@
-/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
-
- 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 . */
package nodomain.freeyourgadget.gadgetbridge.activities;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.LocaleList;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.app.AppCompatActivity;
-
import java.util.Locale;
-import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
-import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
-import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
+public interface GBActivity {
+ void setLanguage(Locale language, boolean recreate);
+ void setTheme(int themeId);
-
-public class GBActivity extends AppCompatActivity {
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- switch (action) {
- case GBApplication.ACTION_LANGUAGE_CHANGE:
- setLanguage(GBApplication.getLanguage());
- break;
- case GBApplication.ACTION_QUIT:
- finish();
- break;
- }
- }
- };
-
- private void setLanguage(Locale language) {
- AndroidUtils.setLanguage(this, language);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- IntentFilter filterLocal = new IntentFilter();
- filterLocal.addAction(GBApplication.ACTION_QUIT);
- filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
- LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
-
- if (GBApplication.isDarkThemeEnabled()) {
- setTheme(R.style.GadgetbridgeThemeDark);
- } else {
- setTheme(R.style.GadgetbridgeTheme);
- }
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void onDestroy() {
- LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
- super.onDestroy();
- }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java
index ea92116a6..076d8d1c3 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/VibrationActivity.java
@@ -26,7 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
-public class VibrationActivity extends GBActivity {
+public class VibrationActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(VibrationActivity.class);
private SeekBar seekBar;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
index deed2c2e0..4e49ae911 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
@@ -37,7 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
-import nodomain.freeyourgadget.gadgetbridge.activities.GBActivity;
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
@@ -46,7 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
-public class MiBandPairingActivity extends GBActivity {
+public class MiBandPairingActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(MiBandPairingActivity.class);
private static final int REQ_CODE_USER_SETTINGS = 52;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java
new file mode 100644
index 000000000..e839955e0
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Constants.java
@@ -0,0 +1,31 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.no1f1;
+
+import java.util.UUID;
+
+public final class No1F1Constants {
+
+ public static final UUID UUID_CHARACTERISTIC_CONTROL = UUID.fromString("000033f1-0000-1000-8000-00805f9b34fb");
+ public static final UUID UUID_CHARACTERISTIC_MEASURE = UUID.fromString("000033f2-0000-1000-8000-00805f9b34fb");
+ public static final UUID UUID_SERVICE_NO1 = UUID.fromString("000055ff-0000-1000-8000-00805f9b34fb");
+
+ public static final byte CMD_DISPLAY_SETTINGS = (byte) 0xa0;
+ public static final byte CMD_FIRMWARE_VERSION = (byte) 0xa1;
+ public static final byte CMD_BATTERY = (byte) 0xa2;
+ public static final byte CMD_DATETIME = (byte) 0xa3;
+ public static final byte CMD_USER_DATA = (byte) 0xa9;
+ public static final byte CMD_ALARM = (byte) 0xab;
+ public static final byte CMD_FACTORY_RESET = (byte) 0xad;
+ public static final byte CMD_NOTIFICATION = (byte) 0xc1;
+ public static final byte CMD_ICON = (byte) 0xc3;
+ public static final byte CMD_DEVICE_SETTINGS = (byte) 0xd3;
+ public static final byte CMD_HEARTRATE_SETTINGS = (byte) 0xd6;
+
+ public static final byte NOTIFICATION_HEADER = (byte) 0x01;
+ public static final byte NOTIFICATION_CALL = (byte) 0x02;
+ public static final byte NOTIFICATION_SMS = (byte) 0x03;
+ public static final byte NOTIFICATION_STOP = (byte) 0x04; // to stop showing incoming call
+
+ public static final byte ICON_QQ = (byte) 0x01;
+ public static final byte ICON_WECHAT = (byte) 0x02;
+ public static final byte ICON_ALARM = (byte) 0x04;
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java
new file mode 100644
index 000000000..bb51683a6
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java
@@ -0,0 +1,140 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.no1f1;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.bluetooth.le.ScanFilter;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Build;
+import android.os.ParcelUuid;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import nodomain.freeyourgadget.gadgetbridge.GBException;
+import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
+import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
+import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
+import nodomain.freeyourgadget.gadgetbridge.entities.Device;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
+import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
+
+public class No1F1Coordinator extends AbstractDeviceCoordinator {
+
+ @NonNull
+ @Override
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public Collection extends ScanFilter> createBLEScanFilters() {
+ ParcelUuid hpService = new ParcelUuid(No1F1Constants.UUID_SERVICE_NO1);
+ ScanFilter filter = new ScanFilter.Builder().setServiceUuid(hpService).build();
+ return Collections.singletonList(filter);
+ }
+
+ @NonNull
+ @Override
+ public DeviceType getSupportedType(GBDeviceCandidate candidate) {
+ String name = candidate.getDevice().getName();
+ if (name != null && name.startsWith("X-RUN")) {
+ return DeviceType.NO1F1;
+ }
+
+ return DeviceType.UNKNOWN;
+ }
+
+ @Override
+ public DeviceType getDeviceType() {
+ return DeviceType.NO1F1;
+ }
+
+ @Override
+ public int getBondingStyle(GBDevice deviceCandidate) {
+ return BONDING_STYLE_NONE;
+ }
+
+ @Nullable
+ @Override
+ public Class extends Activity> getPairingActivity() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Class extends Activity> getPrimaryActivity() {
+ return null;
+ }
+
+ @Override
+ public boolean supportsActivityDataFetching() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsActivityTracking() {
+ return false;
+ }
+
+ @Override
+ public SampleProvider extends ActivitySample> getSampleProvider(GBDevice device, DaoSession session) {
+ return null;
+ }
+
+ @Override
+ public InstallHandler findInstallHandler(Uri uri, Context context) {
+ return null;
+ }
+
+ @Override
+ public boolean supportsScreenshots() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsAlarmConfiguration() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSmartWakeup(GBDevice device) {
+ return false;
+ }
+
+ @Override
+ public boolean supportsHeartRateMeasurement(GBDevice device) {
+ return false;
+ }
+
+ @Override
+ public String getManufacturer() {
+ return "NO1";
+ }
+
+ @Override
+ public boolean supportsAppsManagement() {
+ return false;
+ }
+
+ @Override
+ public Class extends Activity> getAppsManagementActivity() {
+ return null;
+ }
+
+ @Override
+ public boolean supportsCalendarEvents() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsRealtimeData() {
+ return false;
+ }
+
+ @Override
+ protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
+
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
index f7823a01e..30d0b6d39 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
@@ -38,7 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
-import nodomain.freeyourgadget.gadgetbridge.activities.GBActivity;
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
@@ -50,7 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
-public class PebblePairingActivity extends GBActivity {
+public class PebblePairingActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(PebblePairingActivity.class);
private TextView message;
private boolean isPairing;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java
index d7caa1e8a..93e4dcb2c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/WeatherNotificationConfig.java
@@ -19,9 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents;
import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.GBActivity;
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
-public class WeatherNotificationConfig extends GBActivity {
+public class WeatherNotificationConfig extends AbstractGBActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java
index f1c095b11..2444aabcc 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java
@@ -61,6 +61,7 @@ public class GBDevice implements Parcelable {
private static final String DEVINFO_HW_VER = "HW: ";
private static final String DEVINFO_FW_VER = "FW: ";
private static final String DEVINFO_HR_VER = "HR: ";
+ private static final String DEVINFO_GPS_VER = "GPS: ";
private static final String DEVINFO_ADDR = "ADDR: ";
private static final String DEVINFO_ADDR2 = "ADDR2: ";
private String mName;
@@ -165,7 +166,7 @@ public class GBDevice implements Parcelable {
}
/**
- * Sets the second firmware version, typically the heart rate firmware version
+ * Sets the second firmware version (HR or GPS or other component)
* @param firmwareVersion2
*/
public void setFirmwareVersion2(String firmwareVersion2) {
@@ -445,7 +446,12 @@ public class GBDevice implements Parcelable {
result.add(new GenericItem(DEVINFO_FW_VER, mFirmwareVersion));
}
if (mFirmwareVersion2 != null) {
- result.add(new GenericItem(DEVINFO_HR_VER, mFirmwareVersion2));
+ // FIXME: thats ugly
+ if (mDeviceType == DeviceType.AMAZFITBIP) {
+ result.add(new GenericItem(DEVINFO_GPS_VER, mFirmwareVersion2));
+ } else {
+ result.add(new GenericItem(DEVINFO_HR_VER, mFirmwareVersion2));
+ }
}
if (mAddress != null) {
result.add(new GenericItem(DEVINFO_ADDR, mAddress));
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
index 209666250..d543f913d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -37,6 +37,7 @@ public enum DeviceType {
LIVEVIEW(30, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled),
HPLUS(40, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled),
MAKIBESF68(41, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled),
+ NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled),
TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled);
private final int key;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java
index a8ae4616a..24e014b9e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java
@@ -229,7 +229,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
- shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(fullpath)));
+ shareIntent.putExtra(Intent.EXTRA_STREAM, screenshotURI);
PendingIntent pendingShareIntent = PendingIntent.getActivity(context, 0, Intent.createChooser(shareIntent, "share screenshot"),
PendingIntent.FLAG_UPDATE_CURRENT);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
index cf4d77664..73e89821e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
@@ -189,7 +189,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
"net.sourceforge.subsonic.androidapp.EVENT_META_CHANGED",
"com.maxmpz.audioplayer.TPOS_SYNC",
"com.maxmpz.audioplayer.STATUS_CHANGED",
- "com.maxmpz.audioplayer.PLAYING_MODE_CHANGED"};
+ "com.maxmpz.audioplayer.PLAYING_MODE_CHANGED",
+ "com.spotify.music.metadatachanged",
+ "com.spotify.music.playbackstatechanged"
+ };
/**
* For testing!
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
index 86a8f0a74..f17a5eec8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
@@ -32,6 +32,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSup
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.MiBand2Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.AmazfitBipSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.no1f1.No1F1Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.vibratissimo.VibratissimoSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusSupport;
@@ -125,6 +126,9 @@ public class DeviceSupportFactory {
case MAKIBESF68:
deviceSupport = new ServiceDeviceSupport(new HPlusSupport(DeviceType.MAKIBESF68), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
break;
+ case NO1F1:
+ deviceSupport = new ServiceDeviceSupport(new No1F1Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
+ break;
}
if (deviceSupport != null) {
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java
index 1c64f025c..3b9e847ab 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEOperation.java
@@ -85,6 +85,9 @@ public abstract class AbstractBTLEOperation
* You MUST call this method when the operation has finished, either
* successfully or unsuccessfully.
*
+ * Subclasses must ensure that the {@link BtLEQueue queue's}'s gatt callback (set on the transaction builder by {@link #performInitialized(String)})
+ * is being unset, otherwise it will continue to receive events until another transaction is being executed by the queue.
+ *
* @throws IOException
*/
protected void operationFinished() throws IOException {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java
index c0e46acea..587c8da71 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/deviceinfo/DeviceInfoProfile.java
@@ -110,49 +110,49 @@ public class DeviceInfoProfile extends Abst
private void handleManufacturerName(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String name = characteristic.getStringValue(0);
+ String name = characteristic.getStringValue(0).trim();
deviceInfo.setManufacturerName(name);
notify(createIntent(deviceInfo));
}
private void handleModelNumber(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String modelNumber = characteristic.getStringValue(0);
+ String modelNumber = characteristic.getStringValue(0).trim();
deviceInfo.setModelNumber(modelNumber);
notify(createIntent(deviceInfo));
}
private void handleSerialNumber(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String serialNumber = characteristic.getStringValue(0);
+ String serialNumber = characteristic.getStringValue(0).trim();
deviceInfo.setSerialNumber(serialNumber);
notify(createIntent(deviceInfo));
}
private void handleHardwareRevision(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String hardwareRevision = characteristic.getStringValue(0);
+ String hardwareRevision = characteristic.getStringValue(0).trim();
deviceInfo.setHardwareRevision(hardwareRevision);
notify(createIntent(deviceInfo));
}
private void handleFirmwareRevision(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String firmwareRevision = characteristic.getStringValue(0);
+ String firmwareRevision = characteristic.getStringValue(0).trim();
deviceInfo.setFirmwareRevision(firmwareRevision);
notify(createIntent(deviceInfo));
}
private void handleSoftwareRevision(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String softwareRevision = characteristic.getStringValue(0);
+ String softwareRevision = characteristic.getStringValue(0).trim();
deviceInfo.setSoftwareRevision(softwareRevision);
notify(createIntent(deviceInfo));
}
private void handleSystemId(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- String systemId = characteristic.getStringValue(0);
+ String systemId = characteristic.getStringValue(0).trim();
deviceInfo.setSystemId(systemId);
notify(createIntent(deviceInfo));
}
private void handleRegulatoryCertificationData(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// TODO: regulatory certification data list not supported yet
-// String regulatoryCertificationData = characteristic.getStringValue(0);
+// String regulatoryCertificationData = characteristic.getStringValue(0).trim();
// deviceInfo.setRegulatoryCertificationDataList(regulatoryCertificationData);
// notify(createIntent(deviceInfo));
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java
index fe23fa7c2..23b2f37bb 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipSupport.java
@@ -89,6 +89,10 @@ public class AmazfitBipSupport extends MiBand2Support {
if (notificationSpec.type == NotificationType.GENERIC_SMS) {
alertCategory = AlertCategory.SMS;
}
+ // EMAIL icon does not work in FW 0.0.8.74, it did in 0.0.7.90
+ else if (notificationSpec.type == NotificationType.GENERIC_EMAIL) {
+ alertCategory = AlertCategory.Email;
+ }
NewAlert alert = new NewAlert(alertCategory, 1, message, customIconId);
profile.newAlert(builder, alert);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipTextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipTextNotificationStrategy.java
index d7c9fac61..866f2f30b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipTextNotificationStrategy.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/AmazfitBipTextNotificationStrategy.java
@@ -40,7 +40,7 @@ class AmazfitBipTextNotificationStrategy extends Mi2TextNotificationStrategy {
@Override
protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
- if (simpleNotification != null && !StringUtils.isEmpty(simpleNotification.getMessage())) {
+ if (simpleNotification != null) {
sendAlert(simpleNotification, builder);
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java
index a27c7ef08..48317d550 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/amazfitbip/operations/AmazfitBipUpdateFirmwareOperation.java
@@ -16,34 +16,24 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.operations;
+import android.content.Context;
import android.net.Uri;
-import android.widget.Toast;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.devices.amazfitbip.AmazfitBipFWHelper;
import nodomain.freeyourgadget.gadgetbridge.service.devices.amazfitbip.AmazfitBipSupport;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.Mi2FirmwareInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.UpdateFirmwareOperation;
-import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class AmazfitBipUpdateFirmwareOperation extends UpdateFirmwareOperation {
public AmazfitBipUpdateFirmwareOperation(Uri uri, AmazfitBipSupport support) {
super(uri, support);
}
- @Override
- protected void doPerform() throws IOException {
- AmazfitBipFWHelper mFwHelper = new AmazfitBipFWHelper(uri, getContext());
- firmwareInfo = mFwHelper.getFirmwareInfo();
- if (!firmwareInfo.isGenerallyCompatibleWith(getDevice())) {
- throw new IOException("Firmware is not compatible with the given device: " + getDevice().getAddress());
- }
-
- if (!sendFwInfo()) {
- displayMessage(getContext(), "Error sending firmware info, aborting.", Toast.LENGTH_LONG, GB.ERROR);
- done();
- }
- //the firmware will be sent by the notification listener if the band confirms that the metadata are ok.
+ protected Mi2FirmwareInfo createFwInfo(Uri uri, Context context) throws IOException {
+ AmazfitBipFWHelper fwHelper = new AmazfitBipFWHelper(uri, getContext());
+ return fwHelper.getFirmwareInfo();
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java
index 2c1180e34..4dacf9fb0 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/AbstractMiBandOperation.java
@@ -48,6 +48,7 @@ public abstract class AbstractMiBandOperation alarms) {
+
+ }
+
+ @Override
+ public void onSetCallState(CallSpec callSpec) {
+ if (callSpec.command == CallSpec.CALL_INCOMING) {
+ showNotification(No1F1Constants.NOTIFICATION_CALL, callSpec.name, callSpec.number);
+ setVibration(3, 5);
+ } else {
+ stopNotification();
+ setVibration(0, 0);
+ }
+ }
+
+ @Override
+ public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
+
+ }
+
+ @Override
+ public void onSetMusicState(MusicStateSpec stateSpec) {
+
+ }
+
+ @Override
+ public void onSetMusicInfo(MusicSpec musicSpec) {
+
+ }
+
+ @Override
+ public void onEnableRealtimeSteps(boolean enable) {
+
+ }
+
+ @Override
+ public void onInstallApp(Uri uri) {
+
+ }
+
+ @Override
+ public void onAppInfoReq() {
+
+ }
+
+ @Override
+ public void onAppStart(UUID uuid, boolean start) {
+
+ }
+
+ @Override
+ public void onAppDelete(UUID uuid) {
+
+ }
+
+ @Override
+ public void onAppConfiguration(UUID appUuid, String config) {
+
+ }
+
+ @Override
+ public void onAppReorder(UUID[] uuids) {
+
+ }
+
+ @Override
+ public void onFetchActivityData() {
+
+ }
+
+ @Override
+ public void onReboot() {
+ try {
+ TransactionBuilder builder = performInitialized("clearNotification");
+ byte[] msg = new byte[]{
+ (byte) 0xad
+ };
+ builder.write(ctrlCharacteristic, msg);
+ performConnected(builder.getTransaction());
+ } catch (IOException e) {
+ }
+ }
+
+ @Override
+ public void onHeartRateTest() {
+
+ }
+
+ @Override
+ public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
+
+ }
+
+ @Override
+ public void onFindDevice(boolean start) {
+ if (start)
+ setVibration(3, 10);
+ else
+ setVibration(0, 0);
+ }
+
+ @Override
+ public void onSetConstantVibration(int integer) {
+
+ }
+
+ @Override
+ public void onScreenshotReq() {
+
+ }
+
+ @Override
+ public void onEnableHeartRateSleepSupport(boolean enable) {
+
+ }
+
+ @Override
+ public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
+
+ }
+
+ @Override
+ public void onDeleteCalendarEvent(byte type, long id) {
+
+ }
+
+ @Override
+ public void onSendConfiguration(String config) {
+
+ }
+
+ @Override
+ public void onTestNewFunction() {
+
+ }
+
+ @Override
+ public void onSendWeather(WeatherSpec weatherSpec) {
+
+ }
+
+ @Override
+ public boolean useAutoConnect() {
+ return true;
+ }
+
+ private void sendSettings(TransactionBuilder builder) {
+ // TODO Create custom settings page for changing hardcoded values
+
+ // set date and time
+ Calendar c = GregorianCalendar.getInstance();
+ byte[] datetimeBytes = new byte[]{
+ No1F1Constants.CMD_DATETIME,
+ (byte) ((c.get(Calendar.YEAR) / 256) & 0xff),
+ (byte) (c.get(Calendar.YEAR) % 256),
+ (byte) (c.get(Calendar.MONTH) + 1),
+ (byte) c.get(Calendar.DAY_OF_MONTH),
+ (byte) c.get(Calendar.HOUR_OF_DAY),
+ (byte) c.get(Calendar.MINUTE),
+ (byte) c.get(Calendar.SECOND)
+ };
+ builder.write(ctrlCharacteristic, datetimeBytes);
+
+ // set user data
+ ActivityUser activityUser = new ActivityUser();
+ byte[] userBytes = new byte[]{
+ No1F1Constants.CMD_USER_DATA,
+ 0,
+ (byte) Math.round(activityUser.getHeightCm() * 0.43), // step length in cm
+ 0,
+ (byte) activityUser.getWeightKg(),
+ 5, // screen on time
+ 0,
+ 0,
+ (byte) (activityUser.getStepsGoal() / 256),
+ (byte) (activityUser.getStepsGoal() % 256),
+ 1, // unknown
+ (byte) 0xff, // unknown
+ 0,
+ (byte) activityUser.getAge(),
+ 0
+ };
+ if (activityUser.getGender() == ActivityUser.GENDER_FEMALE)
+ userBytes[14] = 2; // female
+ else
+ userBytes[14] = 1; // male
+
+ builder.write(ctrlCharacteristic, userBytes);
+
+ // more settings
+ builder.write(ctrlCharacteristic, new byte[]{
+ No1F1Constants.CMD_DEVICE_SETTINGS,
+ 0x00, // 1 - turns on inactivity alarm
+ 0x3c,
+ 0x02,
+ 0x03,
+ 0x01,
+ 0x00
+ });
+
+ // display settings
+ builder.write(ctrlCharacteristic, new byte[]{
+ No1F1Constants.CMD_DISPLAY_SETTINGS,
+ 0x01, // 1 - display distance in kilometers, 2 - in miles
+ 0x01 // 1 - display 24-hour clock, 2 - for 12-hour with AM/PM
+ });
+
+ // heart rate measurement mode
+ builder.write(ctrlCharacteristic, new byte[]{
+ No1F1Constants.CMD_HEARTRATE_SETTINGS,
+ 0x02, // 1 - static (measure for 15 seconds), 2 - realtime
+ });
+
+ // periodic heart rate measurement
+ builder.write(ctrlCharacteristic, new byte[]{
+ No1F1Constants.CMD_HEARTRATE_SETTINGS,
+ 0x01,
+ 0x02 // measure heart rate every 2 hours (0 to turn off)
+ });
+ }
+
+ private void setVibration(int duration, int count) {
+ try {
+ TransactionBuilder builder = performInitialized("vibrate");
+ byte[] msg = new byte[]{
+ No1F1Constants.CMD_ALARM,
+ 0,
+ 0,
+ 0,
+ (byte) duration,
+ (byte) count,
+ 2,
+ 1
+ };
+ builder.write(ctrlCharacteristic, msg);
+ performConnected(builder.getTransaction());
+ } catch (IOException e) {
+ }
+ }
+
+ private void showIcon(int iconId) {
+ try {
+ TransactionBuilder builder = performInitialized("showIcon");
+ byte[] msg = new byte[]{
+ No1F1Constants.CMD_ICON,
+ (byte) iconId
+ };
+ builder.write(ctrlCharacteristic, msg);
+ performConnected(builder.getTransaction());
+ } catch (IOException e) {
+ }
+ }
+
+ private void showNotification(int type, String header, String body) {
+ try {
+ // TODO Add transliteration.
+ TransactionBuilder builder = performInitialized("showNotification");
+ int length;
+ byte[] bytes;
+ byte[] msg;
+
+ // send header
+ bytes = header.toString().getBytes("EUC-JP");
+ length = min(bytes.length, 18);
+ msg = new byte[length + 2];
+ msg[0] = No1F1Constants.CMD_NOTIFICATION;
+ msg[1] = No1F1Constants.NOTIFICATION_HEADER;
+ System.arraycopy(bytes, 0, msg, 2, length);
+ builder.write(ctrlCharacteristic, msg);
+
+ // send body
+ bytes = header.toString().getBytes("EUC-JP");
+ length = min(bytes.length, 18);
+ msg = new byte[length + 2];
+ msg[0] = No1F1Constants.CMD_NOTIFICATION;
+ msg[1] = (byte) type;
+ System.arraycopy(bytes, 0, msg, 2, length);
+ builder.write(ctrlCharacteristic, msg);
+
+ performConnected(builder.getTransaction());
+ } catch (IOException e) {
+ }
+ }
+
+ private void stopNotification() {
+ try {
+ TransactionBuilder builder = performInitialized("clearNotification");
+ byte[] msg = new byte[]{
+ No1F1Constants.CMD_NOTIFICATION,
+ No1F1Constants.NOTIFICATION_STOP
+ };
+ builder.write(ctrlCharacteristic, msg);
+ performConnected(builder.getTransaction());
+ } catch (IOException e) {
+ }
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java
index a3258b19f..06bafd277 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AndroidUtils.java
@@ -70,13 +70,20 @@ public class AndroidUtils {
}
}
- public static void setLanguage(Activity activity, Locale language) {
+ public static void setLanguage(Activity activity, Locale language, boolean recreate) {
+ setLanguage(activity.getBaseContext(), language);
+
+ if (recreate) {
+ activity.recreate();
+ }
+ }
+
+ public static void setLanguage(Context context, Locale language) {
Configuration config = new Configuration();
config.setLocale(language);
// FIXME: I have no idea what I am doing
- activity.getBaseContext().getResources().updateConfiguration(config, activity.getBaseContext().getResources().getDisplayMetrics());
- activity.recreate();
+ context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
/**
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
index d2c81d20e..e3241d6a6 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
@@ -46,6 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.vibratissimo.VibratissimoCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
@@ -192,6 +193,7 @@ public class DeviceHelper {
result.add(new VibratissimoCoordinator());
result.add(new LiveviewCoordinator());
result.add(new HPlusCoordinator());
+ result.add(new No1F1Coordinator());
result.add(new MakibesF68Coordinator());
return result;
diff --git a/app/src/main/res/drawable/level_list_device.xml b/app/src/main/res/drawable/level_list_device.xml
index 9347fd997..eb68abe6e 100644
--- a/app/src/main/res/drawable/level_list_device.xml
+++ b/app/src/main/res/drawable/level_list_device.xml
@@ -9,6 +9,7 @@
+
@@ -19,5 +20,6 @@
+
\ No newline at end of file