1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-28 04:46:51 +01:00

Fossil Hybrid HR: option to force white background

Currently needs reconnect and one change to the widget configuration to be effective.

This might improve visiblity of the hands when using a model with gray hands
This commit is contained in:
Andreas Shimokawa 2020-02-27 13:36:53 +01:00
parent 335c37795c
commit ddd70f93fc
9 changed files with 83 additions and 53 deletions

View File

@ -21,17 +21,17 @@ import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanFilter;
import androidx.annotation.NonNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import androidx.annotation.NonNull;
import de.greenrobot.dao.query.QueryBuilder; import de.greenrobot.dao.query.QueryBuilder;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
@ -41,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributesDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getPrefs; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getPrefs;
public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
@ -177,7 +178,6 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
@Override @Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) { public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[] {R.xml.devicesettings_pairingkey }; return null;
} }
} }

View File

@ -205,7 +205,7 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
for (int i = 0; i < customWidgets.length(); i++) { for (int i = 0; i < customWidgets.length(); i++) {
JSONObject customWidgetObject = customWidgets.getJSONObject(i); JSONObject customWidgetObject = customWidgets.getJSONObject(i);
CustomWidget widget = new CustomWidget( CustomWidget widget = new CustomWidget(
customWidgetObject.getString("name"), 0, 0 customWidgetObject.getString("name"), 0, 0, "default" // FIXME: handle force white background
); );
JSONArray elements = customWidgetObject.getJSONArray("elements"); JSONArray elements = customWidgetObject.getJSONArray("elements");

View File

@ -19,26 +19,22 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanFilter;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.ParcelUuid; import android.os.ParcelUuid;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.Collection;
import java.util.Collections;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
@ -48,9 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails; import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public class QHybridCoordinator extends AbstractDeviceCoordinator { public class QHybridCoordinator extends AbstractDeviceCoordinator {
@NonNull @NonNull
@ -113,7 +107,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
return false; return false;
} }
public boolean supportsAlarmConfiguration() { private boolean supportsAlarmConfiguration() {
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){ if(connectedDevice == null || connectedDevice.getType() != DeviceType.FOSSILQHYBRID || connectedDevice.getState() != GBDevice.State.INITIALIZED){
return false; return false;
@ -136,8 +130,6 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
return false; return false;
} }
@Override @Override
public String getManufacturer() { public String getManufacturer() {
return "Fossil"; return "Fossil";
@ -150,9 +142,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
@Override @Override
public Class<? extends Activity> getAppsManagementActivity() { public Class<? extends Activity> getAppsManagementActivity() {
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice(); return isHybridHR() ? HRConfigActivity.class : ConfigActivity.class;
boolean isHR = connectedDevice.getFirmwareVersion().charAt(2) == '1';
return isHR ? HRConfigActivity.class : ConfigActivity.class;
} }
@Override @Override
@ -167,7 +157,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
@Override @Override
public boolean supportsWeather() { public boolean supportsWeather() {
return true; // FIXME: not for old Q? return isHybridHR();
} }
@Override @Override
@ -188,5 +178,24 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
} }
@Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
if (isHybridHR()) {
return new int[]{
R.xml.devicesettings_fossilhybridhr,
R.xml.devicesettings_pairingkey
};
}
return new int[]{
R.xml.devicesettings_pairingkey
};
}
private boolean isHybridHR() {
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
if (connectedDevice != null) {
return connectedDevice.getName().startsWith("Hybrid HR");
}
return false;
}
} }

View File

@ -1,32 +1,26 @@
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.RadioGroup; import android.widget.RadioGroup;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.Widget;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomBackgroundWidgetElement;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomTextWidgetElement;
@ -56,7 +50,7 @@ public class WidgetSettingsActivity extends AbstractGBActivity {
((EditText) findViewById(R.id.qhybrid_widget_name)).setText(subject.getName()); ((EditText) findViewById(R.id.qhybrid_widget_name)).setText(subject.getName());
resultCode = RESULT_CODE_WIDGET_UPDATED; resultCode = RESULT_CODE_WIDGET_UPDATED;
}else{ }else{
subject = new CustomWidget("", 0, 63); subject = new CustomWidget("", 0, 63, "default"); // FIXME: handle force white background
resultCode = RESULT_CODE_WIDGET_CREATED; resultCode = RESULT_CODE_WIDGET_CREATED;
findViewById(R.id.qhybrid_widget_delete).setEnabled(false); findViewById(R.id.qhybrid_widget_delete).setEnabled(false);
} }

View File

@ -67,6 +67,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST; import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST;
@ -76,9 +77,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
private byte[] phoneRandomNumber; private byte[] phoneRandomNumber;
private byte[] watchRandomNumber; private byte[] watchRandomNumber;
ArrayList<Widget> widgets = new ArrayList<>(); private ArrayList<Widget> widgets = new ArrayList<>();
NotificationHRConfiguration[] notificationConfigurations; private NotificationHRConfiguration[] notificationConfigurations;
private MusicSpec currentSpec = null; private MusicSpec currentSpec = null;
@ -136,18 +137,29 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} }
private void loadBackground(){ private void loadBackground(){
/*Bitmap backgroundBitmap = BitmapFactory Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()));
.decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg"); boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false);
if (forceWhiteBackground) {
byte[] whiteGIF = new byte[]{
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00, 0x01, 0x00, (byte) 0x80, 0x01, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3B
};
try { Bitmap backgroundBitmap = BitmapFactory.decodeByteArray(whiteGIF, 0, whiteGIF.length);
this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0,:wq //Bitmap backgroundBitmap = BitmapFactory.decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg");
0, 0);
} catch (IOException e) { try {
GB.log("Backgroundimage error", GB.ERROR, e); this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0, 0, 0);
}*/ } catch (IOException e) {
logger.error("Backgroundimage error", e);
}
}
} }
private void loadWidgets() { private void loadWidgets() {
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()));
boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false);
String fontColor = forceWhiteBackground ? "black" : "default";
this.widgets.clear(); this.widgets.clear();
String widgetJson = GBApplication.getPrefs().getPreferences().getString("FOSSIL_HR_WIDGETS", "{}"); String widgetJson = GBApplication.getPrefs().getPreferences().getString("FOSSIL_HR_WIDGETS", "{}");
String customWidgetJson = GBApplication.getPrefs().getString("QHYBRID_CUSTOM_WIDGETS", "[]"); String customWidgetJson = GBApplication.getPrefs().getString("QHYBRID_CUSTOM_WIDGETS", "[]");
@ -170,7 +182,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
Widget widget = null; Widget widget = null;
if(type != null) { if(type != null) {
widget = new Widget(type, positionMap.get(position), 63); widget = new Widget(type, positionMap.get(position), 63, fontColor);
}else{ }else{
identifier = identifier.substring(7); identifier = identifier.substring(7);
for(int i = 0; i < customWidgets.length(); i++){ for(int i = 0; i < customWidgets.length(); i++){
@ -179,7 +191,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
CustomWidget newWidget = new CustomWidget( CustomWidget newWidget = new CustomWidget(
customWidget.getString("name"), customWidget.getString("name"),
positionMap.get(position), positionMap.get(position),
63 63,
fontColor
); );
JSONArray elements = customWidget.getJSONArray("elements"); JSONArray elements = customWidget.getJSONArray("elements");
@ -224,6 +237,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} }
private void renderWidgets() { private void renderWidgets() {
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()));
boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false);
try { try {
ArrayList<AssetImage> widgetImages = new ArrayList<>(); ArrayList<AssetImage> widgetImages = new ArrayList<>();
@ -245,12 +260,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
Paint circlePaint = new Paint(); Paint circlePaint = new Paint();
if(!backgroundDrawn){ if(!backgroundDrawn){
circlePaint.setColor(Color.BLACK); circlePaint.setColor(forceWhiteBackground ? Color.WHITE : Color.BLACK);
circlePaint.setStyle(Paint.Style.FILL); circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setStrokeWidth(3); circlePaint.setStrokeWidth(3);
widgetCanvas.drawCircle(38, 38, 37, circlePaint); widgetCanvas.drawCircle(38, 38, 37, circlePaint);
circlePaint.setColor(Color.WHITE); circlePaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE);
circlePaint.setStyle(Paint.Style.STROKE); circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeWidth(3); circlePaint.setStrokeWidth(3);
widgetCanvas.drawCircle(38, 38, 37, circlePaint); widgetCanvas.drawCircle(38, 38, 37, circlePaint);
@ -287,7 +302,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
textPaint.setStrokeWidth(4); textPaint.setStrokeWidth(4);
textPaint.setTextSize(17f); textPaint.setTextSize(17f);
textPaint.setStyle(Paint.Style.FILL); textPaint.setStyle(Paint.Style.FILL);
textPaint.setColor(Color.WHITE); textPaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE);
textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextAlign(Paint.Align.CENTER);
widgetCanvas.drawText(element.getValue(), element.getX(), element.getY() - (textPaint.descent() + textPaint.ascent()) / 2f, textPaint); widgetCanvas.drawText(element.getValue(), element.getX(), element.getY() - (textPaint.descent() + textPaint.ascent()) / 2f, textPaint);

View File

@ -10,8 +10,8 @@ public class CustomWidget extends Widget {
private int angle, distance; private int angle, distance;
private String name; private String name;
public CustomWidget(String name, int angle, int distance) { public CustomWidget(String name, int angle, int distance, String fontColor) {
super(null, angle, distance); super(null, angle, distance, fontColor);
this.angle = angle; this.angle = angle;
this.distance = distance; this.distance = distance;
this.name = name; this.name = name;

View File

@ -11,12 +11,14 @@ import nodomain.freeyourgadget.gadgetbridge.R;
public class Widget implements Serializable { public class Widget implements Serializable {
private WidgetType widgetType; private WidgetType widgetType;
int angle, distance; private int angle, distance;
private String fontColor;
public Widget(WidgetType type, int angle, int distance) { public Widget(WidgetType type, int angle, int distance, String fontColor) {
this.widgetType = type; this.widgetType = type;
this.angle = angle; this.angle = angle;
this.distance = distance; this.distance = distance;
this.fontColor = fontColor;
} }
@NonNull @NonNull
@ -39,7 +41,7 @@ public class Widget implements Serializable {
.put("data", new JSONObject()) .put("data", new JSONObject())
.put("theme", .put("theme",
new JSONObject() new JSONObject()
.put("font_color", "default") .put("font_color", fontColor)
); );
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -496,6 +496,8 @@
<string name="mi3_prefs_band_screen_unlock_summary">Swipe up to unlock the band\'s screen</string> <string name="mi3_prefs_band_screen_unlock_summary">Swipe up to unlock the band\'s screen</string>
<string name="mi3_prefs_night_mode">Night mode</string> <string name="mi3_prefs_night_mode">Night mode</string>
<string name="mi3_prefs_night_mode_summary">Lower band screen brightness automatically at night</string> <string name="mi3_prefs_night_mode_summary">Lower band screen brightness automatically at night</string>
<string name="pref_title_force_white_color_scheme">Force black on white color scheme</string>
<string name="pref_summary_force_white_color_scheme">Useful if you your watch has dark hands</string>
<string name="automatic">Automatic</string> <string name="automatic">Automatic</string>
<string name="simplified_chinese">Simplified Chinese</string> <string name="simplified_chinese">Simplified Chinese</string>
<string name="traditional_chinese">Traditional Chinese</string> <string name="traditional_chinese">Traditional Chinese</string>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="false"
android:key="force_white_color_scheme"
android:summary="@string/pref_summary_force_white_color_scheme"
android:title="@string/pref_title_force_white_color_scheme" />
</androidx.preference.PreferenceScreen>