mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-01 14:32:54 +01:00
FIXES:
- Cleaned code for repeat watch vibration during phone ring. - On my samsung phone and Bulgarian language, when call is ended, on watch shows notification with name "Phone" and vibrates until disconnect from app. Finally managed to fix it. ADD: - Add setting for ignore/reject phone call with device button. - Add setting for ignore/reject phone call with shake device. (duplicates button action) P.S. to apply needs to reconnect device. - Add setting for sending Missed call if call is missed. - Add setting for continious vibration while phone ringing. NEED MORE TESTING: - When phone alarm trigger - send notification on watch. Works on samsung phone. Don't have other phones for testing. P.S. To apply altitude calibration, need to disconnect and reconnect watch
This commit is contained in:
parent
81997e7725
commit
33f18036d3
@ -36,7 +36,12 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
|
||||
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";
|
||||
public static final String PREF_CONTINIOUS = "watchxplus_continious";
|
||||
public static final String PREF_MISSED_CALL = "watchxplus_missed";
|
||||
public static final String PREF_IS_BP_CALIBRATED = "watchxplus_is_bp_calibrated";
|
||||
public static final String PREF_BUTTON_REJECT = "watchxplus_button_reject";
|
||||
public static final String PREF_SHAKE_REJECT = "watchxplus_shake_reject";
|
||||
|
||||
|
||||
// time format constants
|
||||
public static final byte ARG_SET_TIMEMODE_24H = 0x00;
|
||||
@ -71,6 +76,7 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
|
||||
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_IS_BP_CALIBRATED = new byte[]{0x08, 0x05, 0x0B};
|
||||
public static final byte[] RESP_BUTTON_WHILE_RING = new byte[]{0x04, 0x03, 0x03};
|
||||
|
||||
public static final byte[] RESP_AUTHORIZATION_TASK = new byte[]{0x01, 0x01, 0x05};
|
||||
public static final byte[] RESP_DAY_STEPS_INDICATOR = new byte[]{0x08, 0x10, 0x03};
|
||||
|
@ -223,6 +223,14 @@ Prefs from device settings on main page
|
||||
}
|
||||
}
|
||||
|
||||
public static byte getBPCalibrationStatus(SharedPreferences sharedPrefs) {
|
||||
String timeMode = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
|
||||
if (timeMode.equals(getContext().getString(R.string.p_timeformat_24h))) {
|
||||
return WatchXPlusConstants.ARG_SET_TIMEMODE_24H;
|
||||
} else {
|
||||
return WatchXPlusConstants.ARG_SET_TIMEMODE_12H;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Values from device specific settings page
|
||||
*/
|
||||
@ -236,17 +244,30 @@ Values from device specific settings page
|
||||
return (int) prefs.getInt(WatchXPlusConstants.PREF_REPEAT, 1);
|
||||
}
|
||||
|
||||
//read continious call notification
|
||||
public static boolean getContiniousVibrationOnCall(String address) {
|
||||
return (boolean) prefs.getBoolean(WatchXPlusConstants.PREF_CONTINIOUS, false);
|
||||
}
|
||||
|
||||
//read missed call notification
|
||||
public static boolean getMissedCallReminder(String address) {
|
||||
return (boolean) prefs.getBoolean(WatchXPlusConstants.PREF_MISSED_CALL, false);
|
||||
}
|
||||
|
||||
//read button reject call settings
|
||||
public static boolean getButtonReject(String address) {
|
||||
return (boolean) prefs.getBoolean(WatchXPlusConstants.PREF_BUTTON_REJECT, false);
|
||||
}
|
||||
|
||||
//read shake wrist reject call settings
|
||||
public static boolean getShakeReject(String address) {
|
||||
return (boolean) prefs.getBoolean(WatchXPlusConstants.PREF_SHAKE_REJECT, false);
|
||||
}
|
||||
|
||||
/*
|
||||
Other saved preferences
|
||||
*/
|
||||
public static byte getBPCalibrationStatus(SharedPreferences sharedPrefs) {
|
||||
String timeMode = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
|
||||
if (timeMode.equals(getContext().getString(R.string.p_timeformat_24h))) {
|
||||
return WatchXPlusConstants.ARG_SET_TIMEMODE_24H;
|
||||
} else {
|
||||
return WatchXPlusConstants.ARG_SET_TIMEMODE_12H;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntry;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntryDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.AppNotificationType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
@ -249,8 +250,8 @@ public class NotificationListener extends NotificationListenerService {
|
||||
}
|
||||
|
||||
if (shouldIgnore(sbn)) {
|
||||
if (!"com.sec.android.app.clockpackage".equals(sbn.getPackageName())) { // allow phone alarm notification
|
||||
LOG.info("Ignore notification: " + sbn.getPackageName());
|
||||
if (!"com.sec.android.app.clockpackage".equals(sbn.getPackageName())) { // workaround to allow phone alarm notification
|
||||
LOG.info("Ignore notification: " + sbn.getPackageName()); // need to fix
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -677,7 +678,6 @@ public class NotificationListener extends NotificationListenerService {
|
||||
if (!isServiceRunning() || sbn == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return shouldIgnoreSource(sbn.getPackageName()) || shouldIgnoreNotification(
|
||||
sbn.getNotification(), sbn.getPackageName());
|
||||
|
||||
@ -721,8 +721,9 @@ public class NotificationListener extends NotificationListenerService {
|
||||
|
||||
MediaSessionCompat.Token mediaSession = getMediaSession(notification);
|
||||
//try to handle media session notifications
|
||||
if (mediaSession != null && handleMediaSessionNotification(mediaSession))
|
||||
if (mediaSession != null && handleMediaSessionNotification(mediaSession)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NotificationType type = AppNotificationType.getInstance().get(source);
|
||||
//ignore notifications marked as LocalOnly https://developer.android.com/reference/android/app/Notification.html#FLAG_LOCAL_ONLY
|
||||
@ -743,7 +744,6 @@ public class NotificationListener extends NotificationListenerService {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT;
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
@ -53,6 +54,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.DataType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.watchxplus.WatchXPlusConstants;
|
||||
@ -62,6 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.WatchXPlusActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.WatchXPlusHealthActivityOverlay;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.WatchXPlusHealthActivityOverlayDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
@ -81,13 +84,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.operations.InitOperation;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
|
||||
public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
|
||||
private boolean needsAuth;
|
||||
@ -466,80 +469,48 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
alarmValue));
|
||||
}
|
||||
}
|
||||
int repeat = 0;
|
||||
|
||||
// variables to handle ring notifications
|
||||
boolean isRinging = false;
|
||||
int remainingRepeats = 0;
|
||||
@Override
|
||||
public void onSetCallState(final CallSpec callSpec) {
|
||||
int repeatDelay = 5000;
|
||||
final int repeatDelay = 5000; // repeat delay of 5 sec
|
||||
// get settings from device settings page
|
||||
final boolean continiousRing = WatchXPlusDeviceCoordinator.getContiniousVibrationOnCall(getDevice().getAddress());
|
||||
boolean missedCall = WatchXPlusDeviceCoordinator.getMissedCallReminder(getDevice().getAddress());
|
||||
int repeatCount = WatchXPlusDeviceCoordinator.getRepeatOnCall(getDevice().getAddress());
|
||||
if (repeatCount < 0) {
|
||||
repeatCount = 0;
|
||||
}
|
||||
if (repeatCount > 5) {
|
||||
repeatCount = 5;
|
||||
}
|
||||
|
||||
if("Phone".equals(callSpec.name)) { // ignore notification if caller name is Phone
|
||||
return;
|
||||
}
|
||||
// check if repeatCount is in boundaries min=0, max=10
|
||||
if (repeatCount < 0) repeatCount = 0;
|
||||
if (repeatCount > 10) repeatCount = 10; // limit repeats to 10
|
||||
|
||||
switch (callSpec.command) {
|
||||
case CallSpec.CALL_INCOMING:
|
||||
isRinging = true;
|
||||
remainingRepeats = repeatCount;
|
||||
if (("Phone".equals(callSpec.name)) || (callSpec.name.contains("ropusn")) || (callSpec.name.contains("issed"))) {
|
||||
// do nothing for notifications without caller name, e.g. system call event
|
||||
} else {
|
||||
// send first notification
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
// TODO dirty code, need to fix
|
||||
// repeat call notification up to 5 times
|
||||
Handler handler = new Handler();
|
||||
if (repeatCount > 0) {
|
||||
// init repeat handler
|
||||
final Handler handler = new Handler();
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
// Actions to do after 5 seconds
|
||||
if (isRinging) {
|
||||
// Actions to do after repeatDelay seconds
|
||||
if (((isRinging) && (remainingRepeats > 0)) || ((isRinging) && (continiousRing))) {
|
||||
remainingRepeats = remainingRepeats - 1;
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
// re-run handler
|
||||
handler.postDelayed(this, repeatDelay);
|
||||
} else {
|
||||
remainingRepeats = 0;
|
||||
// stop handler
|
||||
handler.removeCallbacks(this);
|
||||
}
|
||||
}
|
||||
}, repeatDelay);
|
||||
}
|
||||
if (repeatCount > 1) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
// Actions to do after 5 seconds
|
||||
if (isRinging) {
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
}
|
||||
}
|
||||
}, repeatDelay * 2);
|
||||
}
|
||||
if (repeatCount > 2) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
// Actions to do after 5 seconds
|
||||
if (isRinging) {
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
}
|
||||
}
|
||||
}, repeatDelay * 3);
|
||||
}
|
||||
if (repeatCount > 3) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
// Actions to do after 5 seconds
|
||||
if (isRinging) {
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
}
|
||||
}
|
||||
}, repeatDelay * 4);
|
||||
}
|
||||
if (repeatCount > 4) {
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
// Actions to do after 5 seconds
|
||||
if (isRinging) {
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
|
||||
}
|
||||
}
|
||||
}, repeatDelay * 5);
|
||||
}
|
||||
break;
|
||||
case CallSpec.CALL_START:
|
||||
isRinging = false;
|
||||
@ -559,19 +530,44 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
break;
|
||||
case CallSpec.CALL_END:
|
||||
if (isRinging) {
|
||||
// it's a missed call
|
||||
// don't clear notification to preserve small icon near bluetooth
|
||||
// it's a missed call, don't clear notification to preserve small icon near bluetooth
|
||||
isRinging = false;
|
||||
// send missed call notification if enabled in settings
|
||||
if (missedCall) {
|
||||
sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, "Missed call");
|
||||
}
|
||||
} else {
|
||||
isRinging = false;
|
||||
cancelNotification();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
isRinging = false;
|
||||
cancelNotification();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// handle button press while ringing
|
||||
private void handleButtonWhenRing(byte[] value) {
|
||||
GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl();
|
||||
// get saved settings if true - reject call, otherwise ignore call
|
||||
boolean buttonReject = WatchXPlusDeviceCoordinator.getButtonReject(getDevice().getAddress());
|
||||
if (buttonReject) {
|
||||
LOG.info(" call rejected ");
|
||||
isRinging = false;
|
||||
callCmd.event = GBDeviceEventCallControl.Event.REJECT;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
cancelNotification();
|
||||
} else {
|
||||
LOG.info(" call ignored ");
|
||||
isRinging = false;
|
||||
callCmd.event = GBDeviceEventCallControl.Event.IGNORE;
|
||||
evaluateGBDeviceEvent(callCmd);
|
||||
cancelNotification();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
|
||||
|
||||
@ -830,6 +826,8 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
handleFirmwareInfo(value);
|
||||
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_SHAKE_SWITCH, 5)) {
|
||||
handleShakeState(value);
|
||||
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BUTTON_WHILE_RING, 5)) {
|
||||
handleButtonWhenRing(value);
|
||||
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_DISCONNECT_REMIND, 5)) {
|
||||
handleDisconnectReminderState(value);
|
||||
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BATTERY_INFO, 5)) {
|
||||
@ -1387,9 +1385,12 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
WatchXPlusDeviceCoordinator.shouldEnableHeadsUpScreen(sharedPreferences));
|
||||
}
|
||||
|
||||
// Command to toggle Lift Wrist to Light Screen
|
||||
// Command to toggle Lift Wrist to Light Screen, and shake to ignore/reject call
|
||||
private WatchXPlusDeviceSupport setHeadsUpScreen(TransactionBuilder transactionBuilder, boolean enable) {
|
||||
byte refuseCall = 0x00; // force refuse call to OFF
|
||||
boolean shakeReject = WatchXPlusDeviceCoordinator.getShakeReject(getDevice().getAddress());
|
||||
byte refuseCall = 0x00; // force shake wrist to ignore/reject call to OFF
|
||||
// returned characteristic is equal with button press while ringing
|
||||
if (shakeReject) refuseCall = 0x01;
|
||||
byte lightScreen = 0x00;
|
||||
if (enable) {
|
||||
lightScreen = 0x01;
|
||||
@ -1427,7 +1428,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
WatchXPlusConstants.READ_VALUE));
|
||||
return this;
|
||||
}
|
||||
// Request status of Lift Wrist to Light Screen, and Shake to Refuse Call
|
||||
// Request status of Lift Wrist to Light Screen, and Shake to Ignore/Reject Call
|
||||
public WatchXPlusDeviceSupport getShakeStatus(TransactionBuilder transactionBuilder) {
|
||||
transactionBuilder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
|
||||
buildCommand(WatchXPlusConstants.CMD_SHAKE_SWITCH,
|
||||
|
@ -288,7 +288,13 @@
|
||||
<string name="pref_wxp_title_timeformat">Формат на часа</string>
|
||||
<string name="pref_wxp_title_altitude">Калибриране на височина</string>
|
||||
<string name="pref_wxp_title_repeat_on_call">Повтори известия за звънене</string>
|
||||
<string name="pref_wxp_title_repeat_on_call_summary">Възможни стойности min=0, max=5</string>
|
||||
<string name="pref_wxp_title_repeat_on_call_summary">Възможни стойности min=0, max=10</string>
|
||||
<string name="prefs_wxp_continious">Известие докато звъни</string>
|
||||
<string name="pref_wxp_title_reject_summary">Изкл. - игнорира, Вкл. - отказ</string>
|
||||
<string name="prefs_wxp_reject">Бутона игнорира/отказва повикване</string>
|
||||
<string name="pref_wxp_title_shake_reject_summary">Дублира действието на бутона</string>
|
||||
<string name="prefs_wxp_shake_reject">Разклащането игнорира/отказва повикване</string>
|
||||
<string name="prefs_wxp_missed">Известие за пропуснато повикване</string>
|
||||
<string name="preferences_watchxplus_settings">WatchXPlus настройки</string>
|
||||
<string name="pref_header_wxp_calibration">WatchXPlus калибриране</string>
|
||||
<string name="title_activity_sleepmonitor">Наблюдение/анализ на съня</string>
|
||||
|
@ -191,8 +191,14 @@
|
||||
<string name="pref_wxp_title_timeformat">Time format</string>
|
||||
<string name="pref_wxp_title_altitude">Altitude calibration</string>
|
||||
<string name="pref_wxp_title_repeat_on_call">Repeat call notification</string>
|
||||
<string name="pref_wxp_title_repeat_on_call_summary">Possible values min=0, max=5</string>
|
||||
<string name="pref_wxp_title_repeat_on_call_summary">Possible values min=0, max=10</string>
|
||||
<string name="prefs_wxp_continious">Vibration during phone ring</string>
|
||||
<string name="prefs_wxp_missed">Vibration on missed call</string>
|
||||
<string name="preferences_watchxplus_settings">WatchXPlus settings</string>
|
||||
<string name="pref_wxp_title_reject_summary">Off - ignore, On - reject</string>
|
||||
<string name="prefs_wxp_reject">Button ignore/reject call</string>
|
||||
<string name="pref_wxp_title_shake_reject_summary">Duplicates watch button action</string>
|
||||
<string name="prefs_wxp_shake_reject">Shake wrist ignore/reject call</string>
|
||||
<string name="pref_header_wxp_calibration">WatchXPlus calibration</string>
|
||||
<!-- Makibes HR3 Preferences -->
|
||||
<string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string>
|
||||
|
@ -588,6 +588,28 @@
|
||||
android:key="watchxplus_repeat"
|
||||
android:summary="@string/pref_wxp_title_repeat_on_call_summary"
|
||||
android:title="@string/pref_wxp_title_repeat_on_call"/>
|
||||
<CheckBoxPreference
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:defaultValue="false"
|
||||
android:key="watchxplus_continious"
|
||||
android:title="@string/prefs_wxp_continious" />
|
||||
<CheckBoxPreference
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:defaultValue="false"
|
||||
android:key="watchxplus_missed"
|
||||
android:title="@string/prefs_wxp_missed" />
|
||||
<CheckBoxPreference
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:defaultValue="false"
|
||||
android:key="watchxplus_button_reject"
|
||||
android:summary="@string/pref_wxp_title_reject_summary"
|
||||
android:title="@string/prefs_wxp_reject" />
|
||||
<CheckBoxPreference
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:defaultValue="false"
|
||||
android:key="watchxplus_shake_reject"
|
||||
android:summary="@string/pref_wxp_title_shake_reject_summary"
|
||||
android:title="@string/prefs_wxp_shake_reject" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="pref_category_watchxplus_calibration"
|
||||
|
Loading…
Reference in New Issue
Block a user