1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-01 22:43:00 +01:00

Add Device settings - altitude

Add repeat notification on phone call - need to refine
Add command for cancel text notification
This commit is contained in:
mamutcho 2019-11-04 00:41:48 +02:00
parent fb08af6d04
commit 54f4bbeeef
7 changed files with 130 additions and 27 deletions

View File

@ -34,6 +34,9 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final String PREF_DISCONNECT_REMIND = "disconnect_notification"; public static final String PREF_DISCONNECT_REMIND = "disconnect_notification";
public static final String PREF_FIND_PHONE = "prefs_find_phone"; public static final String PREF_FIND_PHONE = "prefs_find_phone";
public static final String PREF_FIND_PHONE_DURATION = "prefs_find_phone_duration"; public static final String PREF_FIND_PHONE_DURATION = "prefs_find_phone_duration";
public static final String PREF_ALTITUDE = "watchxplus_altitude";
public static final String PREF_REPEAT = "watchxplus_repeat";
// time format constants // time format constants
public static final byte ARG_SET_TIMEMODE_24H = 0x00; public static final byte ARG_SET_TIMEMODE_24H = 0x00;
public static final byte ARG_SET_TIMEMODE_12H = 0x01; public static final byte ARG_SET_TIMEMODE_12H = 0x01;
@ -50,6 +53,7 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] CMD_NOTIFICATION_TEXT_TASK = new byte[]{0x03, 0x06}; public static final byte[] CMD_NOTIFICATION_TEXT_TASK = new byte[]{0x03, 0x06};
public static final byte[] CMD_NOTIFICATION_CANCEL = new byte[]{0x03, 0x04};
public static final byte[] CMD_NOTIFICATION_SETTINGS = new byte[]{0x03, 0x02}; public static final byte[] CMD_NOTIFICATION_SETTINGS = new byte[]{0x03, 0x02};
public static final byte[] CMD_DO_NOT_DISTURB_SETTINGS = new byte[]{0x03, 0x61}; public static final byte[] CMD_DO_NOT_DISTURB_SETTINGS = new byte[]{0x03, 0x61};
@ -59,6 +63,7 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] CMD_SHAKE_SWITCH = new byte[]{0x03, -0x6E}; public static final byte[] CMD_SHAKE_SWITCH = new byte[]{0x03, -0x6E};
public static final byte[] CMD_DISCONNECT_REMIND = new byte[]{0x00, 0x11}; public static final byte[] CMD_DISCONNECT_REMIND = new byte[]{0x00, 0x11};
public static final byte[] CMD_TIME_LANGUAGE = new byte[]{0x03, -0x6F}; public static final byte[] CMD_TIME_LANGUAGE = new byte[]{0x03, -0x6F};
public static final byte[] CMD_ALTITUDE = new byte[]{0x05, 0x0A};
public static final byte[] RESP_SHAKE_SWITCH = new byte[]{0x08, 0x03, -0x6E}; public static final byte[] RESP_SHAKE_SWITCH = new byte[]{0x08, 0x03, -0x6E};
public static final byte[] RESP_DISCONNECT_REMIND = new byte[]{0x08, 0x00, 0x11}; public static final byte[] RESP_DISCONNECT_REMIND = new byte[]{0x08, 0x00, 0x11};

View File

@ -15,6 +15,7 @@ import androidx.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
@ -28,6 +29,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; 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.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
@ -35,6 +37,7 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
public static final int FindPhone_ON = -1; public static final int FindPhone_ON = -1;
public static final int FindPhone_OFF = 0; public static final int FindPhone_OFF = 0;
protected static Prefs prefs = GBApplication.getPrefs();
@NonNull @NonNull
@Override @Override
@ -182,6 +185,18 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
// WatchXPlus doesn't support scheduled intervals. Treat it as "on". // WatchXPlus doesn't support scheduled intervals. Treat it as "on".
return !lostReminder.equals(getContext().getString(R.string.p_off)); return !lostReminder.equals(getContext().getString(R.string.p_off));
} }
// read altitude from preferences
public static int getAltitude(String address) {
return (int) prefs.getInt(WatchXPlusConstants.PREF_ALTITUDE, 200);
}
// read repeat call notification
public static int getRepeatOnCall(String address) {
return (int) prefs.getInt(WatchXPlusConstants.PREF_REPEAT, 1);
}
// read repeat call preferences
public static int getRepeat = 0;
/** /**
* @return {@link #FindPhone_OFF}, {@link #FindPhone_ON}, or the duration * @return {@link #FindPhone_OFF}, {@link #FindPhone_ON}, or the duration

View File

@ -79,7 +79,7 @@ public class InitOperation extends AbstractBTLEOperation<WatchXPlusDeviceSupport
return super.onCharacteristicChanged(gatt, characteristic); return super.onCharacteristicChanged(gatt, characteristic);
} }
} catch (Exception e) { } catch (Exception e) {
GB.toast(getContext(), "Error authenticating Watch 9", Toast.LENGTH_LONG, GB.ERROR, e); GB.toast(getContext(), "Error authenticating Watch X Plus", Toast.LENGTH_LONG, GB.ERROR, e);
} }
return true; return true;
} else { } else {

View File

@ -83,6 +83,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA
import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.operations.InitOperation;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport { public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@ -177,11 +178,23 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
message += StringUtils.truncate(notificationSpec.body, 64); message += StringUtils.truncate(notificationSpec.body, 64);
} }
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_DEFAULT, message); sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_DEFAULT, message, false);
} }
private void sendNotification(int notificationChannel, String notificationText) { private void sendNotification(int notificationChannel, String notificationText, boolean repeat) {
try { try {
int on = 5000; // repeat delay ms
int test = 1; // repeat once
if (repeat) {
test = WatchXPlusDeviceCoordinator.getRepeatOnCall(getDevice().getAddress());
if (test < 1) {
test = 1;
}
WatchXPlusDeviceCoordinator.getRepeat = 1;
} else {
test = 1;
WatchXPlusDeviceCoordinator.getRepeat = 0;
}
TransactionBuilder builder = performInitialized("showNotification"); TransactionBuilder builder = performInitialized("showNotification");
byte[] command = WatchXPlusConstants.CMD_NOTIFICATION_TEXT_TASK; byte[] command = WatchXPlusConstants.CMD_NOTIFICATION_TEXT_TASK;
byte[] text = notificationText.getBytes("UTF-8"); byte[] text = notificationText.getBytes("UTF-8");
@ -209,12 +222,34 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
} }
messagePart[0] = (byte) notificationChannel; messagePart[0] = (byte) notificationChannel;
messagePart[1] = (byte) messageIndex; messagePart[1] = (byte) messageIndex;
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE), for (int i = 0; i < test; i++) { // repeat call notification
buildCommand(command, if (notificationText != "stop") {
WatchXPlusConstants.KEEP_ALIVE, builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
messagePart)); buildCommand(command,
WatchXPlusConstants.KEEP_ALIVE,
messagePart));
if (WatchXPlusDeviceCoordinator.getRepeat == 1) {
builder.wait(on);
} else {
i = test;
break;
}
} else { //cancel text notification
i = test;
byte[] bArr;
int mPosition = 1024;
bArr = new byte[4];
bArr[0] = (byte) ((int) (mPosition >> 24));
bArr[1] = (byte) ((int) (mPosition >> 16));
bArr[2] = (byte) ((int) (mPosition >> 8));
bArr[3] = (byte) ((int) mPosition);
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_NOTIFICATION_CANCEL,
WatchXPlusConstants.WRITE_VALUE,
bArr));
}
}
} }
builder.queue(getQueue()); builder.queue(getQueue());
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Unable to send notification", e); LOG.warn("Unable to send notification", e);
@ -439,17 +474,23 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
alarmValue)); alarmValue));
} }
} }
int repeat = 0;
@Override @Override
public void onSetCallState(CallSpec callSpec) { public void onSetCallState(CallSpec callSpec) {
SharedPreferences.Editor prefs = GBApplication.getPrefs().getPreferences().edit();
switch (callSpec.command) { switch (callSpec.command) {
case CallSpec.CALL_INCOMING: case CallSpec.CALL_INCOMING:
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name); WatchXPlusDeviceCoordinator.getRepeat = 1;
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name, true);
break; break;
case CallSpec.CALL_START: case CallSpec.CALL_START:
WatchXPlusDeviceCoordinator.getRepeat = 1;
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, "stop", false);
break;
case CallSpec.CALL_END: case CallSpec.CALL_END:
// sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, true); WatchXPlusDeviceCoordinator.getRepeat = 0;
// break; sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, "stop", false);
break;
default: default:
break; break;
} }
@ -595,6 +636,10 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
break; break;
case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT: case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
setTimeMode(builder, sharedPreferences); setTimeMode(builder, sharedPreferences);
break;
case WatchXPlusConstants.PREF_ALTITUDE:
LOG.info(" ALTITUDE: " + config);
break; break;
} }
builder.queue(getQueue()); builder.queue(getQueue());
@ -1174,10 +1219,12 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
// read preferences // read preferences
private void syncPreferences(TransactionBuilder transaction) { private void syncPreferences(TransactionBuilder transaction) {
SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress()); SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress());
this.setHeadsUpScreen(transaction, sharedPreferences); this.setHeadsUpScreen(transaction, sharedPreferences); // lift wirst to screen on
this.setDisconnectReminder(transaction, sharedPreferences); this.setDisconnectReminder(transaction, sharedPreferences); // disconnect reminder
this.setTimeMode(transaction, sharedPreferences); this.setTimeMode(transaction, sharedPreferences); // set time mode 12/24h
this.setAltitude(transaction); // set altitude calibration
} }
private Handler mFindPhoneHandler = new Handler(); private Handler mFindPhoneHandler = new Handler();
private void onReverseFindDevice(boolean start) { private void onReverseFindDevice(boolean start) {
@ -1220,7 +1267,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
// Command to toggle Lift Wrist to Light Screen // Command to toggle Lift Wrist to Light Screen
private WatchXPlusDeviceSupport setHeadsUpScreen(TransactionBuilder transactionBuilder, boolean enable) { private WatchXPlusDeviceSupport setHeadsUpScreen(TransactionBuilder transactionBuilder, boolean enable) {
byte refuseCall = 0x00; byte refuseCall = 0x00; // force refuse call to OFF
byte lightScreen = 0x00; byte lightScreen = 0x00;
if (enable) { if (enable) {
lightScreen = 0x01; lightScreen = 0x01;
@ -1275,9 +1322,29 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
buildCommand(WatchXPlusConstants.CMD_TIME_LANGUAGE, buildCommand(WatchXPlusConstants.CMD_TIME_LANGUAGE,
WatchXPlusConstants.WRITE_VALUE, WatchXPlusConstants.WRITE_VALUE,
bArr)); bArr));
LOG.info(" setTimeMode: " + bArr); //LOG.info(" setTimeMode: " + bArr);
return this; return this;
}
// calibrate altitude
private WatchXPlusDeviceSupport setAltitude(TransactionBuilder transactionBuilder) {
int value = WatchXPlusDeviceCoordinator.getAltitude(getDevice().getAddress());
int mAltitude = value;
if (mAltitude < 0) {
mAltitude = (Math.abs(mAltitude) ^ 65535) + 1;
}
int mAirPressure = Math.abs(0); // air pressure 0 ???
byte[] bArr = new byte[4];
bArr[0] = (byte) (mAltitude >> 8); // bytr[8]
bArr[1] = (byte) mAltitude; // bytr[9]
bArr[2] = (byte) (mAirPressure >> 8); // bytr[10]
bArr[3] = (byte) mAirPressure; // bytr[11]
transactionBuilder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_ALTITUDE,
WatchXPlusConstants.WRITE_VALUE,
bArr));
//LOG.info(" setAltitude: " + mAltitude);
return this;
} }
private WatchXPlusDeviceSupport setTimeMode(TransactionBuilder transactionBuilder, SharedPreferences sharedPreferences) { private WatchXPlusDeviceSupport setTimeMode(TransactionBuilder transactionBuilder, SharedPreferences sharedPreferences) {

View File

@ -1,5 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_display_add_device_fab">Бутон за ново устройство</string>
<string name="pref_display_add_device_fab_on">Винаги видим</string>
<string name="pref_display_add_device_fab_off">Видим само ако няма свързано устройство</string>
<string name="language_and_region_prefs">Език и регион</string>
<string name="activity_prefs_about_you">За Вас</string>
<string name="activity_prefs_year_birth">Година на раждане</string>
<string name="activity_prefs_gender">Пол</string>
<string name="activity_prefs_height_cm">Височина в cm</string>
<string name="activity_prefs_weight_kg">Тегло в kg</string>
<string name="pref_header_charts">Настройки на Графиката</string>
<string name="pref_title_charts_average">Показвай средни стойности</string>
<string name="activity_prefs_charts">Настройки на графика</string>
<string name="activity_prefs_chart_max_heart_rate">Max сърдечен ритъм</string>
<string name="activity_prefs_chart_min_heart_rate">Min сърдечен ритъм</string>
<string name="pref_title_charts_range">Обхват на Графиката</string>
<string name="pref_charts_range_on">Обхвата е Месец</string>
<string name="pref_charts_range_off">Обхвата е Седмица</string>
<string name="app_name">Gadgetbridge</string> <string name="app_name">Gadgetbridge</string>
<string name="title_activity_controlcenter">Gadgetbridge</string> <string name="title_activity_controlcenter">Gadgetbridge</string>
<string name="action_settings">Настройки</string> <string name="action_settings">Настройки</string>

View File

@ -189,8 +189,8 @@
<!-- WatchXPlus Preferences --> <!-- WatchXPlus Preferences -->
<string name="pref_wxp_title_unit_system">Units</string> <string name="pref_wxp_title_unit_system">Units</string>
<string name="pref_wxp_title_timeformat">Time format</string> <string name="pref_wxp_title_timeformat">Time format</string>
<string name="pref_wxp_title_screentime">Screen on duration</string> <string name="pref_wxp_title_altitude">Altitude calibration</string>
<string name="pref_wxp_title_lift_wirst">Lift wirst to screen on</string> <string name="pref_wxp_title_repeat_on_call">Repeat vibration on call</string>
<string name="preferences_watchxplus_settings">WatchXPlus settings</string> <string name="preferences_watchxplus_settings">WatchXPlus settings</string>
<!-- Makibes HR3 Preferences --> <!-- Makibes HR3 Preferences -->
<string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string> <string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string>

View File

@ -584,15 +584,14 @@
android:title="@string/pref_header_general"> android:title="@string/pref_header_general">
<EditTextPreference <EditTextPreference
android:defaultValue="5" android:defaultValue="200"
android:key="watchxplus_screentime" android:key="watchxplus_altitude"
android:title="@string/pref_wxp_title_screentime"/> android:title="@string/pref_wxp_title_altitude"/>
<CheckBoxPreference <EditTextPreference
android:layout="@layout/preference_checkbox" android:defaultValue="1"
android:defaultValue="true" android:key="watchxplus_repeat"
android:key="watchxplus_liftwirst" android:title="@string/pref_wxp_title_repeat_on_call"/>
android:title="@string/pref_wxp_title_lift_wirst" />
</PreferenceCategory> </PreferenceCategory>